xref: /freebsd-src/usr.bin/top/top.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
1d408c8f7SEitan Adler /*-
23be6ef06SEitan Adler  *  Top users/processes display for Unix
33be6ef06SEitan Adler  *
43be6ef06SEitan Adler  *  This program may be freely redistributed,
53be6ef06SEitan Adler  *  but this entire comment MUST remain intact.
63be6ef06SEitan Adler  *
73be6ef06SEitan Adler  *  Copyright (c) 1984, 1989, William LeFebvre, Rice University
83be6ef06SEitan Adler  *  Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University
93be6ef06SEitan Adler  *  Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory
103be6ef06SEitan Adler  *  Copyright (c) 1996, William LeFebvre, Group sys Consulting
113be6ef06SEitan Adler  */
123be6ef06SEitan Adler 
13caee4883SEitan Adler #include <sys/types.h>
143be6ef06SEitan Adler #include <sys/time.h>
158d0d2676SEitan Adler #include <sys/cdefs.h>
168d0d2676SEitan Adler #include <sys/limits.h>
17a0116099SEitan Adler #include <sys/resource.h>
188d0d2676SEitan Adler #include <sys/select.h>
198d0d2676SEitan Adler #include <sys/signal.h>
203be6ef06SEitan Adler 
21c8aa5e52SEitan Adler #include <assert.h>
22eeb147d5SEitan Adler #include <err.h>
233be6ef06SEitan Adler #include <errno.h>
24c388909bSEitan Adler #include <getopt.h>
253be6ef06SEitan Adler #include <jail.h>
26b1de37faSDaichi GOTO #include <locale.h>
278d0d2676SEitan Adler #include <stdbool.h>
288d0d2676SEitan Adler #include <stdio.h>
29caee4883SEitan Adler #include <stdlib.h>
303be6ef06SEitan Adler #include <signal.h>
31caee4883SEitan Adler #include <string.h>
323be6ef06SEitan Adler #include <unistd.h>
333be6ef06SEitan Adler 
343be6ef06SEitan Adler #include "commands.h"
353be6ef06SEitan Adler #include "display.h"		/* interface to display package */
363be6ef06SEitan Adler #include "screen.h"		/* interface to screen package */
373be6ef06SEitan Adler #include "top.h"
383be6ef06SEitan Adler #include "machine.h"
393be6ef06SEitan Adler #include "utils.h"
403be6ef06SEitan Adler #include "username.h"
413be6ef06SEitan Adler 
423be6ef06SEitan Adler /* Size of the stdio buffer given to stdout */
433be6ef06SEitan Adler #define Buffersize	2048
443be6ef06SEitan Adler 
451b7645c6SEitan Adler char copyright[] =
46a5ca08edSEitan Adler     "Copyright (c) 1984 through 1996, William LeFebvre";
47a5ca08edSEitan Adler 
48caee4883SEitan Adler typedef void sigret_t;
49caee4883SEitan Adler 
503be6ef06SEitan Adler /* The buffer that stdio will use */
51a5ca08edSEitan Adler static char stdoutbuf[Buffersize];
523be6ef06SEitan Adler 
533be6ef06SEitan Adler static int fmt_flags = 0;
54a00d703fSJohn Grafton int show_args = false;
550b2f6ed1SEitan Adler int pcpu_stats = false;
563be6ef06SEitan Adler 
573be6ef06SEitan Adler /* signal handling routines */
58666cf873SEitan Adler static sigret_t leave(int);
59666cf873SEitan Adler static sigret_t tstop(int);
60666cf873SEitan Adler static sigret_t top_winch(int);
613be6ef06SEitan Adler 
62fcfaa473SEitan Adler static volatile sig_atomic_t leaveflag;
63fcfaa473SEitan Adler static volatile sig_atomic_t tstopflag;
64fcfaa473SEitan Adler static volatile sig_atomic_t winchflag;
653be6ef06SEitan Adler 
663be6ef06SEitan Adler /* values which need to be accessed by signal handlers */
673be6ef06SEitan Adler static int max_topn;		/* maximum displayable processes */
683be6ef06SEitan Adler 
693be6ef06SEitan Adler /* miscellaneous things */
703be6ef06SEitan Adler struct process_select ps;
71fc36f5a7SEitan Adler pid_t mypid;
723be6ef06SEitan Adler 
733be6ef06SEitan Adler /* pointers to display routines */
74a5ca08edSEitan Adler static void (*d_loadave)(int mpid, double *avenrun) = i_loadave;
75a5ca08edSEitan Adler static void (*d_procstates)(int total, int *brkdn) = i_procstates;
76a5ca08edSEitan Adler static void (*d_cpustates)(int *states) = i_cpustates;
77a5ca08edSEitan Adler static void (*d_memory)(int *stats) = i_memory;
78a5ca08edSEitan Adler static void (*d_arc)(int *stats) = i_arc;
79a5ca08edSEitan Adler static void (*d_carc)(int *stats) = i_carc;
80a5ca08edSEitan Adler static void (*d_swap)(int *stats) = i_swap;
81a5ca08edSEitan Adler static void (*d_message)(void) = i_message;
829f8096e3SEitan Adler static void (*d_header)(const char *text) = i_header;
83a5ca08edSEitan Adler static void (*d_process)(int line, char *thisline) = i_process;
843be6ef06SEitan Adler 
85a5ca08edSEitan Adler static void reset_display(void);
863be6ef06SEitan Adler 
87c388909bSEitan Adler static const struct option longopts[] = {
88c388909bSEitan Adler     { "cpu-display-mode", no_argument, NULL, 'C' }, /* differs from orignal */
89c388909bSEitan Adler     /* D reserved */
90c388909bSEitan Adler     { "thread", no_argument, NULL, 'H' },
91c388909bSEitan Adler     { "idle-procs", no_argument, NULL, 'I' },
92d73bfd43SEitan Adler 	{ "jail", required_argument, NULL, 'J' },
93d73bfd43SEitan Adler 	{ "per-cpu", no_argument, NULL, 'P' },
94c388909bSEitan Adler     { "system-procs", no_argument, NULL, 'S' },
95c388909bSEitan Adler     { "thread-id", no_argument, NULL, 'T' }, /* differs from orignal */
96c388909bSEitan Adler     { "user", required_argument, NULL, 'U' },
97c388909bSEitan Adler     { "all", no_argument, NULL, 'a' },
98c388909bSEitan Adler     { "batch", no_argument, NULL, 'b' },
99c388909bSEitan Adler     /* c reserved */
100c388909bSEitan Adler     { "displays", required_argument, NULL, 'd' },
101c388909bSEitan Adler     { "interactive", no_argument, NULL, 'i' },
102c388909bSEitan Adler     { "jail-id", no_argument, NULL, 'j' },
103c388909bSEitan Adler     { "display-mode", required_argument, NULL, 'm' },
104c388909bSEitan Adler     /* n is identical to batch */
105c388909bSEitan Adler     { "sort-order", required_argument, NULL, 'o' },
106c388909bSEitan Adler     { "pid", required_argument, NULL, 'p' },
107c388909bSEitan Adler     { "quick", no_argument, NULL, 'q' },
108c388909bSEitan Adler     { "delay", required_argument, NULL, 's' },
109c388909bSEitan Adler     { "threads", no_argument, NULL, 't' },
110c388909bSEitan Adler     { "uids", no_argument, NULL, 'u' },
111c388909bSEitan Adler     { "version", no_argument, NULL, 'v' },
112d73bfd43SEitan Adler 	{ "swap", no_argument, NULL, 'w' },
11361ef814fSJustin Hibbits 	{ "system-idle-procs", no_argument, NULL, 'z' },
11461ef814fSJustin Hibbits 	{ NULL, 0, NULL, 0 }
115c388909bSEitan Adler };
116c388909bSEitan Adler 
1173be6ef06SEitan Adler static void
reset_uids(void)118bc875b45SEitan Adler reset_uids(void)
1193be6ef06SEitan Adler {
1203be6ef06SEitan Adler     for (size_t i = 0; i < TOP_MAX_UIDS; ++i)
1213be6ef06SEitan Adler 	ps.uid[i] = -1;
1223be6ef06SEitan Adler }
1233be6ef06SEitan Adler 
1243be6ef06SEitan Adler static int
add_uid(int uid)1253be6ef06SEitan Adler add_uid(int uid)
1263be6ef06SEitan Adler {
1273be6ef06SEitan Adler     size_t i = 0;
1283be6ef06SEitan Adler 
1293be6ef06SEitan Adler     /* Add the uid if there's room */
1303be6ef06SEitan Adler     for (; i < TOP_MAX_UIDS; ++i)
1313be6ef06SEitan Adler     {
1323be6ef06SEitan Adler 	if (ps.uid[i] == -1 || ps.uid[i] == uid)
1333be6ef06SEitan Adler 	{
1343be6ef06SEitan Adler 	    ps.uid[i] = uid;
1353be6ef06SEitan Adler 	    break;
1363be6ef06SEitan Adler 	}
1373be6ef06SEitan Adler     }
1383be6ef06SEitan Adler 
1393be6ef06SEitan Adler     return (i == TOP_MAX_UIDS);
1403be6ef06SEitan Adler }
1413be6ef06SEitan Adler 
1423be6ef06SEitan Adler static void
rem_uid(int uid)1433be6ef06SEitan Adler rem_uid(int uid)
1443be6ef06SEitan Adler {
1453be6ef06SEitan Adler     size_t i = 0;
1463be6ef06SEitan Adler     size_t where = TOP_MAX_UIDS;
1473be6ef06SEitan Adler 
1483be6ef06SEitan Adler     /* Look for the user to remove - no problem if it's not there */
1493be6ef06SEitan Adler     for (; i < TOP_MAX_UIDS; ++i)
1503be6ef06SEitan Adler     {
1513be6ef06SEitan Adler 	if (ps.uid[i] == -1)
1523be6ef06SEitan Adler 	    break;
1533be6ef06SEitan Adler 	if (ps.uid[i] == uid)
1543be6ef06SEitan Adler 	    where = i;
1553be6ef06SEitan Adler     }
1563be6ef06SEitan Adler 
1573be6ef06SEitan Adler     /* Make sure we don't leave a hole in the middle */
1583be6ef06SEitan Adler     if (where != TOP_MAX_UIDS)
1593be6ef06SEitan Adler     {
1603be6ef06SEitan Adler 	ps.uid[where] = ps.uid[i-1];
1613be6ef06SEitan Adler 	ps.uid[i-1] = -1;
1623be6ef06SEitan Adler     }
1633be6ef06SEitan Adler }
1643be6ef06SEitan Adler 
1653be6ef06SEitan Adler static int
handle_user(char * buf,size_t buflen)1663be6ef06SEitan Adler handle_user(char *buf, size_t buflen)
1673be6ef06SEitan Adler {
1683be6ef06SEitan Adler     int rc = 0;
1693be6ef06SEitan Adler     int uid = -1;
1703be6ef06SEitan Adler     char *buf2 = buf;
1713be6ef06SEitan Adler 
1723be6ef06SEitan Adler     new_message(MT_standout, "Username to show (+ for all): ");
1730b2f6ed1SEitan Adler     if (readline(buf, buflen, false) <= 0)
1743be6ef06SEitan Adler     {
1753be6ef06SEitan Adler 	clear_message();
176d408c8f7SEitan Adler 	return (rc);
1773be6ef06SEitan Adler     }
1783be6ef06SEitan Adler 
1793be6ef06SEitan Adler     if (buf[0] == '+' || buf[0] == '-')
1803be6ef06SEitan Adler     {
1813be6ef06SEitan Adler 	if (buf[1] == '\0')
1823be6ef06SEitan Adler 	{
1833be6ef06SEitan Adler 	    reset_uids();
1843be6ef06SEitan Adler 	    goto end;
1853be6ef06SEitan Adler 	}
1863be6ef06SEitan Adler 	else
1873be6ef06SEitan Adler 	    ++buf2;
1883be6ef06SEitan Adler     }
1893be6ef06SEitan Adler 
1903be6ef06SEitan Adler     if ((uid = userid(buf2)) == -1)
1913be6ef06SEitan Adler     {
1923be6ef06SEitan Adler 	new_message(MT_standout, " %s: unknown user", buf2);
1933be6ef06SEitan Adler 	rc = 1;
1943be6ef06SEitan Adler 	goto end;
1953be6ef06SEitan Adler     }
1963be6ef06SEitan Adler 
1973be6ef06SEitan Adler     if (buf2 == buf)
1983be6ef06SEitan Adler     {
1993be6ef06SEitan Adler 	reset_uids();
2003be6ef06SEitan Adler 	ps.uid[0] = uid;
2013be6ef06SEitan Adler 	goto end;
2023be6ef06SEitan Adler     }
2033be6ef06SEitan Adler 
2043be6ef06SEitan Adler     if (buf[0] == '+')
2053be6ef06SEitan Adler     {
2063be6ef06SEitan Adler 	if (add_uid(uid))
2073be6ef06SEitan Adler 	{
2083be6ef06SEitan Adler 	    new_message(MT_standout, " too many users, reset with '+'");
2093be6ef06SEitan Adler 	    rc = 1;
2103be6ef06SEitan Adler 	    goto end;
2113be6ef06SEitan Adler 	}
2123be6ef06SEitan Adler     }
2133be6ef06SEitan Adler     else
2143be6ef06SEitan Adler 	rem_uid(uid);
2153be6ef06SEitan Adler 
2163be6ef06SEitan Adler end:
2173be6ef06SEitan Adler     putchar('\r');
218d408c8f7SEitan Adler     return (rc);
2193be6ef06SEitan Adler }
2203be6ef06SEitan Adler 
2213be6ef06SEitan Adler int
main(int argc,const char * argv[])222d0f687d3SDimitry Andric main(int argc, const char *argv[])
2233be6ef06SEitan Adler {
22498c299e0SEitan Adler     int i;
22598c299e0SEitan Adler     int active_procs;
2263be6ef06SEitan Adler 
2273be6ef06SEitan Adler     struct system_info system_info;
2283be6ef06SEitan Adler     struct statics statics;
2291b7645c6SEitan Adler     void * processes;
2303be6ef06SEitan Adler 
2313be6ef06SEitan Adler     static char tempbuf1[50];
2323be6ef06SEitan Adler     static char tempbuf2[50];
2336bb0d5cfSEitan Adler 	sigset_t old_sigmask, new_sigmask;
234668af25dSEitan Adler     int topn = Infinity;
235a6f721ecSDimitry Andric     struct timeval delay = { 2, 0 };
2363be6ef06SEitan Adler     int displays = 0;		/* indicates unspecified */
2373be6ef06SEitan Adler     int sel_ret = 0;
2383be6ef06SEitan Adler     time_t curr_time;
23901a55f00SEitan Adler     char *(*get_userid)(int) = username;
2409f8096e3SEitan Adler     const char *uname_field = "USERNAME";
2419f8096e3SEitan Adler     const char *header_text;
2423be6ef06SEitan Adler     char *env_top;
243eae589f1SEitan Adler     const char **preset_argv;
2443be6ef06SEitan Adler     int  preset_argc = 0;
24559c50d82SEitan Adler     const char **av = NULL;
24659c50d82SEitan Adler     int  ac = -1;
2470b2f6ed1SEitan Adler     bool do_unames = true;
2480b2f6ed1SEitan Adler     char interactive = 2;
2493be6ef06SEitan Adler     char warnings = 0;
2500b2f6ed1SEitan Adler     char topn_specified = false;
2513be6ef06SEitan Adler     char ch;
2523be6ef06SEitan Adler     char no_command = 1;
2533be6ef06SEitan Adler     struct timeval timeout;
2543be6ef06SEitan Adler     char *order_name = NULL;
2553be6ef06SEitan Adler     int order_index = 0;
2563be6ef06SEitan Adler     fd_set readfds;
257eeb147d5SEitan Adler 	char *nptr;
2583be6ef06SEitan Adler 
2593be6ef06SEitan Adler     /* set the buffer for stdout */
2603be6ef06SEitan Adler #ifdef DEBUG
2613be6ef06SEitan Adler     extern FILE *debug;
2623be6ef06SEitan Adler     debug = fopen("debug.run", "w");
2633be6ef06SEitan Adler     setbuffer(stdout, NULL, 0);
2643be6ef06SEitan Adler #else
2653be6ef06SEitan Adler     setbuffer(stdout, stdoutbuf, Buffersize);
2663be6ef06SEitan Adler #endif
2673be6ef06SEitan Adler 
268b1de37faSDaichi GOTO     if (setlocale(LC_ALL, "") == NULL) {
269b1de37faSDaichi GOTO         fprintf(stderr, "invalid locale.\n");
270b1de37faSDaichi GOTO 	exit(1);
271b1de37faSDaichi GOTO     }
272b1de37faSDaichi GOTO 
273fc36f5a7SEitan Adler     mypid = getpid();
274fc36f5a7SEitan Adler 
275fc36f5a7SEitan Adler     /* get our name */
2763be6ef06SEitan Adler     /* initialize some selection options */
2770b2f6ed1SEitan Adler     ps.idle    = true;
27857ad79afSEitan Adler     ps.self    = true;
2790b2f6ed1SEitan Adler     ps.system  = false;
2803be6ef06SEitan Adler     reset_uids();
2810b2f6ed1SEitan Adler     ps.thread  = false;
2823be6ef06SEitan Adler     ps.wcpu    = 1;
2833be6ef06SEitan Adler     ps.jid     = -1;
2840b2f6ed1SEitan Adler     ps.jail    = false;
2850b2f6ed1SEitan Adler     ps.swap    = false;
2860b2f6ed1SEitan Adler     ps.kidle   = true;
28751b29cb7SRoman Bogorodskiy     ps.pid     = -1;
2883be6ef06SEitan Adler     ps.command = NULL;
289fc36f5a7SEitan Adler     ps.thread_id = false;
2903be6ef06SEitan Adler 
2913be6ef06SEitan Adler     /* get preset options from the environment */
2923be6ef06SEitan Adler     if ((env_top = getenv("TOP")) != NULL)
2933be6ef06SEitan Adler     {
2943be6ef06SEitan Adler 	av = preset_argv = argparse(env_top, &preset_argc);
2953be6ef06SEitan Adler 	ac = preset_argc;
2963be6ef06SEitan Adler 
2973be6ef06SEitan Adler 	/* set the dummy argument to an explanatory message, in case
2983be6ef06SEitan Adler 	   getopt encounters a bad argument */
2993be6ef06SEitan Adler 	preset_argv[0] = "while processing environment";
3003be6ef06SEitan Adler     }
3013be6ef06SEitan Adler 
3023be6ef06SEitan Adler     /* process options */
3033be6ef06SEitan Adler     do {
3043be6ef06SEitan Adler 	/* if we're done doing the presets, then process the real arguments */
3053be6ef06SEitan Adler 	if (preset_argc == 0)
3063be6ef06SEitan Adler 	{
3073be6ef06SEitan Adler 	    ac = argc;
3083be6ef06SEitan Adler 	    av = argv;
3093be6ef06SEitan Adler 
3103be6ef06SEitan Adler 	    /* this should keep getopt happy... */
3113be6ef06SEitan Adler 	    optind = 1;
3123be6ef06SEitan Adler 	}
3133be6ef06SEitan Adler 
314d0f687d3SDimitry Andric 	while ((i = getopt_long(ac, __DECONST(char * const *, av), "CSIHPabijJ:nquvzs:d:U:m:o:p:Ttw", longopts, NULL)) != EOF)
3153be6ef06SEitan Adler 	{
3163be6ef06SEitan Adler 	    switch(i)
3173be6ef06SEitan Adler 	    {
3183be6ef06SEitan Adler 	      case 'v':			/* show version number */
31917be5f23SEitan Adler 			  errx(0, "version FreeBSD");
3203be6ef06SEitan Adler 			  break;
3213be6ef06SEitan Adler 
3223be6ef06SEitan Adler 	      case 'u':			/* toggle uid/username display */
3233be6ef06SEitan Adler 		do_unames = !do_unames;
3243be6ef06SEitan Adler 		break;
3253be6ef06SEitan Adler 
3263be6ef06SEitan Adler 	      case 'U':			/* display only username's processes */
3273be6ef06SEitan Adler 		if ((ps.uid[0] = userid(optarg)) == -1)
3283be6ef06SEitan Adler 		{
32917be5f23SEitan Adler 		    errx(1, "%s: unknown user\n", optarg);
3303be6ef06SEitan Adler 		}
3313be6ef06SEitan Adler 		break;
3323be6ef06SEitan Adler 
3333be6ef06SEitan Adler 	      case 'S':			/* show system processes */
33451b29cb7SRoman Bogorodskiy 		ps.system = true;
3353be6ef06SEitan Adler 		break;
3363be6ef06SEitan Adler 
3373be6ef06SEitan Adler 	      case 'I':                   /* show idle processes */
3383be6ef06SEitan Adler 		ps.idle = !ps.idle;
3393be6ef06SEitan Adler 		break;
3403be6ef06SEitan Adler 
3413be6ef06SEitan Adler 	      case 'i':			/* go interactive regardless */
3420b2f6ed1SEitan Adler 		interactive = 1;
3433be6ef06SEitan Adler 		break;
3443be6ef06SEitan Adler 
3453be6ef06SEitan Adler 	      case 'n':			/* batch, or non-interactive */
3463be6ef06SEitan Adler 	      case 'b':
3470b2f6ed1SEitan Adler 		interactive = 0;
3483be6ef06SEitan Adler 		break;
3493be6ef06SEitan Adler 
3503be6ef06SEitan Adler 	      case 'a':
3513be6ef06SEitan Adler 		fmt_flags ^= FMT_SHOWARGS;
3523be6ef06SEitan Adler 		break;
3533be6ef06SEitan Adler 
3543be6ef06SEitan Adler 	      case 'd':			/* number of displays to show */
3553be6ef06SEitan Adler 		if ((i = atoiwi(optarg)) == Invalid || i == 0)
3563be6ef06SEitan Adler 		{
35717be5f23SEitan Adler 		    warnx("warning: display count should be positive -- option ignored");
3583be6ef06SEitan Adler 		    warnings++;
3593be6ef06SEitan Adler 		}
3603be6ef06SEitan Adler 		else
3613be6ef06SEitan Adler 		{
3623be6ef06SEitan Adler 		    displays = i;
3633be6ef06SEitan Adler 		}
3643be6ef06SEitan Adler 		break;
36551b29cb7SRoman Bogorodskiy 	      case 'p': {
36651b29cb7SRoman Bogorodskiy 		unsigned long long num;
36751b29cb7SRoman Bogorodskiy 		const char *errstr;
36851b29cb7SRoman Bogorodskiy 
36951b29cb7SRoman Bogorodskiy 		num = strtonum(optarg, 0, INT_MAX, &errstr);
37051b29cb7SRoman Bogorodskiy 		if (errstr != NULL || !find_pid(num)) {
37151b29cb7SRoman Bogorodskiy 			fprintf(stderr, "%s: unknown pid\n", optarg);
37251b29cb7SRoman Bogorodskiy 			exit(1);
37351b29cb7SRoman Bogorodskiy 		}
37451b29cb7SRoman Bogorodskiy 		ps.pid = (pid_t)num;
37551b29cb7SRoman Bogorodskiy 		ps.system = true;
37651b29cb7SRoman Bogorodskiy 		break;
37751b29cb7SRoman Bogorodskiy 	      }
3783be6ef06SEitan Adler 
3793be6ef06SEitan Adler 	      case 's':
380a6f721ecSDimitry Andric 	      {
381a6f721ecSDimitry Andric 		  double delay_d = strtod(optarg, &nptr);
382a6f721ecSDimitry Andric 		  if (nptr == optarg)
383a6f721ecSDimitry Andric 		  {
384eeb147d5SEitan Adler 		      warnx("warning: invalid delay");
385eeb147d5SEitan Adler 		      warnings++;
386eeb147d5SEitan Adler 		  }
387a6f721ecSDimitry Andric 		  else if (delay_d <= 0)
388a6f721ecSDimitry Andric 		  {
38917be5f23SEitan Adler 		      warnx("warning: seconds delay should be positive -- using default");
3903be6ef06SEitan Adler 		      warnings++;
3913be6ef06SEitan Adler 		  }
392a6f721ecSDimitry Andric 		  else
393a6f721ecSDimitry Andric 		  {
394a6f721ecSDimitry Andric 		      delay.tv_sec = delay_d;
395a6f721ecSDimitry Andric 		      delay.tv_usec = (delay_d - delay.tv_sec) * 1e6;
396a6f721ecSDimitry Andric 		  }
3973be6ef06SEitan Adler 		  break;
398a6f721ecSDimitry Andric 	      }
3993be6ef06SEitan Adler 
4003be6ef06SEitan Adler 	      case 'q':		/* be quick about it */
401a0116099SEitan Adler 			errno = 0;
402a0116099SEitan Adler 			i = setpriority(PRIO_PROCESS, 0, PRIO_MIN);
403a0116099SEitan Adler 			if (i == -1 && errno != 0) {
40417be5f23SEitan Adler 				warnx("warning: `-q' option failed (%m)");
4053be6ef06SEitan Adler 				warnings++;
4063be6ef06SEitan Adler 			}
4073be6ef06SEitan Adler 		break;
4083be6ef06SEitan Adler 
4093be6ef06SEitan Adler 	      case 'm':		/* select display mode */
4103be6ef06SEitan Adler 		if (strcmp(optarg, "io") == 0) {
4113be6ef06SEitan Adler 			displaymode = DISP_IO;
4123be6ef06SEitan Adler 		} else if (strcmp(optarg, "cpu") == 0) {
4133be6ef06SEitan Adler 			displaymode = DISP_CPU;
4143be6ef06SEitan Adler 		} else {
41517be5f23SEitan Adler 			errx(1, "warning: `-m' option can only take args 'io' or 'cpu'");
4163be6ef06SEitan Adler 		}
4173be6ef06SEitan Adler 		break;
4183be6ef06SEitan Adler 
4193be6ef06SEitan Adler 	      case 'o':		/* select sort order */
4203be6ef06SEitan Adler 		order_name = optarg;
4213be6ef06SEitan Adler 		break;
4223be6ef06SEitan Adler 
4233be6ef06SEitan Adler 	      case 't':
424fc36f5a7SEitan Adler 		ps.self = !ps.self;
4253be6ef06SEitan Adler 		break;
4263be6ef06SEitan Adler 
4273be6ef06SEitan Adler 	      case 'C':
4283be6ef06SEitan Adler 		ps.wcpu = !ps.wcpu;
4293be6ef06SEitan Adler 		break;
4303be6ef06SEitan Adler 
4313be6ef06SEitan Adler 	      case 'H':
4323be6ef06SEitan Adler 		ps.thread = !ps.thread;
4333be6ef06SEitan Adler 		break;
4343be6ef06SEitan Adler 
435fc36f5a7SEitan Adler 	      case 'T':
436fc36f5a7SEitan Adler 		ps.thread_id = !ps.thread_id;
437fc36f5a7SEitan Adler 		break;
438fc36f5a7SEitan Adler 
4393be6ef06SEitan Adler 	      case 'j':
4403be6ef06SEitan Adler 		ps.jail = !ps.jail;
4413be6ef06SEitan Adler 		break;
4423be6ef06SEitan Adler 
4433be6ef06SEitan Adler 	      case 'J':			/* display only jail's processes */
4443be6ef06SEitan Adler 		if ((ps.jid = jail_getid(optarg)) == -1)
4453be6ef06SEitan Adler 		{
4463be6ef06SEitan Adler 		    fprintf(stderr, "%s: unknown jail\n", optarg);
4473be6ef06SEitan Adler 		    exit(1);
4483be6ef06SEitan Adler 		}
4493be6ef06SEitan Adler 		ps.jail = 1;
4503be6ef06SEitan Adler 		break;
4513be6ef06SEitan Adler 
4523be6ef06SEitan Adler 	      case 'P':
4533be6ef06SEitan Adler 		pcpu_stats = !pcpu_stats;
4543be6ef06SEitan Adler 		break;
4553be6ef06SEitan Adler 
4563be6ef06SEitan Adler 	      case 'w':
4573be6ef06SEitan Adler 		ps.swap = 1;
4583be6ef06SEitan Adler 		break;
4593be6ef06SEitan Adler 
4603be6ef06SEitan Adler 	      case 'z':
4613be6ef06SEitan Adler 		ps.kidle = !ps.kidle;
4623be6ef06SEitan Adler 		break;
4633be6ef06SEitan Adler 
4643be6ef06SEitan Adler 	      default:
46517be5f23SEitan Adler 		errx(1,
46682d0f865SMateusz Piotrowski "[-abCHIijnPqStuvwz] [-d count] [-J jail] [-m cpu | io] [-o field]\n"
46782d0f865SMateusz Piotrowski "     [-p pid] [-s time] [-U username] [number]");
4683be6ef06SEitan Adler 	    }
4693be6ef06SEitan Adler 	}
4703be6ef06SEitan Adler 
4713be6ef06SEitan Adler 	/* get count of top processes to display (if any) */
4723be6ef06SEitan Adler 	if (optind < ac)
4733be6ef06SEitan Adler 	{
4743be6ef06SEitan Adler 	    if ((topn = atoiwi(av[optind])) == Invalid)
4753be6ef06SEitan Adler 	    {
47617be5f23SEitan Adler 			warnx("warning: process display count should be non-negative -- using default");
4773be6ef06SEitan Adler 			warnings++;
4783be6ef06SEitan Adler 	    }
4793be6ef06SEitan Adler             else
4803be6ef06SEitan Adler 	    {
4810b2f6ed1SEitan Adler 		topn_specified = true;
4823be6ef06SEitan Adler 	    }
4833be6ef06SEitan Adler 	}
4843be6ef06SEitan Adler 
4853be6ef06SEitan Adler 	/* tricky:  remember old value of preset_argc & set preset_argc = 0 */
4863be6ef06SEitan Adler 	i = preset_argc;
4873be6ef06SEitan Adler 	preset_argc = 0;
4883be6ef06SEitan Adler 
4893be6ef06SEitan Adler     /* repeat only if we really did the preset arguments */
4903be6ef06SEitan Adler     } while (i != 0);
4913be6ef06SEitan Adler 
4923be6ef06SEitan Adler     /* set constants for username/uid display correctly */
4933be6ef06SEitan Adler     if (!do_unames)
4943be6ef06SEitan Adler     {
4953be6ef06SEitan Adler 	uname_field = "   UID  ";
4963be6ef06SEitan Adler 	get_userid = itoa7;
4973be6ef06SEitan Adler     }
4983be6ef06SEitan Adler 
4993be6ef06SEitan Adler     /* initialize the kernel memory interface */
5004b9ca404SEitan Adler     if (machine_init(&statics) == -1)
5013be6ef06SEitan Adler     {
5023be6ef06SEitan Adler 	exit(1);
5033be6ef06SEitan Adler     }
5043be6ef06SEitan Adler 
5053be6ef06SEitan Adler     /* determine sorting order index, if necessary */
5063be6ef06SEitan Adler     if (order_name != NULL)
5073be6ef06SEitan Adler     {
5083be6ef06SEitan Adler 	if ((order_index = string_index(order_name, statics.order_names)) == -1)
5093be6ef06SEitan Adler 	{
510d408c8f7SEitan Adler 	    const char * const *pp;
5113be6ef06SEitan Adler 
51217be5f23SEitan Adler 	    warnx("'%s' is not a recognized sorting order.", order_name);
5133be6ef06SEitan Adler 	    fprintf(stderr, "\tTry one of these:");
5143be6ef06SEitan Adler 	    pp = statics.order_names;
5153be6ef06SEitan Adler 	    while (*pp != NULL)
5163be6ef06SEitan Adler 	    {
5173be6ef06SEitan Adler 		fprintf(stderr, " %s", *pp++);
5183be6ef06SEitan Adler 	    }
5193be6ef06SEitan Adler 	    fputc('\n', stderr);
5203be6ef06SEitan Adler 	    exit(1);
5213be6ef06SEitan Adler 	}
5223be6ef06SEitan Adler     }
5233be6ef06SEitan Adler 
5243be6ef06SEitan Adler     /* initialize termcap */
5253be6ef06SEitan Adler     init_termcap(interactive);
5263be6ef06SEitan Adler 
5273be6ef06SEitan Adler     /* get the string to use for the process area header */
5283be6ef06SEitan Adler     header_text = format_header(uname_field);
5293be6ef06SEitan Adler 
5303be6ef06SEitan Adler     /* initialize display interface */
5313be6ef06SEitan Adler     if ((max_topn = display_init(&statics)) == -1)
5323be6ef06SEitan Adler     {
53317be5f23SEitan Adler 		errx(4, "can't allocate sufficient memory");
5343be6ef06SEitan Adler     }
5353be6ef06SEitan Adler 
5363be6ef06SEitan Adler     /* print warning if user requested more processes than we can display */
5373be6ef06SEitan Adler     if (topn > max_topn)
5383be6ef06SEitan Adler     {
53917be5f23SEitan Adler 		warnx("warning: this terminal can only display %d processes.", max_topn);
5403be6ef06SEitan Adler 		warnings++;
5413be6ef06SEitan Adler     }
5423be6ef06SEitan Adler 
5433be6ef06SEitan Adler     /* adjust for topn == Infinity */
5443be6ef06SEitan Adler     if (topn == Infinity)
5453be6ef06SEitan Adler     {
5463be6ef06SEitan Adler 	/*
5473be6ef06SEitan Adler 	 *  For smart terminals, infinity really means everything that can
5483be6ef06SEitan Adler 	 *  be displayed, or Largest.
5493be6ef06SEitan Adler 	 *  On dumb terminals, infinity means every process in the system!
5503be6ef06SEitan Adler 	 *  We only really want to do that if it was explicitly specified.
5513be6ef06SEitan Adler 	 *  This is always the case when "Default_TOPN != Infinity".  But if
5523be6ef06SEitan Adler 	 *  topn wasn't explicitly specified and we are on a dumb terminal
5533be6ef06SEitan Adler 	 *  and the default is Infinity, then (and only then) we use
5543be6ef06SEitan Adler 	 *  "Nominal_TOPN" instead.
5553be6ef06SEitan Adler 	 */
5563be6ef06SEitan Adler 	topn = smart_terminal ? Largest :
5573be6ef06SEitan Adler 		    (topn_specified ? Largest : Nominal_TOPN);
5583be6ef06SEitan Adler     }
5593be6ef06SEitan Adler 
5603be6ef06SEitan Adler     /* set header display accordingly */
5613be6ef06SEitan Adler     display_header(topn > 0);
5623be6ef06SEitan Adler 
5633be6ef06SEitan Adler     /* determine interactive state */
5640b2f6ed1SEitan Adler     if (interactive == 2)
5653be6ef06SEitan Adler     {
5663be6ef06SEitan Adler 	interactive = smart_terminal;
5673be6ef06SEitan Adler     }
5683be6ef06SEitan Adler 
5693be6ef06SEitan Adler     /* if # of displays not specified, fill it in */
5703be6ef06SEitan Adler     if (displays == 0)
5713be6ef06SEitan Adler     {
5723be6ef06SEitan Adler 	displays = smart_terminal ? Infinity : 1;
5733be6ef06SEitan Adler     }
5743be6ef06SEitan Adler 
5753be6ef06SEitan Adler     /* hold interrupt signals while setting up the screen and the handlers */
5766bb0d5cfSEitan Adler 
5776bb0d5cfSEitan Adler 	sigemptyset(&new_sigmask);
5786bb0d5cfSEitan Adler 	sigaddset(&new_sigmask, SIGINT);
5796bb0d5cfSEitan Adler 	sigaddset(&new_sigmask, SIGQUIT);
5806bb0d5cfSEitan Adler 	sigaddset(&new_sigmask, SIGTSTP);
5816bb0d5cfSEitan Adler 	sigprocmask(SIG_BLOCK, &new_sigmask, &old_sigmask);
5823be6ef06SEitan Adler     init_screen();
583666cf873SEitan Adler     signal(SIGINT, leave);
584666cf873SEitan Adler     signal(SIGQUIT, leave);
585666cf873SEitan Adler     signal(SIGTSTP, tstop);
586666cf873SEitan Adler     signal(SIGWINCH, top_winch);
5876bb0d5cfSEitan Adler     sigprocmask(SIG_SETMASK, &old_sigmask, NULL);
5883be6ef06SEitan Adler     if (warnings)
5893be6ef06SEitan Adler     {
5903be6ef06SEitan Adler 	fputs("....", stderr);
591b4aadfd2SEitan Adler 	fflush(stderr);
592b4aadfd2SEitan Adler 	sleep(3 * warnings);
5933be6ef06SEitan Adler 	fputc('\n', stderr);
5943be6ef06SEitan Adler     }
5953be6ef06SEitan Adler 
5963be6ef06SEitan Adler restart:
5973be6ef06SEitan Adler 
5983be6ef06SEitan Adler     /*
5993be6ef06SEitan Adler      *  main loop -- repeat while display count is positive or while it
6003be6ef06SEitan Adler      *		indicates infinity (by being -1)
6013be6ef06SEitan Adler      */
6023be6ef06SEitan Adler 
6033be6ef06SEitan Adler     while ((displays == -1) || (displays-- > 0))
6043be6ef06SEitan Adler     {
6051d6a4ba3SEitan Adler 	int (*compare)(const void * const, const void * const);
6063be6ef06SEitan Adler 
6073be6ef06SEitan Adler 
6083be6ef06SEitan Adler 	/* get the current stats */
6093be6ef06SEitan Adler 	get_system_info(&system_info);
6103be6ef06SEitan Adler 
6113be6ef06SEitan Adler 	compare = compares[order_index];
6123be6ef06SEitan Adler 
6133be6ef06SEitan Adler 	/* get the current set of processes */
6143be6ef06SEitan Adler 	processes =
6153be6ef06SEitan Adler 		get_process_info(&system_info, &ps, compare);
6163be6ef06SEitan Adler 
6173be6ef06SEitan Adler 	/* display the load averages */
6183be6ef06SEitan Adler 	(*d_loadave)(system_info.last_pid,
6193be6ef06SEitan Adler 		     system_info.load_avg);
6203be6ef06SEitan Adler 
621fc8ae86aSPhilip Paeps 	/* display the battery info (if any) */
622fc8ae86aSPhilip Paeps 	i_battery(statics.nbatteries, system_info.battery);
623fc8ae86aSPhilip Paeps 
6243be6ef06SEitan Adler 	/* display the current time */
6253be6ef06SEitan Adler 	/* this method of getting the time SHOULD be fairly portable */
6263be6ef06SEitan Adler 	time(&curr_time);
6273be6ef06SEitan Adler 	i_uptime(&system_info.boottime, &curr_time);
6283be6ef06SEitan Adler 	i_timeofday(&curr_time);
6293be6ef06SEitan Adler 
6303be6ef06SEitan Adler 	/* display process state breakdown */
6313be6ef06SEitan Adler 	(*d_procstates)(system_info.p_total,
6323be6ef06SEitan Adler 			system_info.procstates);
6333be6ef06SEitan Adler 	(*d_cpustates)(system_info.cpustates);
6343be6ef06SEitan Adler 
6353be6ef06SEitan Adler 	/* display memory stats */
6363be6ef06SEitan Adler 	(*d_memory)(system_info.memory);
6373be6ef06SEitan Adler 	(*d_arc)(system_info.arc);
6383be6ef06SEitan Adler 	(*d_carc)(system_info.carc);
6393be6ef06SEitan Adler 
6403be6ef06SEitan Adler 	/* display swap stats */
6413be6ef06SEitan Adler 	(*d_swap)(system_info.swap);
6423be6ef06SEitan Adler 
6433be6ef06SEitan Adler 	/* handle message area */
6443be6ef06SEitan Adler 	(*d_message)();
6453be6ef06SEitan Adler 
6463be6ef06SEitan Adler 	/* update the header area */
6473be6ef06SEitan Adler 	(*d_header)(header_text);
6483be6ef06SEitan Adler 
6493be6ef06SEitan Adler 	if (topn > 0)
6503be6ef06SEitan Adler 	{
6513be6ef06SEitan Adler 	    /* determine number of processes to actually display */
6523be6ef06SEitan Adler 	    /* this number will be the smallest of:  active processes,
653*2fc08940SGordon Bergling 	       number user requested, number current screen accommodates */
6545ef89dbfSEitan Adler 	    active_procs = system_info.p_pactive;
6553be6ef06SEitan Adler 	    if (active_procs > topn)
6563be6ef06SEitan Adler 	    {
6573be6ef06SEitan Adler 		active_procs = topn;
6583be6ef06SEitan Adler 	    }
6593be6ef06SEitan Adler 	    if (active_procs > max_topn)
6603be6ef06SEitan Adler 	    {
6613be6ef06SEitan Adler 		active_procs = max_topn;
6623be6ef06SEitan Adler 	    }
6633be6ef06SEitan Adler 
6643be6ef06SEitan Adler 	    /* now show the top "n" processes. */
6653be6ef06SEitan Adler 	    for (i = 0; i < active_procs; i++)
6663be6ef06SEitan Adler 	    {
6673be6ef06SEitan Adler 		(*d_process)(i, format_next_process(processes, get_userid,
6683be6ef06SEitan Adler 			     fmt_flags));
6693be6ef06SEitan Adler 	    }
6703be6ef06SEitan Adler 	}
6713be6ef06SEitan Adler 	else
6723be6ef06SEitan Adler 	{
6733be6ef06SEitan Adler 	    i = 0;
6743be6ef06SEitan Adler 	}
6753be6ef06SEitan Adler 
6763be6ef06SEitan Adler 	/* do end-screen processing */
6773be6ef06SEitan Adler 	u_endscreen(i);
6783be6ef06SEitan Adler 
6793be6ef06SEitan Adler 	/* now, flush the output buffer */
6803be6ef06SEitan Adler 	if (fflush(stdout) != 0)
6813be6ef06SEitan Adler 	{
6823be6ef06SEitan Adler 	    new_message(MT_standout, " Write error on stdout");
6833be6ef06SEitan Adler 	    putchar('\r');
6843be6ef06SEitan Adler 	    quit(1);
6853be6ef06SEitan Adler 	}
6863be6ef06SEitan Adler 
6873be6ef06SEitan Adler 	/* only do the rest if we have more displays to show */
6883be6ef06SEitan Adler 	if (displays)
6893be6ef06SEitan Adler 	{
6903be6ef06SEitan Adler 	    /* switch out for new display on smart terminals */
6913be6ef06SEitan Adler 	    if (smart_terminal)
6923be6ef06SEitan Adler 	    {
6933be6ef06SEitan Adler 		if (overstrike)
6943be6ef06SEitan Adler 		{
6953be6ef06SEitan Adler 		    reset_display();
6963be6ef06SEitan Adler 		}
6973be6ef06SEitan Adler 		else
6983be6ef06SEitan Adler 		{
6993be6ef06SEitan Adler 		    d_loadave = u_loadave;
7003be6ef06SEitan Adler 		    d_procstates = u_procstates;
7013be6ef06SEitan Adler 		    d_cpustates = u_cpustates;
7023be6ef06SEitan Adler 		    d_memory = u_memory;
7033be6ef06SEitan Adler 		    d_arc = u_arc;
7043be6ef06SEitan Adler 		    d_carc = u_carc;
7053be6ef06SEitan Adler 		    d_swap = u_swap;
7063be6ef06SEitan Adler 		    d_message = u_message;
7073be6ef06SEitan Adler 		    d_header = u_header;
7083be6ef06SEitan Adler 		    d_process = u_process;
7093be6ef06SEitan Adler 		}
7103be6ef06SEitan Adler 	    }
7113be6ef06SEitan Adler 
7120b2f6ed1SEitan Adler 	    no_command = true;
7133be6ef06SEitan Adler 	    if (!interactive)
7143be6ef06SEitan Adler 	    {
715a6f721ecSDimitry Andric 		timeout = delay;
716a6f721ecSDimitry Andric 		select(0, NULL, NULL, NULL, &timeout);
7173be6ef06SEitan Adler 		if (leaveflag) {
7183be6ef06SEitan Adler 		    end_screen();
7193be6ef06SEitan Adler 		    exit(0);
7203be6ef06SEitan Adler 		}
7213be6ef06SEitan Adler 	    }
7223be6ef06SEitan Adler 	    else while (no_command)
7233be6ef06SEitan Adler 	    {
7243be6ef06SEitan Adler 		/* assume valid command unless told otherwise */
7250b2f6ed1SEitan Adler 		no_command = false;
7263be6ef06SEitan Adler 
7273be6ef06SEitan Adler 		/* set up arguments for select with timeout */
7283be6ef06SEitan Adler 		FD_ZERO(&readfds);
7293be6ef06SEitan Adler 		FD_SET(0, &readfds);		/* for standard input */
730a6f721ecSDimitry Andric 		timeout = delay;
7313be6ef06SEitan Adler 
7323be6ef06SEitan Adler 		if (leaveflag) {
7333be6ef06SEitan Adler 		    end_screen();
7343be6ef06SEitan Adler 		    exit(0);
7353be6ef06SEitan Adler 		}
7363be6ef06SEitan Adler 
7373be6ef06SEitan Adler 		if (tstopflag) {
7383be6ef06SEitan Adler 		    /* move to the lower left */
7393be6ef06SEitan Adler 		    end_screen();
7403be6ef06SEitan Adler 		    fflush(stdout);
7413be6ef06SEitan Adler 
7423be6ef06SEitan Adler 		    /* default the signal handler action */
7435ef89dbfSEitan Adler 		    signal(SIGTSTP, SIG_DFL);
7443be6ef06SEitan Adler 
7453be6ef06SEitan Adler 		    /* unblock the signal and send ourselves one */
7465ef89dbfSEitan Adler 		    sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
7475ef89dbfSEitan Adler 		    kill(0, SIGTSTP);
7483be6ef06SEitan Adler 
7493be6ef06SEitan Adler 		    /* reset the signal handler */
7505ef89dbfSEitan Adler 		    signal(SIGTSTP, tstop);
7513be6ef06SEitan Adler 
7523be6ef06SEitan Adler 		    /* reinit screen */
7533be6ef06SEitan Adler 		    reinit_screen();
7543be6ef06SEitan Adler 		    reset_display();
7553be6ef06SEitan Adler 		    tstopflag = 0;
7563be6ef06SEitan Adler 		    goto restart;
7573be6ef06SEitan Adler 		}
7583be6ef06SEitan Adler 
7593be6ef06SEitan Adler 		if (winchflag) {
7603be6ef06SEitan Adler 		    /* reascertain the screen dimensions */
7613be6ef06SEitan Adler 		    get_screensize();
7623be6ef06SEitan Adler 
7633be6ef06SEitan Adler 		    /* tell display to resize */
7643be6ef06SEitan Adler 		    max_topn = display_resize();
7653be6ef06SEitan Adler 
7663be6ef06SEitan Adler 		    /* reset the signal handler */
7675ef89dbfSEitan Adler 		    signal(SIGWINCH, top_winch);
7683be6ef06SEitan Adler 
7693be6ef06SEitan Adler 		    reset_display();
7703be6ef06SEitan Adler 		    winchflag = 0;
7713be6ef06SEitan Adler 		    goto restart;
7723be6ef06SEitan Adler 		}
7733be6ef06SEitan Adler 
7743be6ef06SEitan Adler 		/* wait for either input or the end of the delay period */
7753be6ef06SEitan Adler 		sel_ret = select(2, &readfds, NULL, NULL, &timeout);
7763be6ef06SEitan Adler 		if (sel_ret < 0 && errno != EINTR)
7773be6ef06SEitan Adler 		    quit(0);
7783be6ef06SEitan Adler 		if (sel_ret > 0)
7793be6ef06SEitan Adler 		{
7803be6ef06SEitan Adler 		    int newval;
781fc36f5a7SEitan Adler 		    const char *errmsg;
782c8aa5e52SEitan Adler 			const struct command *cptr;
7833be6ef06SEitan Adler 
7843be6ef06SEitan Adler 		    /* something to read -- clear the message area first */
7853be6ef06SEitan Adler 		    clear_message();
7863be6ef06SEitan Adler 
7873be6ef06SEitan Adler 		    /* now read it and convert to command strchr */
7883be6ef06SEitan Adler 		    /* (use "change" as a temporary to hold strchr) */
7893be6ef06SEitan Adler 		    if (read(0, &ch, 1) != 1)
7903be6ef06SEitan Adler 		    {
7913be6ef06SEitan Adler 			/* read error: either 0 or -1 */
7923be6ef06SEitan Adler 			new_message(MT_standout, " Read error on stdin");
7933be6ef06SEitan Adler 			putchar('\r');
7943be6ef06SEitan Adler 			quit(1);
7953be6ef06SEitan Adler 		    }
796c8aa5e52SEitan Adler 			if (ch == '\r' || ch == '\n') {
797c8aa5e52SEitan Adler 				continue;
7983be6ef06SEitan Adler 			}
799c8aa5e52SEitan Adler 			cptr = all_commands;
800c8aa5e52SEitan Adler 			while (cptr->c != '\0') {
801c8aa5e52SEitan Adler 				if (cptr->c == ch) {
802c8aa5e52SEitan Adler 					break;
803c8aa5e52SEitan Adler 				}
804c8aa5e52SEitan Adler 				cptr++;
805c8aa5e52SEitan Adler 			}
806c8aa5e52SEitan Adler 			if (cptr->c == '\0') {
807c8aa5e52SEitan Adler 			    new_message(MT_standout, " Command not understood");
8083be6ef06SEitan Adler 			    putchar('\r');
8090b2f6ed1SEitan Adler 				no_command = true;
8103be6ef06SEitan Adler 			}
811c8aa5e52SEitan Adler 			if (overstrike && !cptr->available_to_dumb)
8123be6ef06SEitan Adler 			{
8133be6ef06SEitan Adler 			    new_message(MT_standout,
8143be6ef06SEitan Adler 			    " Command cannot be handled by this terminal");
8153be6ef06SEitan Adler 			    putchar('\r');
8160b2f6ed1SEitan Adler 				no_command = true;
8173be6ef06SEitan Adler 			}
818c8aa5e52SEitan Adler 			if (!no_command) {
819c8aa5e52SEitan Adler 			switch(cptr->id)
8203be6ef06SEitan Adler 			{
8213be6ef06SEitan Adler 			    case CMD_redraw:	/* redraw screen */
8223be6ef06SEitan Adler 				reset_display();
8233be6ef06SEitan Adler 				break;
8243be6ef06SEitan Adler 
8253be6ef06SEitan Adler 			    case CMD_update:	/* merely update display */
8263be6ef06SEitan Adler 				break;
8273be6ef06SEitan Adler 
828c8aa5e52SEitan Adler 			    case CMD_quit:
8293be6ef06SEitan Adler 				quit(0);
8303be6ef06SEitan Adler 				break;
8313be6ef06SEitan Adler 
832c8aa5e52SEitan Adler 			    case CMD_help:
8333be6ef06SEitan Adler 				reset_display();
8343be6ef06SEitan Adler 				top_clear();
8353be6ef06SEitan Adler 				show_help();
8363be6ef06SEitan Adler 				top_standout("Hit any key to continue: ");
8373be6ef06SEitan Adler 				fflush(stdout);
8385ef89dbfSEitan Adler 				read(0, &ch, 1);
8393be6ef06SEitan Adler 				break;
8403be6ef06SEitan Adler 
8413be6ef06SEitan Adler 			    case CMD_errors:	/* show errors */
8423be6ef06SEitan Adler 				if (error_count() == 0)
8433be6ef06SEitan Adler 				{
8443be6ef06SEitan Adler 				    new_message(MT_standout,
8453be6ef06SEitan Adler 					" Currently no errors to report.");
8463be6ef06SEitan Adler 				    putchar('\r');
8470b2f6ed1SEitan Adler 				    no_command = true;
8483be6ef06SEitan Adler 				}
8493be6ef06SEitan Adler 				else
8503be6ef06SEitan Adler 				{
8513be6ef06SEitan Adler 				    reset_display();
8523be6ef06SEitan Adler 				    top_clear();
8533be6ef06SEitan Adler 				    show_errors();
8543be6ef06SEitan Adler 				    top_standout("Hit any key to continue: ");
8553be6ef06SEitan Adler 				    fflush(stdout);
8565ef89dbfSEitan Adler 				    read(0, &ch, 1);
8573be6ef06SEitan Adler 				}
8583be6ef06SEitan Adler 				break;
8593be6ef06SEitan Adler 
860c8aa5e52SEitan Adler 			    case CMD_number:
8613be6ef06SEitan Adler 				new_message(MT_standout,
8623be6ef06SEitan Adler 				    "Number of processes to show: ");
8630b2f6ed1SEitan Adler 				newval = readline(tempbuf1, 8, true);
8643be6ef06SEitan Adler 				if (newval > -1)
8653be6ef06SEitan Adler 				{
8663be6ef06SEitan Adler 				    if (newval > max_topn)
8673be6ef06SEitan Adler 				    {
8683be6ef06SEitan Adler 					new_message(MT_standout | MT_delayed,
8693be6ef06SEitan Adler 					  " This terminal can only display %d processes.",
8703be6ef06SEitan Adler 					  max_topn);
8713be6ef06SEitan Adler 					putchar('\r');
8723be6ef06SEitan Adler 				    }
8733be6ef06SEitan Adler 
8743be6ef06SEitan Adler 				    if (newval == 0)
8753be6ef06SEitan Adler 				    {
8763be6ef06SEitan Adler 					/* inhibit the header */
8770b2f6ed1SEitan Adler 					display_header(false);
8783be6ef06SEitan Adler 				    }
8793be6ef06SEitan Adler 				    else if (newval > topn && topn == 0)
8803be6ef06SEitan Adler 				    {
8813be6ef06SEitan Adler 					/* redraw the header */
8820b2f6ed1SEitan Adler 					display_header(true);
8833be6ef06SEitan Adler 					d_header = i_header;
8843be6ef06SEitan Adler 				    }
8853be6ef06SEitan Adler 				    topn = newval;
8863be6ef06SEitan Adler 				}
8873be6ef06SEitan Adler 				break;
8883be6ef06SEitan Adler 
8893be6ef06SEitan Adler 			    case CMD_delay:	/* new seconds delay */
8903be6ef06SEitan Adler 				new_message(MT_standout, "Seconds to delay: ");
891fc4ac32fSDimitry Andric 				if ((i = readline(tempbuf1, 8, false)) > 0)
8923be6ef06SEitan Adler 				{
893fc4ac32fSDimitry Andric 				    double delay_d = strtod(tempbuf1, &nptr);
894fc4ac32fSDimitry Andric 				    if (nptr == tempbuf1 || delay_d <= 0)
895fc4ac32fSDimitry Andric 				    {
896fc4ac32fSDimitry Andric 					new_message(MT_standout, " Invalid delay");
897fc4ac32fSDimitry Andric 					putchar('\r');
898fc4ac32fSDimitry Andric 					no_command = true;
8993be6ef06SEitan Adler 				    }
900fc4ac32fSDimitry Andric 				    else
901fc4ac32fSDimitry Andric 				    {
902fc4ac32fSDimitry Andric 					delay.tv_sec = delay_d;
903fc4ac32fSDimitry Andric 					delay.tv_usec = (delay_d - delay.tv_sec) * 1e6;
9043be6ef06SEitan Adler 					clear_message();
905fc4ac32fSDimitry Andric 				    }
906fc4ac32fSDimitry Andric 				}
9073be6ef06SEitan Adler 				break;
9083be6ef06SEitan Adler 
909a00d703fSJohn Grafton 			    case CMD_grep: /* grep command name */
910a00d703fSJohn Grafton 				new_message(MT_standout,
9114ccbbe5fSJohn Grafton 				    "Grep command name (+ for all): ");
912a00d703fSJohn Grafton 				if (readline(tempbuf1, sizeof(tempbuf1), false) > 0) {
913a00d703fSJohn Grafton 					free(ps.command);
914a00d703fSJohn Grafton 					if (tempbuf1[0] == '+' && tempbuf1[1] == '\0') {
915a00d703fSJohn Grafton 						ps.command = NULL;
916a00d703fSJohn Grafton 					} else if ((ps.command = strdup(tempbuf1)) == NULL)
917a00d703fSJohn Grafton 						quit(1);
918a00d703fSJohn Grafton 				}
919a00d703fSJohn Grafton 				clear_message();
920a00d703fSJohn Grafton 				break;
921a00d703fSJohn Grafton 
9223be6ef06SEitan Adler 			    case CMD_displays:	/* change display count */
9233be6ef06SEitan Adler 				new_message(MT_standout,
9243be6ef06SEitan Adler 					"Displays to show (currently %s): ",
9253be6ef06SEitan Adler 					displays == -1 ? "infinite" :
9263be6ef06SEitan Adler 							 itoa(displays));
9270b2f6ed1SEitan Adler 				if ((i = readline(tempbuf1, 10, true)) > 0)
9283be6ef06SEitan Adler 				{
9293be6ef06SEitan Adler 				    displays = i;
9303be6ef06SEitan Adler 				}
9313be6ef06SEitan Adler 				else if (i == 0)
9323be6ef06SEitan Adler 				{
9333be6ef06SEitan Adler 				    quit(0);
9343be6ef06SEitan Adler 				}
9353be6ef06SEitan Adler 				clear_message();
9363be6ef06SEitan Adler 				break;
9373be6ef06SEitan Adler 
9383be6ef06SEitan Adler 			    case CMD_kill:	/* kill program */
9393be6ef06SEitan Adler 				new_message(0, "kill ");
9400b2f6ed1SEitan Adler 				if (readline(tempbuf2, sizeof(tempbuf2), false) > 0)
9413be6ef06SEitan Adler 				{
9423be6ef06SEitan Adler 				    if ((errmsg = kill_procs(tempbuf2)) != NULL)
9433be6ef06SEitan Adler 				    {
9443be6ef06SEitan Adler 					new_message(MT_standout, "%s", errmsg);
9453be6ef06SEitan Adler 					putchar('\r');
9460b2f6ed1SEitan Adler 					no_command = true;
9473be6ef06SEitan Adler 				    }
9483be6ef06SEitan Adler 				}
9493be6ef06SEitan Adler 				else
9503be6ef06SEitan Adler 				{
9513be6ef06SEitan Adler 				    clear_message();
9523be6ef06SEitan Adler 				}
9533be6ef06SEitan Adler 				break;
9543be6ef06SEitan Adler 
9553be6ef06SEitan Adler 			    case CMD_renice:	/* renice program */
9563be6ef06SEitan Adler 				new_message(0, "renice ");
9570b2f6ed1SEitan Adler 				if (readline(tempbuf2, sizeof(tempbuf2), false) > 0)
9583be6ef06SEitan Adler 				{
9593be6ef06SEitan Adler 				    if ((errmsg = renice_procs(tempbuf2)) != NULL)
9603be6ef06SEitan Adler 				    {
9613be6ef06SEitan Adler 					new_message(MT_standout, "%s", errmsg);
9623be6ef06SEitan Adler 					putchar('\r');
9630b2f6ed1SEitan Adler 					no_command = true;
9643be6ef06SEitan Adler 				    }
9653be6ef06SEitan Adler 				}
9663be6ef06SEitan Adler 				else
9673be6ef06SEitan Adler 				{
9683be6ef06SEitan Adler 				    clear_message();
9693be6ef06SEitan Adler 				}
9703be6ef06SEitan Adler 				break;
9713be6ef06SEitan Adler 
9723be6ef06SEitan Adler 			    case CMD_idletog:
9733be6ef06SEitan Adler 				ps.idle = !ps.idle;
9743be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
9753be6ef06SEitan Adler 				    " %sisplaying idle processes.",
9763be6ef06SEitan Adler 				    ps.idle ? "D" : "Not d");
9773be6ef06SEitan Adler 				putchar('\r');
9783be6ef06SEitan Adler 				break;
9793be6ef06SEitan Adler 
9803be6ef06SEitan Adler 			    case CMD_selftog:
981fc36f5a7SEitan Adler 				ps.self = !ps.self;
9823be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
9833be6ef06SEitan Adler 				    " %sisplaying self.",
984fc36f5a7SEitan Adler 				    (ps.self) ? "D" : "Not d");
9853be6ef06SEitan Adler 				putchar('\r');
9863be6ef06SEitan Adler 				break;
9873be6ef06SEitan Adler 
9883be6ef06SEitan Adler 			    case CMD_user:
9893be6ef06SEitan Adler 				if (handle_user(tempbuf2, sizeof(tempbuf2)))
9900b2f6ed1SEitan Adler 				    no_command = true;
9913be6ef06SEitan Adler 				break;
9923be6ef06SEitan Adler 
9933be6ef06SEitan Adler 			    case CMD_thrtog:
9943be6ef06SEitan Adler 				ps.thread = !ps.thread;
9953be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
9963be6ef06SEitan Adler 				    " Displaying threads %s",
9973be6ef06SEitan Adler 				    ps.thread ? "separately" : "as a count");
9983be6ef06SEitan Adler 				header_text = format_header(uname_field);
9993be6ef06SEitan Adler 				reset_display();
10003be6ef06SEitan Adler 				putchar('\r');
10013be6ef06SEitan Adler 				break;
1002fc36f5a7SEitan Adler 
1003fc36f5a7SEitan Adler 			    case CMD_toggletid:
1004fc36f5a7SEitan Adler 				ps.thread_id = !ps.thread_id;
1005fc36f5a7SEitan Adler 				new_message(MT_standout | MT_delayed,
1006fc36f5a7SEitan Adler 				    " Displaying %s",
1007fc36f5a7SEitan Adler 				    ps.thread_id ? "tid" : "pid");
1008fc36f5a7SEitan Adler 				header_text = format_header(uname_field);
1009fc36f5a7SEitan Adler 				reset_display();
1010fc36f5a7SEitan Adler 				putchar('\r');
1011fc36f5a7SEitan Adler 				break;
1012fc36f5a7SEitan Adler 
10133be6ef06SEitan Adler 			    case CMD_wcputog:
10143be6ef06SEitan Adler 				ps.wcpu = !ps.wcpu;
10153be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
10163be6ef06SEitan Adler 				    " Displaying %s CPU",
10173be6ef06SEitan Adler 				    ps.wcpu ? "weighted" : "raw");
10183be6ef06SEitan Adler 				header_text = format_header(uname_field);
10193be6ef06SEitan Adler 				reset_display();
10203be6ef06SEitan Adler 				putchar('\r');
10213be6ef06SEitan Adler 				break;
10223be6ef06SEitan Adler 			    case CMD_viewtog:
1023ccf22059SEitan Adler 				displaymode = displaymode == DISP_IO ? DISP_CPU : DISP_IO;
1024e7a0ad24SMark Johnston 				new_message(MT_standout | MT_delayed,
1025e7a0ad24SMark Johnston 				    " Displaying %s statistics.",
1026e7a0ad24SMark Johnston 				    displaymode == DISP_IO ? "IO" : "CPU");
10273be6ef06SEitan Adler 				header_text = format_header(uname_field);
10280b2f6ed1SEitan Adler 				display_header(true);
10293be6ef06SEitan Adler 				d_header = i_header;
10303be6ef06SEitan Adler 				reset_display();
10313be6ef06SEitan Adler 				break;
10323be6ef06SEitan Adler 			    case CMD_viewsys:
10333be6ef06SEitan Adler 				ps.system = !ps.system;
1034e7a0ad24SMark Johnston 				new_message(MT_standout | MT_delayed,
1035e7a0ad24SMark Johnston 				    " %sisplaying system processes.",
1036e7a0ad24SMark Johnston 				    ps.system ? "D" : "Not d");
10373be6ef06SEitan Adler 				break;
10383be6ef06SEitan Adler 			    case CMD_showargs:
10393be6ef06SEitan Adler 				fmt_flags ^= FMT_SHOWARGS;
1040a00d703fSJohn Grafton 				show_args = fmt_flags & FMT_SHOWARGS;
1041e7a0ad24SMark Johnston 				new_message(MT_standout | MT_delayed,
1042e7a0ad24SMark Johnston 				    " %sisplaying process arguments.",
1043e7a0ad24SMark Johnston 				    fmt_flags & FMT_SHOWARGS ? "D" : "Not d");
10443be6ef06SEitan Adler 				break;
10453be6ef06SEitan Adler 			    case CMD_order:
10463be6ef06SEitan Adler 				new_message(MT_standout,
10473be6ef06SEitan Adler 				    "Order to sort: ");
10480b2f6ed1SEitan Adler 				if (readline(tempbuf2, sizeof(tempbuf2), false) > 0)
10493be6ef06SEitan Adler 				{
10503be6ef06SEitan Adler 				  if ((i = string_index(tempbuf2, statics.order_names)) == -1)
10513be6ef06SEitan Adler 					{
10523be6ef06SEitan Adler 					  new_message(MT_standout,
10533be6ef06SEitan Adler 					      " %s: unrecognized sorting order", tempbuf2);
10540b2f6ed1SEitan Adler 					  no_command = true;
10553be6ef06SEitan Adler 				    }
10563be6ef06SEitan Adler 				    else
10573be6ef06SEitan Adler 				    {
10583be6ef06SEitan Adler 					order_index = i;
10593be6ef06SEitan Adler 				    }
10603be6ef06SEitan Adler 				    putchar('\r');
10613be6ef06SEitan Adler 				}
10623be6ef06SEitan Adler 				else
10633be6ef06SEitan Adler 				{
10643be6ef06SEitan Adler 				    clear_message();
10653be6ef06SEitan Adler 				}
10663be6ef06SEitan Adler 				break;
10673be6ef06SEitan Adler 			    case CMD_jidtog:
10683be6ef06SEitan Adler 				ps.jail = !ps.jail;
10693be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
10703be6ef06SEitan Adler 				    " %sisplaying jail ID.",
10713be6ef06SEitan Adler 				    ps.jail ? "D" : "Not d");
10723be6ef06SEitan Adler 				header_text = format_header(uname_field);
10733be6ef06SEitan Adler 				reset_display();
10743be6ef06SEitan Adler 				putchar('\r');
10753be6ef06SEitan Adler 				break;
10763be6ef06SEitan Adler 
10773be6ef06SEitan Adler 			    case CMD_jail:
10783be6ef06SEitan Adler 				new_message(MT_standout,
10793be6ef06SEitan Adler 				    "Jail to show (+ for all): ");
10800b2f6ed1SEitan Adler 				if (readline(tempbuf2, sizeof(tempbuf2), false) > 0)
10813be6ef06SEitan Adler 				{
10823be6ef06SEitan Adler 				    if (tempbuf2[0] == '+' &&
10833be6ef06SEitan Adler 					tempbuf2[1] == '\0')
10843be6ef06SEitan Adler 				    {
10853be6ef06SEitan Adler 					ps.jid = -1;
10863be6ef06SEitan Adler 				    }
10873be6ef06SEitan Adler 				    else if ((i = jail_getid(tempbuf2)) == -1)
10883be6ef06SEitan Adler 				    {
10893be6ef06SEitan Adler 					new_message(MT_standout,
10903be6ef06SEitan Adler 					    " %s: unknown jail", tempbuf2);
10910b2f6ed1SEitan Adler 					no_command = true;
10923be6ef06SEitan Adler 				    }
10933be6ef06SEitan Adler 				    else
10943be6ef06SEitan Adler 				    {
10953be6ef06SEitan Adler 					ps.jid = i;
10963be6ef06SEitan Adler 				    }
10973be6ef06SEitan Adler 				    if (ps.jail == 0) {
10983be6ef06SEitan Adler 					    ps.jail = 1;
10993be6ef06SEitan Adler 					    new_message(MT_standout |
11003be6ef06SEitan Adler 						MT_delayed, " Displaying jail "
11013be6ef06SEitan Adler 						"ID.");
11023be6ef06SEitan Adler 					    header_text =
11033be6ef06SEitan Adler 						format_header(uname_field);
11043be6ef06SEitan Adler 					    reset_display();
11053be6ef06SEitan Adler 				    }
11063be6ef06SEitan Adler 				    putchar('\r');
11073be6ef06SEitan Adler 				}
11083be6ef06SEitan Adler 				else
11093be6ef06SEitan Adler 				{
11103be6ef06SEitan Adler 				    clear_message();
11113be6ef06SEitan Adler 				}
11123be6ef06SEitan Adler 				break;
11133be6ef06SEitan Adler 
11143be6ef06SEitan Adler 			    case CMD_kidletog:
11153be6ef06SEitan Adler 				ps.kidle = !ps.kidle;
11163be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
11173be6ef06SEitan Adler 				    " %sisplaying system idle process.",
11183be6ef06SEitan Adler 				    ps.kidle ? "D" : "Not d");
11193be6ef06SEitan Adler 				putchar('\r');
11203be6ef06SEitan Adler 				break;
11213be6ef06SEitan Adler 			    case CMD_pcputog:
11223be6ef06SEitan Adler 				pcpu_stats = !pcpu_stats;
11233be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
11243be6ef06SEitan Adler 				    " Displaying %sCPU statistics.",
11253be6ef06SEitan Adler 				    pcpu_stats ? "per-" : "global ");
11263be6ef06SEitan Adler 				toggle_pcpustats();
11273be6ef06SEitan Adler 				max_topn = display_updatecpus(&statics);
11283be6ef06SEitan Adler 				reset_display();
11293be6ef06SEitan Adler 				putchar('\r');
11303be6ef06SEitan Adler 				break;
11313be6ef06SEitan Adler 			    case CMD_swaptog:
11323be6ef06SEitan Adler 				ps.swap = !ps.swap;
11333be6ef06SEitan Adler 				new_message(MT_standout | MT_delayed,
11343be6ef06SEitan Adler 				    " %sisplaying per-process swap usage.",
11353be6ef06SEitan Adler 				    ps.swap ? "D" : "Not d");
11363be6ef06SEitan Adler 				header_text = format_header(uname_field);
11373be6ef06SEitan Adler 				reset_display();
11383be6ef06SEitan Adler 				putchar('\r');
11393be6ef06SEitan Adler 				break;
114051b29cb7SRoman Bogorodskiy 			    case CMD_pid:
114151b29cb7SRoman Bogorodskiy 				new_message(MT_standout,
114251b29cb7SRoman Bogorodskiy 					"Process id to show (+ for all): ");
114351b29cb7SRoman Bogorodskiy 				if (readline(tempbuf2, sizeof(tempbuf2), false) > 0) {
114451b29cb7SRoman Bogorodskiy 					if (tempbuf2[0] == '+' &&
114551b29cb7SRoman Bogorodskiy                    			    tempbuf2[1] == '\0') {
114651b29cb7SRoman Bogorodskiy 						ps.pid = (pid_t)-1;
114751b29cb7SRoman Bogorodskiy 					} else {
114851b29cb7SRoman Bogorodskiy 						unsigned long long num;
114951b29cb7SRoman Bogorodskiy 						const char *errstr;
115051b29cb7SRoman Bogorodskiy 
115151b29cb7SRoman Bogorodskiy 						num = strtonum(tempbuf2, 0, INT_MAX,
115251b29cb7SRoman Bogorodskiy 							&errstr);
115351b29cb7SRoman Bogorodskiy 						if (errstr != NULL || !find_pid(num)) {
115451b29cb7SRoman Bogorodskiy 							new_message(MT_standout,
115551b29cb7SRoman Bogorodskiy 								" %s: unknown pid",
115651b29cb7SRoman Bogorodskiy 								tempbuf2);
115751b29cb7SRoman Bogorodskiy 							no_command = true;
115851b29cb7SRoman Bogorodskiy 						} else {
115951b29cb7SRoman Bogorodskiy 							ps.pid = (pid_t)num;
116051b29cb7SRoman Bogorodskiy 						}
116151b29cb7SRoman Bogorodskiy 					}
116251b29cb7SRoman Bogorodskiy 					putchar('\r');
116351b29cb7SRoman Bogorodskiy 				} else
116451b29cb7SRoman Bogorodskiy 					clear_message();
116551b29cb7SRoman Bogorodskiy 				break;
1166c8aa5e52SEitan Adler 			    case CMD_NONE:
1167cc114730SEitan Adler 					assert(false && "reached switch without command");
1168c8aa5e52SEitan Adler 			}
11693be6ef06SEitan Adler 			}
11703be6ef06SEitan Adler 		    }
11713be6ef06SEitan Adler 
11723be6ef06SEitan Adler 		    /* flush out stuff that may have been written */
11733be6ef06SEitan Adler 		    fflush(stdout);
11743be6ef06SEitan Adler 		}
11753be6ef06SEitan Adler 	    }
11763be6ef06SEitan Adler     }
11773be6ef06SEitan Adler 
11783be6ef06SEitan Adler #ifdef DEBUG
11793be6ef06SEitan Adler     fclose(debug);
11803be6ef06SEitan Adler #endif
11813be6ef06SEitan Adler     quit(0);
11823be6ef06SEitan Adler }
11833be6ef06SEitan Adler 
11843be6ef06SEitan Adler /*
11853be6ef06SEitan Adler  *  reset_display() - reset all the display routine pointers so that entire
11863be6ef06SEitan Adler  *	screen will get redrawn.
11873be6ef06SEitan Adler  */
11883be6ef06SEitan Adler 
1189a5ca08edSEitan Adler static void
reset_display(void)1190f6234b51SEitan Adler reset_display(void)
11913be6ef06SEitan Adler {
11923be6ef06SEitan Adler     d_loadave    = i_loadave;
11933be6ef06SEitan Adler     d_procstates = i_procstates;
11943be6ef06SEitan Adler     d_cpustates  = i_cpustates;
11953be6ef06SEitan Adler     d_memory     = i_memory;
11963be6ef06SEitan Adler     d_arc        = i_arc;
11973be6ef06SEitan Adler     d_carc       = i_carc;
11983be6ef06SEitan Adler     d_swap       = i_swap;
11993be6ef06SEitan Adler     d_message	 = i_message;
12003be6ef06SEitan Adler     d_header	 = i_header;
12013be6ef06SEitan Adler     d_process	 = i_process;
12023be6ef06SEitan Adler }
12033be6ef06SEitan Adler 
12043be6ef06SEitan Adler /*
12053be6ef06SEitan Adler  *  signal handlers
12063be6ef06SEitan Adler  */
12073be6ef06SEitan Adler 
1208666cf873SEitan Adler static sigret_t
leave(int i __unused)1209666cf873SEitan Adler leave(int i __unused)	/* exit under normal conditions -- INT handler */
12103be6ef06SEitan Adler {
1211b3c88c28SEitan Adler 
12123be6ef06SEitan Adler     leaveflag = 1;
12133be6ef06SEitan Adler }
12143be6ef06SEitan Adler 
1215666cf873SEitan Adler static sigret_t
tstop(int i __unused)1216666cf873SEitan Adler tstop(int i __unused)	/* SIGTSTP handler */
12173be6ef06SEitan Adler {
1218b3c88c28SEitan Adler 
12193be6ef06SEitan Adler     tstopflag = 1;
12203be6ef06SEitan Adler }
12213be6ef06SEitan Adler 
1222666cf873SEitan Adler static sigret_t
top_winch(int i __unused)1223666cf873SEitan Adler top_winch(int i __unused)		/* SIGWINCH handler */
12243be6ef06SEitan Adler {
1225b3c88c28SEitan Adler 
12263be6ef06SEitan Adler     winchflag = 1;
12273be6ef06SEitan Adler }
12283be6ef06SEitan Adler 
122959c50d82SEitan Adler void __dead2
quit(int status)1230666cf873SEitan Adler quit(int status)		/* exit under duress */
12313be6ef06SEitan Adler {
12323be6ef06SEitan Adler     end_screen();
12333be6ef06SEitan Adler     exit(status);
12343be6ef06SEitan Adler }
1235