top.c revision 232660
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: head/contrib/top/top.c 232660 2012-03-07 18:05:45Z kib $ 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(); 12424142Sjoergint i_swap(); 12524142Sjoergint u_swap(); 12624139Sjoergint i_message(); 12724139Sjoergint u_message(); 12824139Sjoergint i_header(); 12924139Sjoergint u_header(); 13024139Sjoergint i_process(); 13124139Sjoergint u_process(); 13224139Sjoerg 13324139Sjoerg/* pointers to display routines */ 13424139Sjoergint (*d_loadave)() = i_loadave; 13524139Sjoergint (*d_procstates)() = i_procstates; 13624139Sjoergint (*d_cpustates)() = i_cpustates; 13724139Sjoergint (*d_memory)() = i_memory; 13824142Sjoergint (*d_swap)() = i_swap; 13924139Sjoergint (*d_message)() = i_message; 14024139Sjoergint (*d_header)() = i_header; 14124139Sjoergint (*d_process)() = i_process; 14224139Sjoerg 14324139Sjoerg 14424139Sjoergmain(argc, argv) 14524139Sjoerg 14624139Sjoergint argc; 14724139Sjoergchar *argv[]; 14824139Sjoerg 14924139Sjoerg{ 15024139Sjoerg register int i; 15124139Sjoerg register int active_procs; 15224139Sjoerg register int change; 15324139Sjoerg 15424139Sjoerg struct system_info system_info; 15524139Sjoerg struct statics statics; 15624139Sjoerg caddr_t processes; 15724139Sjoerg 15824139Sjoerg static char tempbuf1[50]; 15924139Sjoerg static char tempbuf2[50]; 16024139Sjoerg int old_sigmask; /* only used for BSD-style signals */ 16124139Sjoerg int topn = Default_TOPN; 16224139Sjoerg int delay = Default_DELAY; 16324139Sjoerg int displays = 0; /* indicates unspecified */ 16486042Sdwmalone int sel_ret = 0; 16524139Sjoerg time_t curr_time; 16624139Sjoerg char *(*get_userid)() = username; 16724139Sjoerg char *uname_field = "USERNAME"; 16824139Sjoerg char *header_text; 16924139Sjoerg char *env_top; 17024139Sjoerg char **preset_argv; 17124139Sjoerg int preset_argc = 0; 17224139Sjoerg char **av; 17324139Sjoerg int ac; 17424139Sjoerg char dostates = No; 17524139Sjoerg char do_unames = Yes; 17624139Sjoerg char interactive = Maybe; 17724139Sjoerg char warnings = 0; 17824139Sjoerg#if Default_TOPN == Infinity 17924139Sjoerg char topn_specified = No; 18024139Sjoerg#endif 18124139Sjoerg char ch; 18224139Sjoerg char *iptr; 18324139Sjoerg char no_command = 1; 18424139Sjoerg struct timeval timeout; 18524139Sjoerg#ifdef ORDER 18624139Sjoerg char *order_name = NULL; 18724139Sjoerg int order_index = 0; 18824139Sjoerg#endif 18924139Sjoerg#ifndef FD_SET 19024139Sjoerg /* FD_SET and friends are not present: fake it */ 19124139Sjoerg typedef int fd_set; 19224139Sjoerg#define FD_ZERO(x) (*(x) = 0) 19389757Sdwmalone#define FD_SET(f, x) (*(x) = 1<<f) 19424139Sjoerg#endif 19524139Sjoerg fd_set readfds; 19624139Sjoerg 19724139Sjoerg#ifdef ORDER 198223936Sjhb static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPo"; 19924139Sjoerg#else 200223936Sjhb static char command_chars[] = "\f qh?en#sdkriIutHmSCajzP"; 20124139Sjoerg#endif 20224139Sjoerg/* these defines enumerate the "strchr"s of the commands in command_chars */ 20324139Sjoerg#define CMD_redraw 0 20424139Sjoerg#define CMD_update 1 20524139Sjoerg#define CMD_quit 2 20624139Sjoerg#define CMD_help1 3 20724139Sjoerg#define CMD_help2 4 20824139Sjoerg#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ 20924139Sjoerg#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ 21024139Sjoerg#define CMD_number1 6 21124139Sjoerg#define CMD_number2 7 21224139Sjoerg#define CMD_delay 8 21324139Sjoerg#define CMD_displays 9 21424139Sjoerg#define CMD_kill 10 21524139Sjoerg#define CMD_renice 11 21624139Sjoerg#define CMD_idletog 12 21724139Sjoerg#define CMD_idletog2 13 21824139Sjoerg#define CMD_user 14 21938090Sdes#define CMD_selftog 15 220117709Sjulian#define CMD_thrtog 16 221131402Salfred#define CMD_viewtog 17 222132005Salfred#define CMD_viewsys 18 223146342Skeramida#define CMD_wcputog 19 224168710Sstas#define CMD_showargs 20 225168799Srafan#define CMD_jidtog 21 226222530Sjhb#define CMD_kidletog 22 227223936Sjhb#define CMD_pcputog 23 22824139Sjoerg#ifdef ORDER 229223936Sjhb#define CMD_order 24 23024139Sjoerg#endif 23124139Sjoerg 23224139Sjoerg /* set the buffer for stdout */ 23324139Sjoerg#ifdef DEBUG 23489757Sdwmalone extern FILE *debug; 23589757Sdwmalone debug = fopen("debug.run", "w"); 23624139Sjoerg setbuffer(stdout, NULL, 0); 23724139Sjoerg#else 23824139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 23924139Sjoerg#endif 24024139Sjoerg 24124139Sjoerg /* get our name */ 24224139Sjoerg if (argc > 0) 24324139Sjoerg { 24424139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 24524139Sjoerg { 24624139Sjoerg myname = argv[0]; 24724139Sjoerg } 24824139Sjoerg else 24924139Sjoerg { 25024139Sjoerg myname++; 25124139Sjoerg } 25224139Sjoerg } 25324139Sjoerg 25424139Sjoerg /* initialize some selection options */ 25524139Sjoerg ps.idle = Yes; 25638090Sdes ps.self = -1; 25724139Sjoerg ps.system = No; 25824139Sjoerg ps.uid = -1; 259117709Sjulian ps.thread = No; 260146342Skeramida ps.wcpu = 1; 261168799Srafan ps.jail = No; 262222530Sjhb ps.kidle = Yes; 26324139Sjoerg ps.command = NULL; 26424139Sjoerg 26524139Sjoerg /* get preset options from the environment */ 26624139Sjoerg if ((env_top = getenv("TOP")) != NULL) 26724139Sjoerg { 26824139Sjoerg av = preset_argv = argparse(env_top, &preset_argc); 26924139Sjoerg ac = preset_argc; 27024139Sjoerg 27124139Sjoerg /* set the dummy argument to an explanatory message, in case 27224139Sjoerg getopt encounters a bad argument */ 27324139Sjoerg preset_argv[0] = "while processing environment"; 27424139Sjoerg } 27524139Sjoerg 27624139Sjoerg /* process options */ 27724139Sjoerg do { 27824139Sjoerg /* if we're done doing the presets, then process the real arguments */ 27924139Sjoerg if (preset_argc == 0) 28024139Sjoerg { 28124139Sjoerg ac = argc; 28224139Sjoerg av = argv; 28324139Sjoerg 28424139Sjoerg /* this should keep getopt happy... */ 28524139Sjoerg optind = 1; 28624139Sjoerg } 28724139Sjoerg 288222530Sjhb while ((i = getopt(ac, av, "CSIHPabijnquvzs:d:U:m:o:t")) != EOF) 28924139Sjoerg { 29024139Sjoerg switch(i) 29124139Sjoerg { 29289757Sdwmalone case 'v': /* show version number */ 29389757Sdwmalone fprintf(stderr, "%s: version %s\n", 29489757Sdwmalone myname, version_string()); 29589757Sdwmalone exit(1); 29689757Sdwmalone break; 29789757Sdwmalone 29824139Sjoerg case 'u': /* toggle uid/username display */ 29924139Sjoerg do_unames = !do_unames; 30024139Sjoerg break; 30124139Sjoerg 30224139Sjoerg case 'U': /* display only username's processes */ 30324139Sjoerg if ((ps.uid = userid(optarg)) == -1) 30424139Sjoerg { 30524139Sjoerg fprintf(stderr, "%s: unknown user\n", optarg); 30624139Sjoerg exit(1); 30724139Sjoerg } 30824139Sjoerg break; 30924139Sjoerg 31024139Sjoerg case 'S': /* show system processes */ 31124139Sjoerg ps.system = !ps.system; 31224139Sjoerg break; 31324139Sjoerg 31424139Sjoerg case 'I': /* show idle processes */ 31524139Sjoerg ps.idle = !ps.idle; 31624139Sjoerg break; 31724139Sjoerg 31824139Sjoerg case 'i': /* go interactive regardless */ 31924139Sjoerg interactive = Yes; 32024139Sjoerg break; 32124139Sjoerg 32224139Sjoerg case 'n': /* batch, or non-interactive */ 32324139Sjoerg case 'b': 32424139Sjoerg interactive = No; 32524139Sjoerg break; 32624139Sjoerg 327168710Sstas case 'a': 328168710Sstas fmt_flags ^= FMT_SHOWARGS; 329168710Sstas break; 330168710Sstas 33124139Sjoerg case 'd': /* number of displays to show */ 33224139Sjoerg if ((i = atoiwi(optarg)) == Invalid || i == 0) 33324139Sjoerg { 33424139Sjoerg fprintf(stderr, 33524139Sjoerg "%s: warning: display count should be positive -- option ignored\n", 33624139Sjoerg myname); 33724139Sjoerg warnings++; 33824139Sjoerg } 33924139Sjoerg else 34024139Sjoerg { 34124139Sjoerg displays = i; 34224139Sjoerg } 34324139Sjoerg break; 34424139Sjoerg 34524139Sjoerg case 's': 34689757Sdwmalone if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) 34724139Sjoerg { 34824139Sjoerg fprintf(stderr, 34989757Sdwmalone "%s: warning: seconds delay should be positive -- using default\n", 35024139Sjoerg myname); 35124139Sjoerg delay = Default_DELAY; 35224139Sjoerg warnings++; 35324139Sjoerg } 35424139Sjoerg break; 35524139Sjoerg 35624139Sjoerg case 'q': /* be quick about it */ 35724139Sjoerg /* only allow this if user is really root */ 35824139Sjoerg if (getuid() == 0) 35924139Sjoerg { 36024139Sjoerg /* be very un-nice! */ 36124139Sjoerg (void) nice(-20); 36224139Sjoerg } 36324139Sjoerg else 36424139Sjoerg { 36524139Sjoerg fprintf(stderr, 36624139Sjoerg "%s: warning: `-q' option can only be used by root\n", 36724139Sjoerg myname); 36824139Sjoerg warnings++; 36924139Sjoerg } 37024139Sjoerg break; 37124139Sjoerg 372131616Sdes case 'm': /* select display mode */ 373131402Salfred if (strcmp(optarg, "io") == 0) { 374131402Salfred displaymode = DISP_IO; 375131402Salfred } else if (strcmp(optarg, "cpu") == 0) { 376131402Salfred displaymode = DISP_CPU; 377131402Salfred } else { 378131402Salfred fprintf(stderr, 379131402Salfred "%s: warning: `-m' option can only take args " 380131402Salfred "'io' or 'cpu'\n", 381131402Salfred myname); 382131402Salfred exit(1); 383131402Salfred } 384131402Salfred break; 385131402Salfred 38624139Sjoerg case 'o': /* select sort order */ 38724139Sjoerg#ifdef ORDER 38824139Sjoerg order_name = optarg; 38924139Sjoerg#else 39024139Sjoerg fprintf(stderr, 39124139Sjoerg "%s: this platform does not support arbitrary ordering. Sorry.\n", 39224139Sjoerg myname); 39324139Sjoerg warnings++; 39424139Sjoerg#endif 39524139Sjoerg break; 39624139Sjoerg 39738090Sdes case 't': 39838090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 39938090Sdes break; 400146342Skeramida 401146342Skeramida case 'C': 402146342Skeramida ps.wcpu = !ps.wcpu; 403146342Skeramida break; 404146342Skeramida 405117709Sjulian case 'H': 406117709Sjulian ps.thread = !ps.thread; 407117709Sjulian break; 408146342Skeramida 409168799Srafan case 'j': 410168799Srafan ps.jail = !ps.jail; 411168799Srafan break; 412168799Srafan 413175420Speter case 'P': 414223936Sjhb pcpu_stats = !pcpu_stats; 415175420Speter break; 416175420Speter 417222530Sjhb case 'z': 418222530Sjhb ps.kidle = !ps.kidle; 419222530Sjhb break; 420222530Sjhb 42124139Sjoerg default: 422157842Sru fprintf(stderr, 423157842Sru"Top version %s\n" 424222530Sjhb"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 425157842Sru" [-U username] [number]\n", 42624139Sjoerg version_string(), myname); 42724139Sjoerg exit(1); 42824139Sjoerg } 42924139Sjoerg } 43024139Sjoerg 43124139Sjoerg /* get count of top processes to display (if any) */ 43224139Sjoerg if (optind < ac) 43324139Sjoerg { 43424139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 43524139Sjoerg { 43624139Sjoerg fprintf(stderr, 43724139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 43824139Sjoerg myname); 43924139Sjoerg warnings++; 44024139Sjoerg } 44124139Sjoerg#if Default_TOPN == Infinity 44224139Sjoerg else 44324139Sjoerg { 44424139Sjoerg topn_specified = Yes; 44524139Sjoerg } 44624139Sjoerg#endif 44724139Sjoerg } 44824139Sjoerg 44924139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 45024139Sjoerg i = preset_argc; 45124139Sjoerg preset_argc = 0; 45224139Sjoerg 45324139Sjoerg /* repeat only if we really did the preset arguments */ 45424139Sjoerg } while (i != 0); 45524139Sjoerg 45624139Sjoerg /* set constants for username/uid display correctly */ 45724139Sjoerg if (!do_unames) 45824139Sjoerg { 45924139Sjoerg uname_field = " UID "; 46024139Sjoerg get_userid = itoa7; 46124139Sjoerg } 46224139Sjoerg 46324139Sjoerg /* initialize the kernel memory interface */ 464175195Sobrien if (machine_init(&statics, do_unames) == -1) 46524139Sjoerg { 46624139Sjoerg exit(1); 46724139Sjoerg } 46824139Sjoerg 46924139Sjoerg#ifdef ORDER 47024139Sjoerg /* determine sorting order index, if necessary */ 47124139Sjoerg if (order_name != NULL) 47224139Sjoerg { 47324139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 47424139Sjoerg { 47524139Sjoerg char **pp; 47624139Sjoerg 47724139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 47824139Sjoerg myname, order_name); 47924139Sjoerg fprintf(stderr, "\tTry one of these:"); 48024139Sjoerg pp = statics.order_names; 48124139Sjoerg while (*pp != NULL) 48224139Sjoerg { 48324139Sjoerg fprintf(stderr, " %s", *pp++); 48424139Sjoerg } 48524139Sjoerg fputc('\n', stderr); 48624139Sjoerg exit(1); 48724139Sjoerg } 48824139Sjoerg } 48924139Sjoerg#endif 49024139Sjoerg 49124139Sjoerg#ifdef no_initialization_needed 49224139Sjoerg /* initialize the hashing stuff */ 49324139Sjoerg if (do_unames) 49424139Sjoerg { 49524139Sjoerg init_hash(); 49624139Sjoerg } 49724139Sjoerg#endif 49824139Sjoerg 49924139Sjoerg /* initialize termcap */ 50024139Sjoerg init_termcap(interactive); 50124139Sjoerg 50224139Sjoerg /* get the string to use for the process area header */ 50324139Sjoerg header_text = format_header(uname_field); 50424139Sjoerg 50524139Sjoerg /* initialize display interface */ 50624139Sjoerg if ((max_topn = display_init(&statics)) == -1) 50724139Sjoerg { 50824139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 50924139Sjoerg exit(4); 51024139Sjoerg } 51124139Sjoerg 51224139Sjoerg /* print warning if user requested more processes than we can display */ 51324139Sjoerg if (topn > max_topn) 51424139Sjoerg { 51524139Sjoerg fprintf(stderr, 51624139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 51724139Sjoerg myname, max_topn); 51824139Sjoerg warnings++; 51924139Sjoerg } 52024139Sjoerg 52124139Sjoerg /* adjust for topn == Infinity */ 52224139Sjoerg if (topn == Infinity) 52324139Sjoerg { 52424139Sjoerg /* 52524139Sjoerg * For smart terminals, infinity really means everything that can 52624139Sjoerg * be displayed, or Largest. 52724139Sjoerg * On dumb terminals, infinity means every process in the system! 52824139Sjoerg * We only really want to do that if it was explicitly specified. 52924139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 53024139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 53124139Sjoerg * and the default is Infinity, then (and only then) we use 53224139Sjoerg * "Nominal_TOPN" instead. 53324139Sjoerg */ 53424139Sjoerg#if Default_TOPN == Infinity 53524139Sjoerg topn = smart_terminal ? Largest : 53624139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 53724139Sjoerg#else 53824139Sjoerg topn = Largest; 53924139Sjoerg#endif 54024139Sjoerg } 54124139Sjoerg 54224139Sjoerg /* set header display accordingly */ 54324139Sjoerg display_header(topn > 0); 54424139Sjoerg 54524139Sjoerg /* determine interactive state */ 54624139Sjoerg if (interactive == Maybe) 54724139Sjoerg { 54824139Sjoerg interactive = smart_terminal; 54924139Sjoerg } 55024139Sjoerg 55124139Sjoerg /* if # of displays not specified, fill it in */ 55224139Sjoerg if (displays == 0) 55324139Sjoerg { 55424139Sjoerg displays = smart_terminal ? Infinity : 1; 55524139Sjoerg } 55624139Sjoerg 55724139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 55824139Sjoerg#ifdef SIGHOLD 55924139Sjoerg sighold(SIGINT); 56024139Sjoerg sighold(SIGQUIT); 56124139Sjoerg sighold(SIGTSTP); 56224139Sjoerg#else 56324139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 56424139Sjoerg#endif 56524139Sjoerg init_screen(); 56624139Sjoerg (void) signal(SIGINT, leave); 56724139Sjoerg (void) signal(SIGQUIT, leave); 56824139Sjoerg (void) signal(SIGTSTP, tstop); 56924139Sjoerg#ifdef SIGWINCH 57024139Sjoerg (void) signal(SIGWINCH, winch); 57124139Sjoerg#endif 57224139Sjoerg#ifdef SIGRELSE 57324139Sjoerg sigrelse(SIGINT); 57424139Sjoerg sigrelse(SIGQUIT); 57524139Sjoerg sigrelse(SIGTSTP); 57624139Sjoerg#else 57724139Sjoerg (void) sigsetmask(old_sigmask); 57824139Sjoerg#endif 57924139Sjoerg if (warnings) 58024139Sjoerg { 58124139Sjoerg fputs("....", stderr); 58224139Sjoerg fflush(stderr); /* why must I do this? */ 58324139Sjoerg sleep((unsigned)(3 * warnings)); 58424139Sjoerg fputc('\n', stderr); 58524139Sjoerg } 58624139Sjoerg 58781187Skrisrestart: 58824139Sjoerg 58924139Sjoerg /* 59024139Sjoerg * main loop -- repeat while display count is positive or while it 59124139Sjoerg * indicates infinity (by being -1) 59224139Sjoerg */ 59324139Sjoerg 59424139Sjoerg while ((displays == -1) || (displays-- > 0)) 59524139Sjoerg { 596131402Salfred int (*compare)(); 597131402Salfred 598131402Salfred 59924139Sjoerg /* get the current stats */ 60024139Sjoerg get_system_info(&system_info); 60124139Sjoerg 60224139Sjoerg#ifdef ORDER 603133817Salfred compare = compares[order_index]; 60424139Sjoerg#else 605131829Skeramida if (displaymode == DISP_CPU) 606131402Salfred compare = proc_compare; 607131829Skeramida else 608131829Skeramida compare = io_compare; 60924139Sjoerg#endif 61024139Sjoerg 611131402Salfred /* get the current set of processes */ 612131402Salfred processes = 613131402Salfred get_process_info(&system_info, &ps, compare); 614131402Salfred 61524139Sjoerg /* display the load averages */ 61624139Sjoerg (*d_loadave)(system_info.last_pid, 61724139Sjoerg system_info.load_avg); 61824139Sjoerg 61924139Sjoerg /* display the current time */ 62024139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 62124139Sjoerg time(&curr_time); 62242447Sobrien i_uptime(&system_info.boottime, &curr_time); 62324139Sjoerg i_timeofday(&curr_time); 62424139Sjoerg 62524139Sjoerg /* display process state breakdown */ 62624139Sjoerg (*d_procstates)(system_info.p_total, 62724139Sjoerg system_info.procstates); 62824139Sjoerg 62924139Sjoerg /* display the cpu state percentage breakdown */ 63024139Sjoerg if (dostates) /* but not the first time */ 63124139Sjoerg { 63224139Sjoerg (*d_cpustates)(system_info.cpustates); 63324139Sjoerg } 63424139Sjoerg else 63524139Sjoerg { 63624139Sjoerg /* we'll do it next time */ 63724139Sjoerg if (smart_terminal) 63824139Sjoerg { 63924139Sjoerg z_cpustates(); 64024139Sjoerg } 64124139Sjoerg else 64224139Sjoerg { 64324139Sjoerg putchar('\n'); 64424139Sjoerg } 64524139Sjoerg dostates = Yes; 64624139Sjoerg } 64724139Sjoerg 64824139Sjoerg /* display memory stats */ 64924139Sjoerg (*d_memory)(system_info.memory); 65024139Sjoerg 65124142Sjoerg /* display swap stats */ 65224142Sjoerg (*d_swap)(system_info.swap); 65324142Sjoerg 65424139Sjoerg /* handle message area */ 65524139Sjoerg (*d_message)(); 65624139Sjoerg 65724139Sjoerg /* update the header area */ 65824139Sjoerg (*d_header)(header_text); 65924139Sjoerg 66024139Sjoerg if (topn > 0) 66124139Sjoerg { 66224139Sjoerg /* determine number of processes to actually display */ 66324139Sjoerg /* this number will be the smallest of: active processes, 66424139Sjoerg number user requested, number current screen accomodates */ 66589757Sdwmalone active_procs = system_info.P_ACTIVE; 66624139Sjoerg if (active_procs > topn) 66724139Sjoerg { 66824139Sjoerg active_procs = topn; 66924139Sjoerg } 67024139Sjoerg if (active_procs > max_topn) 67124139Sjoerg { 67224139Sjoerg active_procs = max_topn; 67324139Sjoerg } 67424139Sjoerg 67524139Sjoerg /* now show the top "n" processes. */ 67624139Sjoerg for (i = 0; i < active_procs; i++) 67724139Sjoerg { 678168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 679168710Sstas fmt_flags)); 68024139Sjoerg } 68124139Sjoerg } 68224139Sjoerg else 68324139Sjoerg { 68424139Sjoerg i = 0; 68524139Sjoerg } 68624139Sjoerg 68724139Sjoerg /* do end-screen processing */ 68824139Sjoerg u_endscreen(i); 68924139Sjoerg 69024139Sjoerg /* now, flush the output buffer */ 69189757Sdwmalone if (fflush(stdout) != 0) 69289757Sdwmalone { 69389757Sdwmalone new_message(MT_standout, " Write error on stdout"); 69489757Sdwmalone putchar('\r'); 69589757Sdwmalone quit(1); 69689757Sdwmalone /*NOTREACHED*/ 69789757Sdwmalone } 69824139Sjoerg 69924139Sjoerg /* only do the rest if we have more displays to show */ 70024139Sjoerg if (displays) 70124139Sjoerg { 70224139Sjoerg /* switch out for new display on smart terminals */ 70324139Sjoerg if (smart_terminal) 70424139Sjoerg { 70524139Sjoerg if (overstrike) 70624139Sjoerg { 70724139Sjoerg reset_display(); 70824139Sjoerg } 70924139Sjoerg else 71024139Sjoerg { 71124139Sjoerg d_loadave = u_loadave; 71224139Sjoerg d_procstates = u_procstates; 71324139Sjoerg d_cpustates = u_cpustates; 71424139Sjoerg d_memory = u_memory; 71524142Sjoerg d_swap = u_swap; 71624139Sjoerg d_message = u_message; 71724139Sjoerg d_header = u_header; 71824139Sjoerg d_process = u_process; 71924139Sjoerg } 72024139Sjoerg } 72124139Sjoerg 72224139Sjoerg no_command = Yes; 72324139Sjoerg if (!interactive) 72424139Sjoerg { 725232239Skib sleep(delay); 726232660Skib if (leaveflag) { 727232660Skib end_screen(); 728232660Skib exit(0); 729232660Skib } 73024139Sjoerg } 73124139Sjoerg else while (no_command) 73224139Sjoerg { 73324139Sjoerg /* assume valid command unless told otherwise */ 73424139Sjoerg no_command = No; 73524139Sjoerg 73624139Sjoerg /* set up arguments for select with timeout */ 73724139Sjoerg FD_ZERO(&readfds); 73889757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 73924139Sjoerg timeout.tv_sec = delay; 74024139Sjoerg timeout.tv_usec = 0; 74124139Sjoerg 74281187Skris if (leaveflag) { 74381187Skris end_screen(); 74481187Skris exit(0); 74581187Skris } 74681187Skris 74781187Skris if (tstopflag) { 74881187Skris /* move to the lower left */ 74981187Skris end_screen(); 75081187Skris fflush(stdout); 75181187Skris 75281187Skris /* default the signal handler action */ 75381187Skris (void) signal(SIGTSTP, SIG_DFL); 75481187Skris 75581187Skris /* unblock the signal and send ourselves one */ 75681187Skris#ifdef SIGRELSE 75781187Skris sigrelse(SIGTSTP); 75881187Skris#else 75981187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 76081187Skris#endif 76181187Skris (void) kill(0, SIGTSTP); 76281187Skris 76381187Skris /* reset the signal handler */ 76481187Skris (void) signal(SIGTSTP, tstop); 76581187Skris 76681187Skris /* reinit screen */ 76781187Skris reinit_screen(); 76881187Skris reset_display(); 76981187Skris tstopflag = 0; 77081187Skris goto restart; 77181187Skris } 77281187Skris 77381187Skris if (winchflag) { 77481187Skris /* reascertain the screen dimensions */ 77581187Skris get_screensize(); 77681187Skris 77781187Skris /* tell display to resize */ 77881187Skris max_topn = display_resize(); 77981187Skris 78081187Skris /* reset the signal handler */ 78181187Skris (void) signal(SIGWINCH, winch); 78281187Skris 78381187Skris reset_display(); 78481187Skris winchflag = 0; 78581187Skris goto restart; 78681187Skris } 78781187Skris 78824139Sjoerg /* wait for either input or the end of the delay period */ 78986042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 79086042Sdwmalone if (sel_ret < 0 && errno != EINTR) 79186042Sdwmalone quit(0); 79286042Sdwmalone if (sel_ret > 0) 79324139Sjoerg { 79424139Sjoerg int newval; 79524139Sjoerg char *errmsg; 79624139Sjoerg 79724139Sjoerg /* something to read -- clear the message area first */ 79824139Sjoerg clear_message(); 79924139Sjoerg 80024139Sjoerg /* now read it and convert to command strchr */ 80124139Sjoerg /* (use "change" as a temporary to hold strchr) */ 80286042Sdwmalone if (read(0, &ch, 1) != 1) 80389757Sdwmalone { 80489757Sdwmalone /* read error: either 0 or -1 */ 80589757Sdwmalone new_message(MT_standout, " Read error on stdin"); 80689757Sdwmalone putchar('\r'); 80789757Sdwmalone quit(1); 80889757Sdwmalone /*NOTREACHED*/ 80989757Sdwmalone } 81024139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 81124139Sjoerg { 81224142Sjoerg if (ch != '\r' && ch != '\n') 81324142Sjoerg { 81424142Sjoerg /* illegal command */ 81524142Sjoerg new_message(MT_standout, " Command not understood"); 81624142Sjoerg } 81724139Sjoerg putchar('\r'); 81824139Sjoerg no_command = Yes; 81924139Sjoerg } 82024139Sjoerg else 82124139Sjoerg { 82224139Sjoerg change = iptr - command_chars; 82324139Sjoerg if (overstrike && change > CMD_OSLIMIT) 82424139Sjoerg { 82524139Sjoerg /* error */ 82624139Sjoerg new_message(MT_standout, 82724139Sjoerg " Command cannot be handled by this terminal"); 82824139Sjoerg putchar('\r'); 82924139Sjoerg no_command = Yes; 83024139Sjoerg } 83124139Sjoerg else switch(change) 83224139Sjoerg { 83324139Sjoerg case CMD_redraw: /* redraw screen */ 83424139Sjoerg reset_display(); 83524139Sjoerg break; 83624139Sjoerg 83724139Sjoerg case CMD_update: /* merely update display */ 83824139Sjoerg /* is the load average high? */ 83924139Sjoerg if (system_info.load_avg[0] > LoadMax) 84024139Sjoerg { 84124139Sjoerg /* yes, go home for visual feedback */ 84224139Sjoerg go_home(); 84324139Sjoerg fflush(stdout); 84424139Sjoerg } 84524139Sjoerg break; 84624139Sjoerg 84724139Sjoerg case CMD_quit: /* quit */ 84824139Sjoerg quit(0); 84924139Sjoerg /*NOTREACHED*/ 85024139Sjoerg break; 85124139Sjoerg 85224139Sjoerg case CMD_help1: /* help */ 85324139Sjoerg case CMD_help2: 85424139Sjoerg reset_display(); 85524139Sjoerg clear(); 85624139Sjoerg show_help(); 85724139Sjoerg standout("Hit any key to continue: "); 85824139Sjoerg fflush(stdout); 85924139Sjoerg (void) read(0, &ch, 1); 86024139Sjoerg break; 86124139Sjoerg 86224139Sjoerg case CMD_errors: /* show errors */ 86324139Sjoerg if (error_count() == 0) 86424139Sjoerg { 86524139Sjoerg new_message(MT_standout, 86624139Sjoerg " Currently no errors to report."); 86724139Sjoerg putchar('\r'); 86824139Sjoerg no_command = Yes; 86924139Sjoerg } 87024139Sjoerg else 87124139Sjoerg { 87224139Sjoerg reset_display(); 87324139Sjoerg clear(); 87424139Sjoerg show_errors(); 87524139Sjoerg standout("Hit any key to continue: "); 87624139Sjoerg fflush(stdout); 87724139Sjoerg (void) read(0, &ch, 1); 87824139Sjoerg } 87924139Sjoerg break; 88024139Sjoerg 88124139Sjoerg case CMD_number1: /* new number */ 88224139Sjoerg case CMD_number2: 88324139Sjoerg new_message(MT_standout, 88424139Sjoerg "Number of processes to show: "); 88524139Sjoerg newval = readline(tempbuf1, 8, Yes); 88624139Sjoerg if (newval > -1) 88724139Sjoerg { 88824139Sjoerg if (newval > max_topn) 88924139Sjoerg { 89024139Sjoerg new_message(MT_standout | MT_delayed, 89124139Sjoerg " This terminal can only display %d processes.", 89224139Sjoerg max_topn); 89324139Sjoerg putchar('\r'); 89424139Sjoerg } 89524139Sjoerg 89624139Sjoerg if (newval == 0) 89724139Sjoerg { 89824139Sjoerg /* inhibit the header */ 89924139Sjoerg display_header(No); 90024139Sjoerg } 90124139Sjoerg else if (newval > topn && topn == 0) 90224139Sjoerg { 90324139Sjoerg /* redraw the header */ 90424139Sjoerg display_header(Yes); 90524139Sjoerg d_header = i_header; 90624139Sjoerg } 90724139Sjoerg topn = newval; 90824139Sjoerg } 90924139Sjoerg break; 91024139Sjoerg 91124139Sjoerg case CMD_delay: /* new seconds delay */ 91224139Sjoerg new_message(MT_standout, "Seconds to delay: "); 91324139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 91424139Sjoerg { 91589757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 91689757Sdwmalone { 91789757Sdwmalone delay = 1; 91889757Sdwmalone } 91924139Sjoerg } 92024139Sjoerg clear_message(); 92124139Sjoerg break; 92224139Sjoerg 92324139Sjoerg case CMD_displays: /* change display count */ 92424139Sjoerg new_message(MT_standout, 92524139Sjoerg "Displays to show (currently %s): ", 92624139Sjoerg displays == -1 ? "infinite" : 92724139Sjoerg itoa(displays)); 92824139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 92924139Sjoerg { 93024139Sjoerg displays = i; 93124139Sjoerg } 93224139Sjoerg else if (i == 0) 93324139Sjoerg { 93424139Sjoerg quit(0); 93524139Sjoerg } 93624139Sjoerg clear_message(); 93724139Sjoerg break; 93824139Sjoerg 93924139Sjoerg case CMD_kill: /* kill program */ 94024139Sjoerg new_message(0, "kill "); 94124139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 94224139Sjoerg { 94324139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 94424139Sjoerg { 94566641Simp new_message(MT_standout, "%s", errmsg); 94624139Sjoerg putchar('\r'); 94724139Sjoerg no_command = Yes; 94824139Sjoerg } 94924139Sjoerg } 95024139Sjoerg else 95124139Sjoerg { 95224139Sjoerg clear_message(); 95324139Sjoerg } 95424139Sjoerg break; 95524139Sjoerg 95624139Sjoerg case CMD_renice: /* renice program */ 95724139Sjoerg new_message(0, "renice "); 95824139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 95924139Sjoerg { 96024139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 96124139Sjoerg { 96268293Simp new_message(MT_standout, "%s", errmsg); 96324139Sjoerg putchar('\r'); 96424139Sjoerg no_command = Yes; 96524139Sjoerg } 96624139Sjoerg } 96724139Sjoerg else 96824139Sjoerg { 96924139Sjoerg clear_message(); 97024139Sjoerg } 97124139Sjoerg break; 97224139Sjoerg 97324139Sjoerg case CMD_idletog: 97424139Sjoerg case CMD_idletog2: 97524139Sjoerg ps.idle = !ps.idle; 97624139Sjoerg new_message(MT_standout | MT_delayed, 97724139Sjoerg " %sisplaying idle processes.", 97824139Sjoerg ps.idle ? "D" : "Not d"); 97924139Sjoerg putchar('\r'); 98024139Sjoerg break; 98124139Sjoerg 98238090Sdes case CMD_selftog: 98338090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 98438090Sdes new_message(MT_standout | MT_delayed, 98538090Sdes " %sisplaying self.", 98638090Sdes (ps.self == -1) ? "D" : "Not d"); 98738090Sdes putchar('\r'); 98838090Sdes break; 98938090Sdes 99024139Sjoerg case CMD_user: 99124139Sjoerg new_message(MT_standout, 99224139Sjoerg "Username to show: "); 99324139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 99424139Sjoerg { 99524139Sjoerg if (tempbuf2[0] == '+' && 99624139Sjoerg tempbuf2[1] == '\0') 99724139Sjoerg { 99824139Sjoerg ps.uid = -1; 99924139Sjoerg } 100024139Sjoerg else if ((i = userid(tempbuf2)) == -1) 100124139Sjoerg { 100224139Sjoerg new_message(MT_standout, 100324139Sjoerg " %s: unknown user", tempbuf2); 100424139Sjoerg no_command = Yes; 100524139Sjoerg } 100624139Sjoerg else 100724139Sjoerg { 100824139Sjoerg ps.uid = i; 100924139Sjoerg } 101024139Sjoerg putchar('\r'); 101124139Sjoerg } 101224139Sjoerg else 101324139Sjoerg { 101424139Sjoerg clear_message(); 101524139Sjoerg } 101624139Sjoerg break; 101724139Sjoerg 1018117709Sjulian case CMD_thrtog: 1019117709Sjulian ps.thread = !ps.thread; 1020117709Sjulian new_message(MT_standout | MT_delayed, 1021223937Sjhb " Displaying threads %s", 1022145073Skeramida ps.thread ? "separately" : "as a count"); 1023145073Skeramida header_text = format_header(uname_field); 1024145073Skeramida reset_display(); 1025117709Sjulian putchar('\r'); 1026117709Sjulian break; 1027146342Skeramida case CMD_wcputog: 1028146342Skeramida ps.wcpu = !ps.wcpu; 1029146342Skeramida new_message(MT_standout | MT_delayed, 1030224204Sjhb " Displaying %s CPU", 1031224204Sjhb ps.wcpu ? "weighted" : "raw"); 1032146342Skeramida header_text = format_header(uname_field); 1033146342Skeramida reset_display(); 1034146342Skeramida putchar('\r'); 1035146342Skeramida break; 1036131402Salfred case CMD_viewtog: 1037131402Salfred if (++displaymode == DISP_MAX) 1038131402Salfred displaymode = 0; 1039131402Salfred header_text = format_header(uname_field); 1040131402Salfred display_header(Yes); 1041131402Salfred d_header = i_header; 1042131402Salfred reset_display(); 1043131402Salfred break; 1044132005Salfred case CMD_viewsys: 1045132005Salfred ps.system = !ps.system; 1046132005Salfred break; 1047168710Sstas case CMD_showargs: 1048168710Sstas fmt_flags ^= FMT_SHOWARGS; 1049168710Sstas break; 105024139Sjoerg#ifdef ORDER 105124139Sjoerg case CMD_order: 105224139Sjoerg new_message(MT_standout, 105324139Sjoerg "Order to sort: "); 105424139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 105524139Sjoerg { 105624139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 105724139Sjoerg { 105824139Sjoerg new_message(MT_standout, 105924139Sjoerg " %s: unrecognized sorting order", tempbuf2); 106024139Sjoerg no_command = Yes; 106124139Sjoerg } 106224139Sjoerg else 106324139Sjoerg { 106424139Sjoerg order_index = i; 106524139Sjoerg } 106624139Sjoerg putchar('\r'); 106724139Sjoerg } 106824139Sjoerg else 106924139Sjoerg { 107024139Sjoerg clear_message(); 107124139Sjoerg } 107224139Sjoerg break; 107324139Sjoerg#endif 1074168799Srafan case CMD_jidtog: 1075168799Srafan ps.jail = !ps.jail; 1076168799Srafan new_message(MT_standout | MT_delayed, 1077169257Srafan " %sisplaying jail ID.", 1078168799Srafan ps.jail ? "D" : "Not d"); 1079168799Srafan header_text = format_header(uname_field); 1080168799Srafan reset_display(); 1081168799Srafan putchar('\r'); 1082168799Srafan break; 1083222530Sjhb case CMD_kidletog: 1084222530Sjhb ps.kidle = !ps.kidle; 1085222530Sjhb new_message(MT_standout | MT_delayed, 1086222530Sjhb " %sisplaying system idle process.", 1087222530Sjhb ps.kidle ? "D" : "Not d"); 1088222530Sjhb putchar('\r'); 1089222530Sjhb break; 1090223936Sjhb case CMD_pcputog: 1091223936Sjhb pcpu_stats = !pcpu_stats; 1092223936Sjhb new_message(MT_standout | MT_delayed, 1093223936Sjhb " Displaying %sCPU statistics.", 1094223936Sjhb pcpu_stats ? "per-" : "global "); 1095224205Sjhb toggle_pcpustats(); 1096223936Sjhb max_topn = display_updatecpus(&statics); 1097223936Sjhb reset_display(); 1098223936Sjhb putchar('\r'); 1099223936Sjhb break; 110024139Sjoerg default: 110124139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 110224139Sjoerg putchar('\r'); 110324139Sjoerg } 110424139Sjoerg } 110524139Sjoerg 110624139Sjoerg /* flush out stuff that may have been written */ 110724139Sjoerg fflush(stdout); 110824139Sjoerg } 110924139Sjoerg } 111024139Sjoerg } 111124139Sjoerg } 111224139Sjoerg 111389757Sdwmalone#ifdef DEBUG 111489757Sdwmalone fclose(debug); 111589757Sdwmalone#endif 111624139Sjoerg quit(0); 111724139Sjoerg /*NOTREACHED*/ 111824139Sjoerg} 111924139Sjoerg 112024139Sjoerg/* 112124139Sjoerg * reset_display() - reset all the display routine pointers so that entire 112224139Sjoerg * screen will get redrawn. 112324139Sjoerg */ 112424139Sjoerg 112524139Sjoergreset_display() 112624139Sjoerg 112724139Sjoerg{ 112824139Sjoerg d_loadave = i_loadave; 112924139Sjoerg d_procstates = i_procstates; 113024139Sjoerg d_cpustates = i_cpustates; 113124139Sjoerg d_memory = i_memory; 113224142Sjoerg d_swap = i_swap; 113324139Sjoerg d_message = i_message; 113424139Sjoerg d_header = i_header; 113524139Sjoerg d_process = i_process; 113624139Sjoerg} 113724139Sjoerg 113824139Sjoerg/* 113924139Sjoerg * signal handlers 114024139Sjoerg */ 114124139Sjoerg 114224139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 114324139Sjoerg 114424139Sjoerg{ 114581187Skris leaveflag = 1; 114624139Sjoerg} 114724139Sjoerg 114824139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 114924139Sjoerg 115024139Sjoergint i; 115124139Sjoerg 115224139Sjoerg{ 115381187Skris tstopflag = 1; 115424139Sjoerg} 115524139Sjoerg 115624139Sjoerg#ifdef SIGWINCH 115724139Sjoergsigret_t winch(i) /* SIGWINCH handler */ 115824139Sjoerg 115924139Sjoergint i; 116024139Sjoerg 116124139Sjoerg{ 116281187Skris winchflag = 1; 116324139Sjoerg} 116424139Sjoerg#endif 116524139Sjoerg 116624139Sjoergvoid quit(status) /* exit under duress */ 116724139Sjoerg 116824139Sjoergint status; 116924139Sjoerg 117024139Sjoerg{ 117124139Sjoerg end_screen(); 117224139Sjoerg exit(status); 117324139Sjoerg /*NOTREACHED*/ 117424139Sjoerg} 1175