124139Sjoergchar *copyright = 224139Sjoerg "Copyright (c) 1984 through 1996, William LeFebvre"; 324139Sjoerg 424139Sjoerg/* 524139Sjoerg * Top users/processes display for Unix 624139Sjoerg * Version 3 724139Sjoerg * 824139Sjoerg * This program may be freely redistributed, 924139Sjoerg * but this entire comment MUST remain intact. 1024139Sjoerg * 1124139Sjoerg * Copyright (c) 1984, 1989, William LeFebvre, Rice University 1289757Sdwmalone * Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University 1389757Sdwmalone * Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory 1489757Sdwmalone * Copyright (c) 1996, William LeFebvre, Group sys Consulting 1566641Simp * 1666641Simp * $FreeBSD$ 1724139Sjoerg */ 1824139Sjoerg 1924139Sjoerg/* 2024139Sjoerg * See the file "Changes" for information on version-to-version changes. 2124139Sjoerg */ 2224139Sjoerg 2324139Sjoerg/* 2424139Sjoerg * This file contains "main" and other high-level routines. 2524139Sjoerg */ 2624139Sjoerg 2724139Sjoerg/* 2824139Sjoerg * The following preprocessor variables, when defined, are used to 2924139Sjoerg * distinguish between different Unix implementations: 3024139Sjoerg * 3124139Sjoerg * SIGHOLD - use SVR4 sighold function when defined 3224139Sjoerg * SIGRELSE - use SVR4 sigrelse function when defined 3324139Sjoerg * FD_SET - macros FD_SET and FD_ZERO are used when defined 3424139Sjoerg */ 3524139Sjoerg 3624139Sjoerg#include "os.h" 3786042Sdwmalone#include <errno.h> 3824139Sjoerg#include <signal.h> 3924139Sjoerg#include <setjmp.h> 4024139Sjoerg#include <ctype.h> 4124139Sjoerg#include <sys/time.h> 4224139Sjoerg 4324139Sjoerg/* includes specific to top */ 4424139Sjoerg#include "display.h" /* interface to display package */ 4524139Sjoerg#include "screen.h" /* interface to screen package */ 4624139Sjoerg#include "top.h" 4724139Sjoerg#include "top.local.h" 4824139Sjoerg#include "boolean.h" 4924139Sjoerg#include "machine.h" 5024139Sjoerg#include "utils.h" 5124139Sjoerg 5224139Sjoerg/* Size of the stdio buffer given to stdout */ 5324139Sjoerg#define Buffersize 2048 5424139Sjoerg 5524139Sjoerg/* The buffer that stdio will use */ 5624139Sjoergchar stdoutbuf[Buffersize]; 5724139Sjoerg 5824139Sjoerg/* build Signal masks */ 5924139Sjoerg#define Smask(s) (1 << ((s) - 1)) 6024139Sjoerg 6124139Sjoerg/* for getopt: */ 6224139Sjoergextern int optind; 6324139Sjoergextern char *optarg; 6424139Sjoerg 6524139Sjoerg/* imported from screen.c */ 6624139Sjoergextern int overstrike; 6724139Sjoerg 68168710Sstasstatic int fmt_flags = 0; 69175420Speterint pcpu_stats = No; 70168710Sstas 7124139Sjoerg/* signal handling routines */ 7224139Sjoergsigret_t leave(); 7324139Sjoergsigret_t tstop(); 7424139Sjoerg#ifdef SIGWINCH 7524139Sjoergsigret_t winch(); 7624139Sjoerg#endif 7724139Sjoerg 7881187Skrisvolatile sig_atomic_t leaveflag; 7981187Skrisvolatile sig_atomic_t tstopflag; 8081187Skrisvolatile sig_atomic_t winchflag; 8181187Skris 8224139Sjoerg/* internal routines */ 8324139Sjoergvoid quit(); 8424139Sjoerg 8524139Sjoerg/* values which need to be accessed by signal handlers */ 8624139Sjoergstatic int max_topn; /* maximum displayable processes */ 8724139Sjoerg 8824139Sjoerg/* miscellaneous things */ 89145073Skeramidastruct process_select ps; 9024139Sjoergchar *myname = "top"; 9124139Sjoergjmp_buf jmp_int; 9224139Sjoerg 9324139Sjoerg/* routines that don't return int */ 9424139Sjoerg 9524139Sjoergchar *username(); 9624139Sjoergchar *ctime(); 9724139Sjoergchar *kill_procs(); 9824139Sjoergchar *renice_procs(); 9924139Sjoerg 10024139Sjoerg#ifdef ORDER 101133817Salfredextern int (*compares[])(); 10224139Sjoerg#else 10324139Sjoergextern int proc_compare(); 104131829Skeramidaextern int io_compare(); 10524139Sjoerg#endif 10624139Sjoergtime_t time(); 10724139Sjoerg 10824139Sjoergcaddr_t get_process_info(); 10924139Sjoerg 11024139Sjoerg/* different routines for displaying the user's identification */ 11124139Sjoerg/* (values assigned to get_userid) */ 11224139Sjoergchar *username(); 11324139Sjoergchar *itoa7(); 11424139Sjoerg 11524139Sjoerg/* display routines that need to be predeclared */ 11624139Sjoergint i_loadave(); 11724139Sjoergint u_loadave(); 11824139Sjoergint i_procstates(); 11924139Sjoergint u_procstates(); 12024139Sjoergint i_cpustates(); 12124139Sjoergint u_cpustates(); 12224139Sjoergint i_memory(); 12324139Sjoergint u_memory(); 124237656Sjhbint i_arc(); 125237656Sjhbint u_arc(); 12624142Sjoergint i_swap(); 12724142Sjoergint u_swap(); 12824139Sjoergint i_message(); 12924139Sjoergint u_message(); 13024139Sjoergint i_header(); 13124139Sjoergint u_header(); 13224139Sjoergint i_process(); 13324139Sjoergint u_process(); 13424139Sjoerg 13524139Sjoerg/* pointers to display routines */ 13624139Sjoergint (*d_loadave)() = i_loadave; 13724139Sjoergint (*d_procstates)() = i_procstates; 13824139Sjoergint (*d_cpustates)() = i_cpustates; 13924139Sjoergint (*d_memory)() = i_memory; 140237656Sjhbint (*d_arc)() = i_arc; 14124142Sjoergint (*d_swap)() = i_swap; 14224139Sjoergint (*d_message)() = i_message; 14324139Sjoergint (*d_header)() = i_header; 14424139Sjoergint (*d_process)() = i_process; 14524139Sjoerg 14624139Sjoerg 14724139Sjoergmain(argc, argv) 14824139Sjoerg 14924139Sjoergint argc; 15024139Sjoergchar *argv[]; 15124139Sjoerg 15224139Sjoerg{ 15324139Sjoerg register int i; 15424139Sjoerg register int active_procs; 15524139Sjoerg register int change; 15624139Sjoerg 15724139Sjoerg struct system_info system_info; 15824139Sjoerg struct statics statics; 15924139Sjoerg caddr_t processes; 16024139Sjoerg 16124139Sjoerg static char tempbuf1[50]; 16224139Sjoerg static char tempbuf2[50]; 16324139Sjoerg int old_sigmask; /* only used for BSD-style signals */ 16424139Sjoerg int topn = Default_TOPN; 16524139Sjoerg int delay = Default_DELAY; 16624139Sjoerg int displays = 0; /* indicates unspecified */ 16786042Sdwmalone int sel_ret = 0; 16824139Sjoerg time_t curr_time; 16924139Sjoerg char *(*get_userid)() = username; 17024139Sjoerg char *uname_field = "USERNAME"; 17124139Sjoerg char *header_text; 17224139Sjoerg char *env_top; 17324139Sjoerg char **preset_argv; 17424139Sjoerg int preset_argc = 0; 17524139Sjoerg char **av; 17624139Sjoerg int ac; 17724139Sjoerg char dostates = No; 17824139Sjoerg char do_unames = Yes; 17924139Sjoerg char interactive = Maybe; 18024139Sjoerg char warnings = 0; 18124139Sjoerg#if Default_TOPN == Infinity 18224139Sjoerg char topn_specified = No; 18324139Sjoerg#endif 18424139Sjoerg char ch; 18524139Sjoerg char *iptr; 18624139Sjoerg char no_command = 1; 18724139Sjoerg struct timeval timeout; 18824139Sjoerg#ifdef ORDER 18924139Sjoerg char *order_name = NULL; 19024139Sjoerg int order_index = 0; 19124139Sjoerg#endif 19224139Sjoerg#ifndef FD_SET 19324139Sjoerg /* FD_SET and friends are not present: fake it */ 19424139Sjoerg typedef int fd_set; 19524139Sjoerg#define FD_ZERO(x) (*(x) = 0) 19689757Sdwmalone#define FD_SET(f, x) (*(x) = 1<<f) 19724139Sjoerg#endif 19824139Sjoerg fd_set readfds; 19924139Sjoerg 20024139Sjoerg#ifdef ORDER 201223936Sjhb static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPo"; 20224139Sjoerg#else 203223936Sjhb static char command_chars[] = "\f qh?en#sdkriIutHmSCajzP"; 20424139Sjoerg#endif 20524139Sjoerg/* these defines enumerate the "strchr"s of the commands in command_chars */ 20624139Sjoerg#define CMD_redraw 0 20724139Sjoerg#define CMD_update 1 20824139Sjoerg#define CMD_quit 2 20924139Sjoerg#define CMD_help1 3 21024139Sjoerg#define CMD_help2 4 21124139Sjoerg#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ 21224139Sjoerg#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ 21324139Sjoerg#define CMD_number1 6 21424139Sjoerg#define CMD_number2 7 21524139Sjoerg#define CMD_delay 8 21624139Sjoerg#define CMD_displays 9 21724139Sjoerg#define CMD_kill 10 21824139Sjoerg#define CMD_renice 11 21924139Sjoerg#define CMD_idletog 12 22024139Sjoerg#define CMD_idletog2 13 22124139Sjoerg#define CMD_user 14 22238090Sdes#define CMD_selftog 15 223117709Sjulian#define CMD_thrtog 16 224131402Salfred#define CMD_viewtog 17 225132005Salfred#define CMD_viewsys 18 226146342Skeramida#define CMD_wcputog 19 227168710Sstas#define CMD_showargs 20 228168799Srafan#define CMD_jidtog 21 229222530Sjhb#define CMD_kidletog 22 230223936Sjhb#define CMD_pcputog 23 23124139Sjoerg#ifdef ORDER 232223936Sjhb#define CMD_order 24 23324139Sjoerg#endif 23424139Sjoerg 23524139Sjoerg /* set the buffer for stdout */ 23624139Sjoerg#ifdef DEBUG 23789757Sdwmalone extern FILE *debug; 23889757Sdwmalone debug = fopen("debug.run", "w"); 23924139Sjoerg setbuffer(stdout, NULL, 0); 24024139Sjoerg#else 24124139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 24224139Sjoerg#endif 24324139Sjoerg 24424139Sjoerg /* get our name */ 24524139Sjoerg if (argc > 0) 24624139Sjoerg { 24724139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 24824139Sjoerg { 24924139Sjoerg myname = argv[0]; 25024139Sjoerg } 25124139Sjoerg else 25224139Sjoerg { 25324139Sjoerg myname++; 25424139Sjoerg } 25524139Sjoerg } 25624139Sjoerg 25724139Sjoerg /* initialize some selection options */ 25824139Sjoerg ps.idle = Yes; 25938090Sdes ps.self = -1; 26024139Sjoerg ps.system = No; 26124139Sjoerg ps.uid = -1; 262117709Sjulian ps.thread = No; 263146342Skeramida ps.wcpu = 1; 264168799Srafan ps.jail = No; 265222530Sjhb ps.kidle = Yes; 26624139Sjoerg ps.command = NULL; 26724139Sjoerg 26824139Sjoerg /* get preset options from the environment */ 26924139Sjoerg if ((env_top = getenv("TOP")) != NULL) 27024139Sjoerg { 27124139Sjoerg av = preset_argv = argparse(env_top, &preset_argc); 27224139Sjoerg ac = preset_argc; 27324139Sjoerg 27424139Sjoerg /* set the dummy argument to an explanatory message, in case 27524139Sjoerg getopt encounters a bad argument */ 27624139Sjoerg preset_argv[0] = "while processing environment"; 27724139Sjoerg } 27824139Sjoerg 27924139Sjoerg /* process options */ 28024139Sjoerg do { 28124139Sjoerg /* if we're done doing the presets, then process the real arguments */ 28224139Sjoerg if (preset_argc == 0) 28324139Sjoerg { 28424139Sjoerg ac = argc; 28524139Sjoerg av = argv; 28624139Sjoerg 28724139Sjoerg /* this should keep getopt happy... */ 28824139Sjoerg optind = 1; 28924139Sjoerg } 29024139Sjoerg 291222530Sjhb while ((i = getopt(ac, av, "CSIHPabijnquvzs:d:U:m:o:t")) != EOF) 29224139Sjoerg { 29324139Sjoerg switch(i) 29424139Sjoerg { 29589757Sdwmalone case 'v': /* show version number */ 29689757Sdwmalone fprintf(stderr, "%s: version %s\n", 29789757Sdwmalone myname, version_string()); 29889757Sdwmalone exit(1); 29989757Sdwmalone break; 30089757Sdwmalone 30124139Sjoerg case 'u': /* toggle uid/username display */ 30224139Sjoerg do_unames = !do_unames; 30324139Sjoerg break; 30424139Sjoerg 30524139Sjoerg case 'U': /* display only username's processes */ 30624139Sjoerg if ((ps.uid = userid(optarg)) == -1) 30724139Sjoerg { 30824139Sjoerg fprintf(stderr, "%s: unknown user\n", optarg); 30924139Sjoerg exit(1); 31024139Sjoerg } 31124139Sjoerg break; 31224139Sjoerg 31324139Sjoerg case 'S': /* show system processes */ 31424139Sjoerg ps.system = !ps.system; 31524139Sjoerg break; 31624139Sjoerg 31724139Sjoerg case 'I': /* show idle processes */ 31824139Sjoerg ps.idle = !ps.idle; 31924139Sjoerg break; 32024139Sjoerg 32124139Sjoerg case 'i': /* go interactive regardless */ 32224139Sjoerg interactive = Yes; 32324139Sjoerg break; 32424139Sjoerg 32524139Sjoerg case 'n': /* batch, or non-interactive */ 32624139Sjoerg case 'b': 32724139Sjoerg interactive = No; 32824139Sjoerg break; 32924139Sjoerg 330168710Sstas case 'a': 331168710Sstas fmt_flags ^= FMT_SHOWARGS; 332168710Sstas break; 333168710Sstas 33424139Sjoerg case 'd': /* number of displays to show */ 33524139Sjoerg if ((i = atoiwi(optarg)) == Invalid || i == 0) 33624139Sjoerg { 33724139Sjoerg fprintf(stderr, 33824139Sjoerg "%s: warning: display count should be positive -- option ignored\n", 33924139Sjoerg myname); 34024139Sjoerg warnings++; 34124139Sjoerg } 34224139Sjoerg else 34324139Sjoerg { 34424139Sjoerg displays = i; 34524139Sjoerg } 34624139Sjoerg break; 34724139Sjoerg 34824139Sjoerg case 's': 34989757Sdwmalone if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) 35024139Sjoerg { 35124139Sjoerg fprintf(stderr, 35289757Sdwmalone "%s: warning: seconds delay should be positive -- using default\n", 35324139Sjoerg myname); 35424139Sjoerg delay = Default_DELAY; 35524139Sjoerg warnings++; 35624139Sjoerg } 35724139Sjoerg break; 35824139Sjoerg 35924139Sjoerg case 'q': /* be quick about it */ 36024139Sjoerg /* only allow this if user is really root */ 36124139Sjoerg if (getuid() == 0) 36224139Sjoerg { 36324139Sjoerg /* be very un-nice! */ 36424139Sjoerg (void) nice(-20); 36524139Sjoerg } 36624139Sjoerg else 36724139Sjoerg { 36824139Sjoerg fprintf(stderr, 36924139Sjoerg "%s: warning: `-q' option can only be used by root\n", 37024139Sjoerg myname); 37124139Sjoerg warnings++; 37224139Sjoerg } 37324139Sjoerg break; 37424139Sjoerg 375131616Sdes case 'm': /* select display mode */ 376131402Salfred if (strcmp(optarg, "io") == 0) { 377131402Salfred displaymode = DISP_IO; 378131402Salfred } else if (strcmp(optarg, "cpu") == 0) { 379131402Salfred displaymode = DISP_CPU; 380131402Salfred } else { 381131402Salfred fprintf(stderr, 382131402Salfred "%s: warning: `-m' option can only take args " 383131402Salfred "'io' or 'cpu'\n", 384131402Salfred myname); 385131402Salfred exit(1); 386131402Salfred } 387131402Salfred break; 388131402Salfred 38924139Sjoerg case 'o': /* select sort order */ 39024139Sjoerg#ifdef ORDER 39124139Sjoerg order_name = optarg; 39224139Sjoerg#else 39324139Sjoerg fprintf(stderr, 39424139Sjoerg "%s: this platform does not support arbitrary ordering. Sorry.\n", 39524139Sjoerg myname); 39624139Sjoerg warnings++; 39724139Sjoerg#endif 39824139Sjoerg break; 39924139Sjoerg 40038090Sdes case 't': 40138090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 40238090Sdes break; 403146342Skeramida 404146342Skeramida case 'C': 405146342Skeramida ps.wcpu = !ps.wcpu; 406146342Skeramida break; 407146342Skeramida 408117709Sjulian case 'H': 409117709Sjulian ps.thread = !ps.thread; 410117709Sjulian break; 411146342Skeramida 412168799Srafan case 'j': 413168799Srafan ps.jail = !ps.jail; 414168799Srafan break; 415168799Srafan 416175420Speter case 'P': 417223936Sjhb pcpu_stats = !pcpu_stats; 418175420Speter break; 419175420Speter 420222530Sjhb case 'z': 421222530Sjhb ps.kidle = !ps.kidle; 422222530Sjhb break; 423222530Sjhb 42424139Sjoerg default: 425157842Sru fprintf(stderr, 426157842Sru"Top version %s\n" 427222530Sjhb"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 428157842Sru" [-U username] [number]\n", 42924139Sjoerg version_string(), myname); 43024139Sjoerg exit(1); 43124139Sjoerg } 43224139Sjoerg } 43324139Sjoerg 43424139Sjoerg /* get count of top processes to display (if any) */ 43524139Sjoerg if (optind < ac) 43624139Sjoerg { 43724139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 43824139Sjoerg { 43924139Sjoerg fprintf(stderr, 44024139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 44124139Sjoerg myname); 44224139Sjoerg warnings++; 44324139Sjoerg } 44424139Sjoerg#if Default_TOPN == Infinity 44524139Sjoerg else 44624139Sjoerg { 44724139Sjoerg topn_specified = Yes; 44824139Sjoerg } 44924139Sjoerg#endif 45024139Sjoerg } 45124139Sjoerg 45224139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 45324139Sjoerg i = preset_argc; 45424139Sjoerg preset_argc = 0; 45524139Sjoerg 45624139Sjoerg /* repeat only if we really did the preset arguments */ 45724139Sjoerg } while (i != 0); 45824139Sjoerg 45924139Sjoerg /* set constants for username/uid display correctly */ 46024139Sjoerg if (!do_unames) 46124139Sjoerg { 46224139Sjoerg uname_field = " UID "; 46324139Sjoerg get_userid = itoa7; 46424139Sjoerg } 46524139Sjoerg 46624139Sjoerg /* initialize the kernel memory interface */ 467175195Sobrien if (machine_init(&statics, do_unames) == -1) 46824139Sjoerg { 46924139Sjoerg exit(1); 47024139Sjoerg } 47124139Sjoerg 47224139Sjoerg#ifdef ORDER 47324139Sjoerg /* determine sorting order index, if necessary */ 47424139Sjoerg if (order_name != NULL) 47524139Sjoerg { 47624139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 47724139Sjoerg { 47824139Sjoerg char **pp; 47924139Sjoerg 48024139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 48124139Sjoerg myname, order_name); 48224139Sjoerg fprintf(stderr, "\tTry one of these:"); 48324139Sjoerg pp = statics.order_names; 48424139Sjoerg while (*pp != NULL) 48524139Sjoerg { 48624139Sjoerg fprintf(stderr, " %s", *pp++); 48724139Sjoerg } 48824139Sjoerg fputc('\n', stderr); 48924139Sjoerg exit(1); 49024139Sjoerg } 49124139Sjoerg } 49224139Sjoerg#endif 49324139Sjoerg 49424139Sjoerg#ifdef no_initialization_needed 49524139Sjoerg /* initialize the hashing stuff */ 49624139Sjoerg if (do_unames) 49724139Sjoerg { 49824139Sjoerg init_hash(); 49924139Sjoerg } 50024139Sjoerg#endif 50124139Sjoerg 50224139Sjoerg /* initialize termcap */ 50324139Sjoerg init_termcap(interactive); 50424139Sjoerg 50524139Sjoerg /* get the string to use for the process area header */ 50624139Sjoerg header_text = format_header(uname_field); 50724139Sjoerg 50824139Sjoerg /* initialize display interface */ 50924139Sjoerg if ((max_topn = display_init(&statics)) == -1) 51024139Sjoerg { 51124139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 51224139Sjoerg exit(4); 51324139Sjoerg } 51424139Sjoerg 51524139Sjoerg /* print warning if user requested more processes than we can display */ 51624139Sjoerg if (topn > max_topn) 51724139Sjoerg { 51824139Sjoerg fprintf(stderr, 51924139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 52024139Sjoerg myname, max_topn); 52124139Sjoerg warnings++; 52224139Sjoerg } 52324139Sjoerg 52424139Sjoerg /* adjust for topn == Infinity */ 52524139Sjoerg if (topn == Infinity) 52624139Sjoerg { 52724139Sjoerg /* 52824139Sjoerg * For smart terminals, infinity really means everything that can 52924139Sjoerg * be displayed, or Largest. 53024139Sjoerg * On dumb terminals, infinity means every process in the system! 53124139Sjoerg * We only really want to do that if it was explicitly specified. 53224139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 53324139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 53424139Sjoerg * and the default is Infinity, then (and only then) we use 53524139Sjoerg * "Nominal_TOPN" instead. 53624139Sjoerg */ 53724139Sjoerg#if Default_TOPN == Infinity 53824139Sjoerg topn = smart_terminal ? Largest : 53924139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 54024139Sjoerg#else 54124139Sjoerg topn = Largest; 54224139Sjoerg#endif 54324139Sjoerg } 54424139Sjoerg 54524139Sjoerg /* set header display accordingly */ 54624139Sjoerg display_header(topn > 0); 54724139Sjoerg 54824139Sjoerg /* determine interactive state */ 54924139Sjoerg if (interactive == Maybe) 55024139Sjoerg { 55124139Sjoerg interactive = smart_terminal; 55224139Sjoerg } 55324139Sjoerg 55424139Sjoerg /* if # of displays not specified, fill it in */ 55524139Sjoerg if (displays == 0) 55624139Sjoerg { 55724139Sjoerg displays = smart_terminal ? Infinity : 1; 55824139Sjoerg } 55924139Sjoerg 56024139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 56124139Sjoerg#ifdef SIGHOLD 56224139Sjoerg sighold(SIGINT); 56324139Sjoerg sighold(SIGQUIT); 56424139Sjoerg sighold(SIGTSTP); 56524139Sjoerg#else 56624139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 56724139Sjoerg#endif 56824139Sjoerg init_screen(); 56924139Sjoerg (void) signal(SIGINT, leave); 57024139Sjoerg (void) signal(SIGQUIT, leave); 57124139Sjoerg (void) signal(SIGTSTP, tstop); 57224139Sjoerg#ifdef SIGWINCH 57324139Sjoerg (void) signal(SIGWINCH, winch); 57424139Sjoerg#endif 57524139Sjoerg#ifdef SIGRELSE 57624139Sjoerg sigrelse(SIGINT); 57724139Sjoerg sigrelse(SIGQUIT); 57824139Sjoerg sigrelse(SIGTSTP); 57924139Sjoerg#else 58024139Sjoerg (void) sigsetmask(old_sigmask); 58124139Sjoerg#endif 58224139Sjoerg if (warnings) 58324139Sjoerg { 58424139Sjoerg fputs("....", stderr); 58524139Sjoerg fflush(stderr); /* why must I do this? */ 58624139Sjoerg sleep((unsigned)(3 * warnings)); 58724139Sjoerg fputc('\n', stderr); 58824139Sjoerg } 58924139Sjoerg 59081187Skrisrestart: 59124139Sjoerg 59224139Sjoerg /* 59324139Sjoerg * main loop -- repeat while display count is positive or while it 59424139Sjoerg * indicates infinity (by being -1) 59524139Sjoerg */ 59624139Sjoerg 59724139Sjoerg while ((displays == -1) || (displays-- > 0)) 59824139Sjoerg { 599131402Salfred int (*compare)(); 600131402Salfred 601131402Salfred 60224139Sjoerg /* get the current stats */ 60324139Sjoerg get_system_info(&system_info); 60424139Sjoerg 60524139Sjoerg#ifdef ORDER 606133817Salfred compare = compares[order_index]; 60724139Sjoerg#else 608131829Skeramida if (displaymode == DISP_CPU) 609131402Salfred compare = proc_compare; 610131829Skeramida else 611131829Skeramida compare = io_compare; 61224139Sjoerg#endif 61324139Sjoerg 614131402Salfred /* get the current set of processes */ 615131402Salfred processes = 616131402Salfred get_process_info(&system_info, &ps, compare); 617131402Salfred 61824139Sjoerg /* display the load averages */ 61924139Sjoerg (*d_loadave)(system_info.last_pid, 62024139Sjoerg system_info.load_avg); 62124139Sjoerg 62224139Sjoerg /* display the current time */ 62324139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 62424139Sjoerg time(&curr_time); 62542447Sobrien i_uptime(&system_info.boottime, &curr_time); 62624139Sjoerg i_timeofday(&curr_time); 62724139Sjoerg 62824139Sjoerg /* display process state breakdown */ 62924139Sjoerg (*d_procstates)(system_info.p_total, 63024139Sjoerg system_info.procstates); 63124139Sjoerg 63224139Sjoerg /* display the cpu state percentage breakdown */ 63324139Sjoerg if (dostates) /* but not the first time */ 63424139Sjoerg { 63524139Sjoerg (*d_cpustates)(system_info.cpustates); 63624139Sjoerg } 63724139Sjoerg else 63824139Sjoerg { 63924139Sjoerg /* we'll do it next time */ 64024139Sjoerg if (smart_terminal) 64124139Sjoerg { 64224139Sjoerg z_cpustates(); 64324139Sjoerg } 64424139Sjoerg else 64524139Sjoerg { 64624139Sjoerg putchar('\n'); 64724139Sjoerg } 64824139Sjoerg dostates = Yes; 64924139Sjoerg } 65024139Sjoerg 65124139Sjoerg /* display memory stats */ 65224139Sjoerg (*d_memory)(system_info.memory); 653237656Sjhb (*d_arc)(system_info.arc); 65424139Sjoerg 65524142Sjoerg /* display swap stats */ 65624142Sjoerg (*d_swap)(system_info.swap); 65724142Sjoerg 65824139Sjoerg /* handle message area */ 65924139Sjoerg (*d_message)(); 66024139Sjoerg 66124139Sjoerg /* update the header area */ 66224139Sjoerg (*d_header)(header_text); 66324139Sjoerg 66424139Sjoerg if (topn > 0) 66524139Sjoerg { 66624139Sjoerg /* determine number of processes to actually display */ 66724139Sjoerg /* this number will be the smallest of: active processes, 66824139Sjoerg number user requested, number current screen accomodates */ 66989757Sdwmalone active_procs = system_info.P_ACTIVE; 67024139Sjoerg if (active_procs > topn) 67124139Sjoerg { 67224139Sjoerg active_procs = topn; 67324139Sjoerg } 67424139Sjoerg if (active_procs > max_topn) 67524139Sjoerg { 67624139Sjoerg active_procs = max_topn; 67724139Sjoerg } 67824139Sjoerg 67924139Sjoerg /* now show the top "n" processes. */ 68024139Sjoerg for (i = 0; i < active_procs; i++) 68124139Sjoerg { 682168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 683168710Sstas fmt_flags)); 68424139Sjoerg } 68524139Sjoerg } 68624139Sjoerg else 68724139Sjoerg { 68824139Sjoerg i = 0; 68924139Sjoerg } 69024139Sjoerg 69124139Sjoerg /* do end-screen processing */ 69224139Sjoerg u_endscreen(i); 69324139Sjoerg 69424139Sjoerg /* now, flush the output buffer */ 69589757Sdwmalone if (fflush(stdout) != 0) 69689757Sdwmalone { 69789757Sdwmalone new_message(MT_standout, " Write error on stdout"); 69889757Sdwmalone putchar('\r'); 69989757Sdwmalone quit(1); 70089757Sdwmalone /*NOTREACHED*/ 70189757Sdwmalone } 70224139Sjoerg 70324139Sjoerg /* only do the rest if we have more displays to show */ 70424139Sjoerg if (displays) 70524139Sjoerg { 70624139Sjoerg /* switch out for new display on smart terminals */ 70724139Sjoerg if (smart_terminal) 70824139Sjoerg { 70924139Sjoerg if (overstrike) 71024139Sjoerg { 71124139Sjoerg reset_display(); 71224139Sjoerg } 71324139Sjoerg else 71424139Sjoerg { 71524139Sjoerg d_loadave = u_loadave; 71624139Sjoerg d_procstates = u_procstates; 71724139Sjoerg d_cpustates = u_cpustates; 71824139Sjoerg d_memory = u_memory; 719237656Sjhb d_arc = u_arc; 72024142Sjoerg d_swap = u_swap; 72124139Sjoerg d_message = u_message; 72224139Sjoerg d_header = u_header; 72324139Sjoerg d_process = u_process; 72424139Sjoerg } 72524139Sjoerg } 72624139Sjoerg 72724139Sjoerg no_command = Yes; 72824139Sjoerg if (!interactive) 72924139Sjoerg { 730232239Skib sleep(delay); 731232660Skib if (leaveflag) { 732232660Skib end_screen(); 733232660Skib exit(0); 734232660Skib } 73524139Sjoerg } 73624139Sjoerg else while (no_command) 73724139Sjoerg { 73824139Sjoerg /* assume valid command unless told otherwise */ 73924139Sjoerg no_command = No; 74024139Sjoerg 74124139Sjoerg /* set up arguments for select with timeout */ 74224139Sjoerg FD_ZERO(&readfds); 74389757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 74424139Sjoerg timeout.tv_sec = delay; 74524139Sjoerg timeout.tv_usec = 0; 74624139Sjoerg 74781187Skris if (leaveflag) { 74881187Skris end_screen(); 74981187Skris exit(0); 75081187Skris } 75181187Skris 75281187Skris if (tstopflag) { 75381187Skris /* move to the lower left */ 75481187Skris end_screen(); 75581187Skris fflush(stdout); 75681187Skris 75781187Skris /* default the signal handler action */ 75881187Skris (void) signal(SIGTSTP, SIG_DFL); 75981187Skris 76081187Skris /* unblock the signal and send ourselves one */ 76181187Skris#ifdef SIGRELSE 76281187Skris sigrelse(SIGTSTP); 76381187Skris#else 76481187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 76581187Skris#endif 76681187Skris (void) kill(0, SIGTSTP); 76781187Skris 76881187Skris /* reset the signal handler */ 76981187Skris (void) signal(SIGTSTP, tstop); 77081187Skris 77181187Skris /* reinit screen */ 77281187Skris reinit_screen(); 77381187Skris reset_display(); 77481187Skris tstopflag = 0; 77581187Skris goto restart; 77681187Skris } 77781187Skris 77881187Skris if (winchflag) { 77981187Skris /* reascertain the screen dimensions */ 78081187Skris get_screensize(); 78181187Skris 78281187Skris /* tell display to resize */ 78381187Skris max_topn = display_resize(); 78481187Skris 78581187Skris /* reset the signal handler */ 78681187Skris (void) signal(SIGWINCH, winch); 78781187Skris 78881187Skris reset_display(); 78981187Skris winchflag = 0; 79081187Skris goto restart; 79181187Skris } 79281187Skris 79324139Sjoerg /* wait for either input or the end of the delay period */ 79486042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 79586042Sdwmalone if (sel_ret < 0 && errno != EINTR) 79686042Sdwmalone quit(0); 79786042Sdwmalone if (sel_ret > 0) 79824139Sjoerg { 79924139Sjoerg int newval; 80024139Sjoerg char *errmsg; 80124139Sjoerg 80224139Sjoerg /* something to read -- clear the message area first */ 80324139Sjoerg clear_message(); 80424139Sjoerg 80524139Sjoerg /* now read it and convert to command strchr */ 80624139Sjoerg /* (use "change" as a temporary to hold strchr) */ 80786042Sdwmalone if (read(0, &ch, 1) != 1) 80889757Sdwmalone { 80989757Sdwmalone /* read error: either 0 or -1 */ 81089757Sdwmalone new_message(MT_standout, " Read error on stdin"); 81189757Sdwmalone putchar('\r'); 81289757Sdwmalone quit(1); 81389757Sdwmalone /*NOTREACHED*/ 81489757Sdwmalone } 81524139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 81624139Sjoerg { 81724142Sjoerg if (ch != '\r' && ch != '\n') 81824142Sjoerg { 81924142Sjoerg /* illegal command */ 82024142Sjoerg new_message(MT_standout, " Command not understood"); 82124142Sjoerg } 82224139Sjoerg putchar('\r'); 82324139Sjoerg no_command = Yes; 82424139Sjoerg } 82524139Sjoerg else 82624139Sjoerg { 82724139Sjoerg change = iptr - command_chars; 82824139Sjoerg if (overstrike && change > CMD_OSLIMIT) 82924139Sjoerg { 83024139Sjoerg /* error */ 83124139Sjoerg new_message(MT_standout, 83224139Sjoerg " Command cannot be handled by this terminal"); 83324139Sjoerg putchar('\r'); 83424139Sjoerg no_command = Yes; 83524139Sjoerg } 83624139Sjoerg else switch(change) 83724139Sjoerg { 83824139Sjoerg case CMD_redraw: /* redraw screen */ 83924139Sjoerg reset_display(); 84024139Sjoerg break; 84124139Sjoerg 84224139Sjoerg case CMD_update: /* merely update display */ 84324139Sjoerg /* is the load average high? */ 84424139Sjoerg if (system_info.load_avg[0] > LoadMax) 84524139Sjoerg { 84624139Sjoerg /* yes, go home for visual feedback */ 84724139Sjoerg go_home(); 84824139Sjoerg fflush(stdout); 84924139Sjoerg } 85024139Sjoerg break; 85124139Sjoerg 85224139Sjoerg case CMD_quit: /* quit */ 85324139Sjoerg quit(0); 85424139Sjoerg /*NOTREACHED*/ 85524139Sjoerg break; 85624139Sjoerg 85724139Sjoerg case CMD_help1: /* help */ 85824139Sjoerg case CMD_help2: 85924139Sjoerg reset_display(); 86024139Sjoerg clear(); 86124139Sjoerg show_help(); 86224139Sjoerg standout("Hit any key to continue: "); 86324139Sjoerg fflush(stdout); 86424139Sjoerg (void) read(0, &ch, 1); 86524139Sjoerg break; 86624139Sjoerg 86724139Sjoerg case CMD_errors: /* show errors */ 86824139Sjoerg if (error_count() == 0) 86924139Sjoerg { 87024139Sjoerg new_message(MT_standout, 87124139Sjoerg " Currently no errors to report."); 87224139Sjoerg putchar('\r'); 87324139Sjoerg no_command = Yes; 87424139Sjoerg } 87524139Sjoerg else 87624139Sjoerg { 87724139Sjoerg reset_display(); 87824139Sjoerg clear(); 87924139Sjoerg show_errors(); 88024139Sjoerg standout("Hit any key to continue: "); 88124139Sjoerg fflush(stdout); 88224139Sjoerg (void) read(0, &ch, 1); 88324139Sjoerg } 88424139Sjoerg break; 88524139Sjoerg 88624139Sjoerg case CMD_number1: /* new number */ 88724139Sjoerg case CMD_number2: 88824139Sjoerg new_message(MT_standout, 88924139Sjoerg "Number of processes to show: "); 89024139Sjoerg newval = readline(tempbuf1, 8, Yes); 89124139Sjoerg if (newval > -1) 89224139Sjoerg { 89324139Sjoerg if (newval > max_topn) 89424139Sjoerg { 89524139Sjoerg new_message(MT_standout | MT_delayed, 89624139Sjoerg " This terminal can only display %d processes.", 89724139Sjoerg max_topn); 89824139Sjoerg putchar('\r'); 89924139Sjoerg } 90024139Sjoerg 90124139Sjoerg if (newval == 0) 90224139Sjoerg { 90324139Sjoerg /* inhibit the header */ 90424139Sjoerg display_header(No); 90524139Sjoerg } 90624139Sjoerg else if (newval > topn && topn == 0) 90724139Sjoerg { 90824139Sjoerg /* redraw the header */ 90924139Sjoerg display_header(Yes); 91024139Sjoerg d_header = i_header; 91124139Sjoerg } 91224139Sjoerg topn = newval; 91324139Sjoerg } 91424139Sjoerg break; 91524139Sjoerg 91624139Sjoerg case CMD_delay: /* new seconds delay */ 91724139Sjoerg new_message(MT_standout, "Seconds to delay: "); 91824139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 91924139Sjoerg { 92089757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 92189757Sdwmalone { 92289757Sdwmalone delay = 1; 92389757Sdwmalone } 92424139Sjoerg } 92524139Sjoerg clear_message(); 92624139Sjoerg break; 92724139Sjoerg 92824139Sjoerg case CMD_displays: /* change display count */ 92924139Sjoerg new_message(MT_standout, 93024139Sjoerg "Displays to show (currently %s): ", 93124139Sjoerg displays == -1 ? "infinite" : 93224139Sjoerg itoa(displays)); 93324139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 93424139Sjoerg { 93524139Sjoerg displays = i; 93624139Sjoerg } 93724139Sjoerg else if (i == 0) 93824139Sjoerg { 93924139Sjoerg quit(0); 94024139Sjoerg } 94124139Sjoerg clear_message(); 94224139Sjoerg break; 94324139Sjoerg 94424139Sjoerg case CMD_kill: /* kill program */ 94524139Sjoerg new_message(0, "kill "); 94624139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 94724139Sjoerg { 94824139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 94924139Sjoerg { 95066641Simp new_message(MT_standout, "%s", errmsg); 95124139Sjoerg putchar('\r'); 95224139Sjoerg no_command = Yes; 95324139Sjoerg } 95424139Sjoerg } 95524139Sjoerg else 95624139Sjoerg { 95724139Sjoerg clear_message(); 95824139Sjoerg } 95924139Sjoerg break; 96024139Sjoerg 96124139Sjoerg case CMD_renice: /* renice program */ 96224139Sjoerg new_message(0, "renice "); 96324139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 96424139Sjoerg { 96524139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 96624139Sjoerg { 96768293Simp new_message(MT_standout, "%s", errmsg); 96824139Sjoerg putchar('\r'); 96924139Sjoerg no_command = Yes; 97024139Sjoerg } 97124139Sjoerg } 97224139Sjoerg else 97324139Sjoerg { 97424139Sjoerg clear_message(); 97524139Sjoerg } 97624139Sjoerg break; 97724139Sjoerg 97824139Sjoerg case CMD_idletog: 97924139Sjoerg case CMD_idletog2: 98024139Sjoerg ps.idle = !ps.idle; 98124139Sjoerg new_message(MT_standout | MT_delayed, 98224139Sjoerg " %sisplaying idle processes.", 98324139Sjoerg ps.idle ? "D" : "Not d"); 98424139Sjoerg putchar('\r'); 98524139Sjoerg break; 98624139Sjoerg 98738090Sdes case CMD_selftog: 98838090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 98938090Sdes new_message(MT_standout | MT_delayed, 99038090Sdes " %sisplaying self.", 99138090Sdes (ps.self == -1) ? "D" : "Not d"); 99238090Sdes putchar('\r'); 99338090Sdes break; 99438090Sdes 99524139Sjoerg case CMD_user: 99624139Sjoerg new_message(MT_standout, 99724139Sjoerg "Username to show: "); 99824139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 99924139Sjoerg { 100024139Sjoerg if (tempbuf2[0] == '+' && 100124139Sjoerg tempbuf2[1] == '\0') 100224139Sjoerg { 100324139Sjoerg ps.uid = -1; 100424139Sjoerg } 100524139Sjoerg else if ((i = userid(tempbuf2)) == -1) 100624139Sjoerg { 100724139Sjoerg new_message(MT_standout, 100824139Sjoerg " %s: unknown user", tempbuf2); 100924139Sjoerg no_command = Yes; 101024139Sjoerg } 101124139Sjoerg else 101224139Sjoerg { 101324139Sjoerg ps.uid = i; 101424139Sjoerg } 101524139Sjoerg putchar('\r'); 101624139Sjoerg } 101724139Sjoerg else 101824139Sjoerg { 101924139Sjoerg clear_message(); 102024139Sjoerg } 102124139Sjoerg break; 102224139Sjoerg 1023117709Sjulian case CMD_thrtog: 1024117709Sjulian ps.thread = !ps.thread; 1025117709Sjulian new_message(MT_standout | MT_delayed, 1026223937Sjhb " Displaying threads %s", 1027145073Skeramida ps.thread ? "separately" : "as a count"); 1028145073Skeramida header_text = format_header(uname_field); 1029145073Skeramida reset_display(); 1030117709Sjulian putchar('\r'); 1031117709Sjulian break; 1032146342Skeramida case CMD_wcputog: 1033146342Skeramida ps.wcpu = !ps.wcpu; 1034146342Skeramida new_message(MT_standout | MT_delayed, 1035224204Sjhb " Displaying %s CPU", 1036224204Sjhb ps.wcpu ? "weighted" : "raw"); 1037146342Skeramida header_text = format_header(uname_field); 1038146342Skeramida reset_display(); 1039146342Skeramida putchar('\r'); 1040146342Skeramida break; 1041131402Salfred case CMD_viewtog: 1042131402Salfred if (++displaymode == DISP_MAX) 1043131402Salfred displaymode = 0; 1044131402Salfred header_text = format_header(uname_field); 1045131402Salfred display_header(Yes); 1046131402Salfred d_header = i_header; 1047131402Salfred reset_display(); 1048131402Salfred break; 1049132005Salfred case CMD_viewsys: 1050132005Salfred ps.system = !ps.system; 1051132005Salfred break; 1052168710Sstas case CMD_showargs: 1053168710Sstas fmt_flags ^= FMT_SHOWARGS; 1054168710Sstas break; 105524139Sjoerg#ifdef ORDER 105624139Sjoerg case CMD_order: 105724139Sjoerg new_message(MT_standout, 105824139Sjoerg "Order to sort: "); 105924139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 106024139Sjoerg { 106124139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 106224139Sjoerg { 106324139Sjoerg new_message(MT_standout, 106424139Sjoerg " %s: unrecognized sorting order", tempbuf2); 106524139Sjoerg no_command = Yes; 106624139Sjoerg } 106724139Sjoerg else 106824139Sjoerg { 106924139Sjoerg order_index = i; 107024139Sjoerg } 107124139Sjoerg putchar('\r'); 107224139Sjoerg } 107324139Sjoerg else 107424139Sjoerg { 107524139Sjoerg clear_message(); 107624139Sjoerg } 107724139Sjoerg break; 107824139Sjoerg#endif 1079168799Srafan case CMD_jidtog: 1080168799Srafan ps.jail = !ps.jail; 1081168799Srafan new_message(MT_standout | MT_delayed, 1082169257Srafan " %sisplaying jail ID.", 1083168799Srafan ps.jail ? "D" : "Not d"); 1084168799Srafan header_text = format_header(uname_field); 1085168799Srafan reset_display(); 1086168799Srafan putchar('\r'); 1087168799Srafan break; 1088222530Sjhb case CMD_kidletog: 1089222530Sjhb ps.kidle = !ps.kidle; 1090222530Sjhb new_message(MT_standout | MT_delayed, 1091222530Sjhb " %sisplaying system idle process.", 1092222530Sjhb ps.kidle ? "D" : "Not d"); 1093222530Sjhb putchar('\r'); 1094222530Sjhb break; 1095223936Sjhb case CMD_pcputog: 1096223936Sjhb pcpu_stats = !pcpu_stats; 1097223936Sjhb new_message(MT_standout | MT_delayed, 1098223936Sjhb " Displaying %sCPU statistics.", 1099223936Sjhb pcpu_stats ? "per-" : "global "); 1100224205Sjhb toggle_pcpustats(); 1101223936Sjhb max_topn = display_updatecpus(&statics); 1102223936Sjhb reset_display(); 1103223936Sjhb putchar('\r'); 1104223936Sjhb break; 110524139Sjoerg default: 110624139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 110724139Sjoerg putchar('\r'); 110824139Sjoerg } 110924139Sjoerg } 111024139Sjoerg 111124139Sjoerg /* flush out stuff that may have been written */ 111224139Sjoerg fflush(stdout); 111324139Sjoerg } 111424139Sjoerg } 111524139Sjoerg } 111624139Sjoerg } 111724139Sjoerg 111889757Sdwmalone#ifdef DEBUG 111989757Sdwmalone fclose(debug); 112089757Sdwmalone#endif 112124139Sjoerg quit(0); 112224139Sjoerg /*NOTREACHED*/ 112324139Sjoerg} 112424139Sjoerg 112524139Sjoerg/* 112624139Sjoerg * reset_display() - reset all the display routine pointers so that entire 112724139Sjoerg * screen will get redrawn. 112824139Sjoerg */ 112924139Sjoerg 113024139Sjoergreset_display() 113124139Sjoerg 113224139Sjoerg{ 113324139Sjoerg d_loadave = i_loadave; 113424139Sjoerg d_procstates = i_procstates; 113524139Sjoerg d_cpustates = i_cpustates; 113624139Sjoerg d_memory = i_memory; 1137237656Sjhb d_arc = i_arc; 113824142Sjoerg d_swap = i_swap; 113924139Sjoerg d_message = i_message; 114024139Sjoerg d_header = i_header; 114124139Sjoerg d_process = i_process; 114224139Sjoerg} 114324139Sjoerg 114424139Sjoerg/* 114524139Sjoerg * signal handlers 114624139Sjoerg */ 114724139Sjoerg 114824139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 114924139Sjoerg 115024139Sjoerg{ 115181187Skris leaveflag = 1; 115224139Sjoerg} 115324139Sjoerg 115424139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 115524139Sjoerg 115624139Sjoergint i; 115724139Sjoerg 115824139Sjoerg{ 115981187Skris tstopflag = 1; 116024139Sjoerg} 116124139Sjoerg 116224139Sjoerg#ifdef SIGWINCH 116324139Sjoergsigret_t winch(i) /* SIGWINCH handler */ 116424139Sjoerg 116524139Sjoergint i; 116624139Sjoerg 116724139Sjoerg{ 116881187Skris winchflag = 1; 116924139Sjoerg} 117024139Sjoerg#endif 117124139Sjoerg 117224139Sjoergvoid quit(status) /* exit under duress */ 117324139Sjoerg 117424139Sjoergint status; 117524139Sjoerg 117624139Sjoerg{ 117724139Sjoerg end_screen(); 117824139Sjoerg exit(status); 117924139Sjoerg /*NOTREACHED*/ 118024139Sjoerg} 1181