top.c revision 168799
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 168799 2007-04-17 03:12:39Z rafan $
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;
69168710Sstas
7024139Sjoerg/* signal handling routines */
7124139Sjoergsigret_t leave();
7224139Sjoergsigret_t onalrm();
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
198168799Srafan    static char command_chars[] = "\f qh?en#sdkriIutHmSCajo";
19924139Sjoerg#else
200168799Srafan    static char command_chars[] = "\f qh?en#sdkriIutHmSCaj";
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
22624139Sjoerg#ifdef ORDER
227168799Srafan#define CMD_order       22
22824139Sjoerg#endif
22924139Sjoerg
23024139Sjoerg    /* set the buffer for stdout */
23124139Sjoerg#ifdef DEBUG
23289757Sdwmalone    extern FILE *debug;
23389757Sdwmalone    debug = fopen("debug.run", "w");
23424139Sjoerg    setbuffer(stdout, NULL, 0);
23524139Sjoerg#else
23624139Sjoerg    setbuffer(stdout, stdoutbuf, Buffersize);
23724139Sjoerg#endif
23824139Sjoerg
23924139Sjoerg    /* get our name */
24024139Sjoerg    if (argc > 0)
24124139Sjoerg    {
24224139Sjoerg	if ((myname = strrchr(argv[0], '/')) == 0)
24324139Sjoerg	{
24424139Sjoerg	    myname = argv[0];
24524139Sjoerg	}
24624139Sjoerg	else
24724139Sjoerg	{
24824139Sjoerg	    myname++;
24924139Sjoerg	}
25024139Sjoerg    }
25124139Sjoerg
25224139Sjoerg    /* initialize some selection options */
25324139Sjoerg    ps.idle    = Yes;
25438090Sdes    ps.self    = -1;
25524139Sjoerg    ps.system  = No;
25624139Sjoerg    ps.uid     = -1;
257117709Sjulian    ps.thread  = No;
258146342Skeramida    ps.wcpu    = 1;
259168799Srafan    ps.jail    = No;
26024139Sjoerg    ps.command = NULL;
26124139Sjoerg
26224139Sjoerg    /* get preset options from the environment */
26324139Sjoerg    if ((env_top = getenv("TOP")) != NULL)
26424139Sjoerg    {
26524139Sjoerg	av = preset_argv = argparse(env_top, &preset_argc);
26624139Sjoerg	ac = preset_argc;
26724139Sjoerg
26824139Sjoerg	/* set the dummy argument to an explanatory message, in case
26924139Sjoerg	   getopt encounters a bad argument */
27024139Sjoerg	preset_argv[0] = "while processing environment";
27124139Sjoerg    }
27224139Sjoerg
27324139Sjoerg    /* process options */
27424139Sjoerg    do {
27524139Sjoerg	/* if we're done doing the presets, then process the real arguments */
27624139Sjoerg	if (preset_argc == 0)
27724139Sjoerg	{
27824139Sjoerg	    ac = argc;
27924139Sjoerg	    av = argv;
28024139Sjoerg
28124139Sjoerg	    /* this should keep getopt happy... */
28224139Sjoerg	    optind = 1;
28324139Sjoerg	}
28424139Sjoerg
285168799Srafan	while ((i = getopt(ac, av, "CSIHabijnquvs:d:U:m:o:t")) != EOF)
28624139Sjoerg	{
28724139Sjoerg	    switch(i)
28824139Sjoerg	    {
28989757Sdwmalone	      case 'v':			/* show version number */
29089757Sdwmalone		fprintf(stderr, "%s: version %s\n",
29189757Sdwmalone			myname, version_string());
29289757Sdwmalone		exit(1);
29389757Sdwmalone		break;
29489757Sdwmalone
29524139Sjoerg	      case 'u':			/* toggle uid/username display */
29624139Sjoerg		do_unames = !do_unames;
29724139Sjoerg		break;
29824139Sjoerg
29924139Sjoerg	      case 'U':			/* display only username's processes */
30024139Sjoerg		if ((ps.uid = userid(optarg)) == -1)
30124139Sjoerg		{
30224139Sjoerg		    fprintf(stderr, "%s: unknown user\n", optarg);
30324139Sjoerg		    exit(1);
30424139Sjoerg		}
30524139Sjoerg		break;
30624139Sjoerg
30724139Sjoerg	      case 'S':			/* show system processes */
30824139Sjoerg		ps.system = !ps.system;
30924139Sjoerg		break;
31024139Sjoerg
31124139Sjoerg	      case 'I':                   /* show idle processes */
31224139Sjoerg		ps.idle = !ps.idle;
31324139Sjoerg		break;
31424139Sjoerg
31524139Sjoerg	      case 'i':			/* go interactive regardless */
31624139Sjoerg		interactive = Yes;
31724139Sjoerg		break;
31824139Sjoerg
31924139Sjoerg	      case 'n':			/* batch, or non-interactive */
32024139Sjoerg	      case 'b':
32124139Sjoerg		interactive = No;
32224139Sjoerg		break;
32324139Sjoerg
324168710Sstas	      case 'a':
325168710Sstas		fmt_flags ^= FMT_SHOWARGS;
326168710Sstas		break;
327168710Sstas
32824139Sjoerg	      case 'd':			/* number of displays to show */
32924139Sjoerg		if ((i = atoiwi(optarg)) == Invalid || i == 0)
33024139Sjoerg		{
33124139Sjoerg		    fprintf(stderr,
33224139Sjoerg			"%s: warning: display count should be positive -- option ignored\n",
33324139Sjoerg			myname);
33424139Sjoerg		    warnings++;
33524139Sjoerg		}
33624139Sjoerg		else
33724139Sjoerg		{
33824139Sjoerg		    displays = i;
33924139Sjoerg		}
34024139Sjoerg		break;
34124139Sjoerg
34224139Sjoerg	      case 's':
34389757Sdwmalone		if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0))
34424139Sjoerg		{
34524139Sjoerg		    fprintf(stderr,
34689757Sdwmalone			"%s: warning: seconds delay should be positive -- using default\n",
34724139Sjoerg			myname);
34824139Sjoerg		    delay = Default_DELAY;
34924139Sjoerg		    warnings++;
35024139Sjoerg		}
35124139Sjoerg		break;
35224139Sjoerg
35324139Sjoerg	      case 'q':		/* be quick about it */
35424139Sjoerg		/* only allow this if user is really root */
35524139Sjoerg		if (getuid() == 0)
35624139Sjoerg		{
35724139Sjoerg		    /* be very un-nice! */
35824139Sjoerg		    (void) nice(-20);
35924139Sjoerg		}
36024139Sjoerg		else
36124139Sjoerg		{
36224139Sjoerg		    fprintf(stderr,
36324139Sjoerg			"%s: warning: `-q' option can only be used by root\n",
36424139Sjoerg			myname);
36524139Sjoerg		    warnings++;
36624139Sjoerg		}
36724139Sjoerg		break;
36824139Sjoerg
369131616Sdes	      case 'm':		/* select display mode */
370131402Salfred		if (strcmp(optarg, "io") == 0) {
371131402Salfred			displaymode = DISP_IO;
372131402Salfred		} else if (strcmp(optarg, "cpu") == 0) {
373131402Salfred			displaymode = DISP_CPU;
374131402Salfred		} else {
375131402Salfred			fprintf(stderr,
376131402Salfred			"%s: warning: `-m' option can only take args "
377131402Salfred			"'io' or 'cpu'\n",
378131402Salfred			myname);
379131402Salfred			exit(1);
380131402Salfred		}
381131402Salfred		break;
382131402Salfred
38324139Sjoerg	      case 'o':		/* select sort order */
38424139Sjoerg#ifdef ORDER
38524139Sjoerg		order_name = optarg;
38624139Sjoerg#else
38724139Sjoerg		fprintf(stderr,
38824139Sjoerg			"%s: this platform does not support arbitrary ordering.  Sorry.\n",
38924139Sjoerg			myname);
39024139Sjoerg		warnings++;
39124139Sjoerg#endif
39224139Sjoerg		break;
39324139Sjoerg
39438090Sdes	      case 't':
39538090Sdes		ps.self = (ps.self == -1) ? getpid() : -1;
39638090Sdes		break;
397146342Skeramida
398146342Skeramida	      case 'C':
399146342Skeramida		ps.wcpu = !ps.wcpu;
400146342Skeramida		break;
401146342Skeramida
402117709Sjulian	      case 'H':
403117709Sjulian		ps.thread = !ps.thread;
404117709Sjulian		break;
405146342Skeramida
406168799Srafan	      case 'j':
407168799Srafan		ps.jail = !ps.jail;
408168799Srafan		break;
409168799Srafan
41024139Sjoerg	      default:
411157842Sru		fprintf(stderr,
412157842Sru"Top version %s\n"
413157866Sru"Usage: %s [-bCHIinqStuv] [-d count] [-m io | cpu] [-o field] [-s time]\n"
414157842Sru"       [-U username] [number]\n",
41524139Sjoerg			version_string(), myname);
41624139Sjoerg		exit(1);
41724139Sjoerg	    }
41824139Sjoerg	}
41924139Sjoerg
42024139Sjoerg	/* get count of top processes to display (if any) */
42124139Sjoerg	if (optind < ac)
42224139Sjoerg	{
42324139Sjoerg	    if ((topn = atoiwi(av[optind])) == Invalid)
42424139Sjoerg	    {
42524139Sjoerg		fprintf(stderr,
42624139Sjoerg			"%s: warning: process display count should be non-negative -- using default\n",
42724139Sjoerg			myname);
42824139Sjoerg		warnings++;
42924139Sjoerg	    }
43024139Sjoerg#if Default_TOPN == Infinity
43124139Sjoerg            else
43224139Sjoerg	    {
43324139Sjoerg		topn_specified = Yes;
43424139Sjoerg	    }
43524139Sjoerg#endif
43624139Sjoerg	}
43724139Sjoerg
43824139Sjoerg	/* tricky:  remember old value of preset_argc & set preset_argc = 0 */
43924139Sjoerg	i = preset_argc;
44024139Sjoerg	preset_argc = 0;
44124139Sjoerg
44224139Sjoerg    /* repeat only if we really did the preset arguments */
44324139Sjoerg    } while (i != 0);
44424139Sjoerg
44524139Sjoerg    /* set constants for username/uid display correctly */
44624139Sjoerg    if (!do_unames)
44724139Sjoerg    {
44824139Sjoerg	uname_field = "   UID  ";
44924139Sjoerg	get_userid = itoa7;
45024139Sjoerg    }
45124139Sjoerg
45224139Sjoerg    /* initialize the kernel memory interface */
45324139Sjoerg    if (machine_init(&statics) == -1)
45424139Sjoerg    {
45524139Sjoerg	exit(1);
45624139Sjoerg    }
45724139Sjoerg
45824139Sjoerg#ifdef ORDER
45924139Sjoerg    /* determine sorting order index, if necessary */
46024139Sjoerg    if (order_name != NULL)
46124139Sjoerg    {
46224139Sjoerg	if ((order_index = string_index(order_name, statics.order_names)) == -1)
46324139Sjoerg	{
46424139Sjoerg	    char **pp;
46524139Sjoerg
46624139Sjoerg	    fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n",
46724139Sjoerg		    myname, order_name);
46824139Sjoerg	    fprintf(stderr, "\tTry one of these:");
46924139Sjoerg	    pp = statics.order_names;
47024139Sjoerg	    while (*pp != NULL)
47124139Sjoerg	    {
47224139Sjoerg		fprintf(stderr, " %s", *pp++);
47324139Sjoerg	    }
47424139Sjoerg	    fputc('\n', stderr);
47524139Sjoerg	    exit(1);
47624139Sjoerg	}
47724139Sjoerg    }
47824139Sjoerg#endif
47924139Sjoerg
48024139Sjoerg#ifdef no_initialization_needed
48124139Sjoerg    /* initialize the hashing stuff */
48224139Sjoerg    if (do_unames)
48324139Sjoerg    {
48424139Sjoerg	init_hash();
48524139Sjoerg    }
48624139Sjoerg#endif
48724139Sjoerg
48824139Sjoerg    /* initialize termcap */
48924139Sjoerg    init_termcap(interactive);
49024139Sjoerg
49124139Sjoerg    /* get the string to use for the process area header */
49224139Sjoerg    header_text = format_header(uname_field);
49324139Sjoerg
49424139Sjoerg    /* initialize display interface */
49524139Sjoerg    if ((max_topn = display_init(&statics)) == -1)
49624139Sjoerg    {
49724139Sjoerg	fprintf(stderr, "%s: can't allocate sufficient memory\n", myname);
49824139Sjoerg	exit(4);
49924139Sjoerg    }
50024139Sjoerg
50124139Sjoerg    /* print warning if user requested more processes than we can display */
50224139Sjoerg    if (topn > max_topn)
50324139Sjoerg    {
50424139Sjoerg	fprintf(stderr,
50524139Sjoerg		"%s: warning: this terminal can only display %d processes.\n",
50624139Sjoerg		myname, max_topn);
50724139Sjoerg	warnings++;
50824139Sjoerg    }
50924139Sjoerg
51024139Sjoerg    /* adjust for topn == Infinity */
51124139Sjoerg    if (topn == Infinity)
51224139Sjoerg    {
51324139Sjoerg	/*
51424139Sjoerg	 *  For smart terminals, infinity really means everything that can
51524139Sjoerg	 *  be displayed, or Largest.
51624139Sjoerg	 *  On dumb terminals, infinity means every process in the system!
51724139Sjoerg	 *  We only really want to do that if it was explicitly specified.
51824139Sjoerg	 *  This is always the case when "Default_TOPN != Infinity".  But if
51924139Sjoerg	 *  topn wasn't explicitly specified and we are on a dumb terminal
52024139Sjoerg	 *  and the default is Infinity, then (and only then) we use
52124139Sjoerg	 *  "Nominal_TOPN" instead.
52224139Sjoerg	 */
52324139Sjoerg#if Default_TOPN == Infinity
52424139Sjoerg	topn = smart_terminal ? Largest :
52524139Sjoerg		    (topn_specified ? Largest : Nominal_TOPN);
52624139Sjoerg#else
52724139Sjoerg	topn = Largest;
52824139Sjoerg#endif
52924139Sjoerg    }
53024139Sjoerg
53124139Sjoerg    /* set header display accordingly */
53224139Sjoerg    display_header(topn > 0);
53324139Sjoerg
53424139Sjoerg    /* determine interactive state */
53524139Sjoerg    if (interactive == Maybe)
53624139Sjoerg    {
53724139Sjoerg	interactive = smart_terminal;
53824139Sjoerg    }
53924139Sjoerg
54024139Sjoerg    /* if # of displays not specified, fill it in */
54124139Sjoerg    if (displays == 0)
54224139Sjoerg    {
54324139Sjoerg	displays = smart_terminal ? Infinity : 1;
54424139Sjoerg    }
54524139Sjoerg
54624139Sjoerg    /* hold interrupt signals while setting up the screen and the handlers */
54724139Sjoerg#ifdef SIGHOLD
54824139Sjoerg    sighold(SIGINT);
54924139Sjoerg    sighold(SIGQUIT);
55024139Sjoerg    sighold(SIGTSTP);
55124139Sjoerg#else
55224139Sjoerg    old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP));
55324139Sjoerg#endif
55424139Sjoerg    init_screen();
55524139Sjoerg    (void) signal(SIGINT, leave);
55624139Sjoerg    (void) signal(SIGQUIT, leave);
55724139Sjoerg    (void) signal(SIGTSTP, tstop);
55824139Sjoerg#ifdef SIGWINCH
55924139Sjoerg    (void) signal(SIGWINCH, winch);
56024139Sjoerg#endif
56124139Sjoerg#ifdef SIGRELSE
56224139Sjoerg    sigrelse(SIGINT);
56324139Sjoerg    sigrelse(SIGQUIT);
56424139Sjoerg    sigrelse(SIGTSTP);
56524139Sjoerg#else
56624139Sjoerg    (void) sigsetmask(old_sigmask);
56724139Sjoerg#endif
56824139Sjoerg    if (warnings)
56924139Sjoerg    {
57024139Sjoerg	fputs("....", stderr);
57124139Sjoerg	fflush(stderr);			/* why must I do this? */
57224139Sjoerg	sleep((unsigned)(3 * warnings));
57324139Sjoerg	fputc('\n', stderr);
57424139Sjoerg    }
57524139Sjoerg
57681187Skrisrestart:
57724139Sjoerg
57824139Sjoerg    /*
57924139Sjoerg     *  main loop -- repeat while display count is positive or while it
58024139Sjoerg     *		indicates infinity (by being -1)
58124139Sjoerg     */
58224139Sjoerg
58324139Sjoerg    while ((displays == -1) || (displays-- > 0))
58424139Sjoerg    {
585131402Salfred	int (*compare)();
586131402Salfred
587131402Salfred
58824139Sjoerg	/* get the current stats */
58924139Sjoerg	get_system_info(&system_info);
59024139Sjoerg
59124139Sjoerg#ifdef ORDER
592133817Salfred	compare = compares[order_index];
59324139Sjoerg#else
594131829Skeramida	if (displaymode == DISP_CPU)
595131402Salfred		compare = proc_compare;
596131829Skeramida	else
597131829Skeramida		compare = io_compare;
59824139Sjoerg#endif
59924139Sjoerg
600131402Salfred	/* get the current set of processes */
601131402Salfred	processes =
602131402Salfred		get_process_info(&system_info, &ps, compare);
603131402Salfred
60424139Sjoerg	/* display the load averages */
60524139Sjoerg	(*d_loadave)(system_info.last_pid,
60624139Sjoerg		     system_info.load_avg);
60724139Sjoerg
60824139Sjoerg	/* display the current time */
60924139Sjoerg	/* this method of getting the time SHOULD be fairly portable */
61024139Sjoerg	time(&curr_time);
61142447Sobrien	i_uptime(&system_info.boottime, &curr_time);
61224139Sjoerg	i_timeofday(&curr_time);
61324139Sjoerg
61424139Sjoerg	/* display process state breakdown */
61524139Sjoerg	(*d_procstates)(system_info.p_total,
61624139Sjoerg			system_info.procstates);
61724139Sjoerg
61824139Sjoerg	/* display the cpu state percentage breakdown */
61924139Sjoerg	if (dostates)	/* but not the first time */
62024139Sjoerg	{
62124139Sjoerg	    (*d_cpustates)(system_info.cpustates);
62224139Sjoerg	}
62324139Sjoerg	else
62424139Sjoerg	{
62524139Sjoerg	    /* we'll do it next time */
62624139Sjoerg	    if (smart_terminal)
62724139Sjoerg	    {
62824139Sjoerg		z_cpustates();
62924139Sjoerg	    }
63024139Sjoerg	    else
63124139Sjoerg	    {
63224139Sjoerg		putchar('\n');
63324139Sjoerg	    }
63424139Sjoerg	    dostates = Yes;
63524139Sjoerg	}
63624139Sjoerg
63724139Sjoerg	/* display memory stats */
63824139Sjoerg	(*d_memory)(system_info.memory);
63924139Sjoerg
64024142Sjoerg	/* display swap stats */
64124142Sjoerg	(*d_swap)(system_info.swap);
64224142Sjoerg
64324139Sjoerg	/* handle message area */
64424139Sjoerg	(*d_message)();
64524139Sjoerg
64624139Sjoerg	/* update the header area */
64724139Sjoerg	(*d_header)(header_text);
64824139Sjoerg
64924139Sjoerg	if (topn > 0)
65024139Sjoerg	{
65124139Sjoerg	    /* determine number of processes to actually display */
65224139Sjoerg	    /* this number will be the smallest of:  active processes,
65324139Sjoerg	       number user requested, number current screen accomodates */
65489757Sdwmalone	    active_procs = system_info.P_ACTIVE;
65524139Sjoerg	    if (active_procs > topn)
65624139Sjoerg	    {
65724139Sjoerg		active_procs = topn;
65824139Sjoerg	    }
65924139Sjoerg	    if (active_procs > max_topn)
66024139Sjoerg	    {
66124139Sjoerg		active_procs = max_topn;
66224139Sjoerg	    }
66324139Sjoerg
66424139Sjoerg	    /* now show the top "n" processes. */
66524139Sjoerg	    for (i = 0; i < active_procs; i++)
66624139Sjoerg	    {
667168710Sstas		(*d_process)(i, format_next_process(processes, get_userid,
668168710Sstas			     fmt_flags));
66924139Sjoerg	    }
67024139Sjoerg	}
67124139Sjoerg	else
67224139Sjoerg	{
67324139Sjoerg	    i = 0;
67424139Sjoerg	}
67524139Sjoerg
67624139Sjoerg	/* do end-screen processing */
67724139Sjoerg	u_endscreen(i);
67824139Sjoerg
67924139Sjoerg	/* now, flush the output buffer */
68089757Sdwmalone	if (fflush(stdout) != 0)
68189757Sdwmalone	{
68289757Sdwmalone	    new_message(MT_standout, " Write error on stdout");
68389757Sdwmalone	    putchar('\r');
68489757Sdwmalone	    quit(1);
68589757Sdwmalone	    /*NOTREACHED*/
68689757Sdwmalone	}
68724139Sjoerg
68824139Sjoerg	/* only do the rest if we have more displays to show */
68924139Sjoerg	if (displays)
69024139Sjoerg	{
69124139Sjoerg	    /* switch out for new display on smart terminals */
69224139Sjoerg	    if (smart_terminal)
69324139Sjoerg	    {
69424139Sjoerg		if (overstrike)
69524139Sjoerg		{
69624139Sjoerg		    reset_display();
69724139Sjoerg		}
69824139Sjoerg		else
69924139Sjoerg		{
70024139Sjoerg		    d_loadave = u_loadave;
70124139Sjoerg		    d_procstates = u_procstates;
70224139Sjoerg		    d_cpustates = u_cpustates;
70324139Sjoerg		    d_memory = u_memory;
70424142Sjoerg		    d_swap = u_swap;
70524139Sjoerg		    d_message = u_message;
70624139Sjoerg		    d_header = u_header;
70724139Sjoerg		    d_process = u_process;
70824139Sjoerg		}
70924139Sjoerg	    }
71024139Sjoerg
71124139Sjoerg	    no_command = Yes;
71224139Sjoerg	    if (!interactive)
71324139Sjoerg	    {
71424139Sjoerg		/* set up alarm */
71524139Sjoerg		(void) signal(SIGALRM, onalrm);
71624139Sjoerg		(void) alarm((unsigned)delay);
71724139Sjoerg
71824139Sjoerg		/* wait for the rest of it .... */
71924139Sjoerg		pause();
72024139Sjoerg	    }
72124139Sjoerg	    else while (no_command)
72224139Sjoerg	    {
72324139Sjoerg		/* assume valid command unless told otherwise */
72424139Sjoerg		no_command = No;
72524139Sjoerg
72624139Sjoerg		/* set up arguments for select with timeout */
72724139Sjoerg		FD_ZERO(&readfds);
72889757Sdwmalone		FD_SET(0, &readfds);		/* for standard input */
72924139Sjoerg		timeout.tv_sec  = delay;
73024139Sjoerg		timeout.tv_usec = 0;
73124139Sjoerg
73281187Skris		if (leaveflag) {
73381187Skris		    end_screen();
73481187Skris		    exit(0);
73581187Skris		}
73681187Skris
73781187Skris		if (tstopflag) {
73881187Skris		    /* move to the lower left */
73981187Skris		    end_screen();
74081187Skris		    fflush(stdout);
74181187Skris
74281187Skris		    /* default the signal handler action */
74381187Skris		    (void) signal(SIGTSTP, SIG_DFL);
74481187Skris
74581187Skris		    /* unblock the signal and send ourselves one */
74681187Skris#ifdef SIGRELSE
74781187Skris		    sigrelse(SIGTSTP);
74881187Skris#else
74981187Skris		    (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
75081187Skris#endif
75181187Skris		    (void) kill(0, SIGTSTP);
75281187Skris
75381187Skris		    /* reset the signal handler */
75481187Skris		    (void) signal(SIGTSTP, tstop);
75581187Skris
75681187Skris		    /* reinit screen */
75781187Skris		    reinit_screen();
75881187Skris		    reset_display();
75981187Skris		    tstopflag = 0;
76081187Skris		    goto restart;
76181187Skris		}
76281187Skris
76381187Skris		if (winchflag) {
76481187Skris		    /* reascertain the screen dimensions */
76581187Skris		    get_screensize();
76681187Skris
76781187Skris		    /* tell display to resize */
76881187Skris		    max_topn = display_resize();
76981187Skris
77081187Skris		    /* reset the signal handler */
77181187Skris		    (void) signal(SIGWINCH, winch);
77281187Skris
77381187Skris		    reset_display();
77481187Skris		    winchflag = 0;
77581187Skris		    goto restart;
77681187Skris		}
77781187Skris
77824139Sjoerg		/* wait for either input or the end of the delay period */
77986042Sdwmalone		sel_ret = select(2, &readfds, NULL, NULL, &timeout);
78086042Sdwmalone		if (sel_ret < 0 && errno != EINTR)
78186042Sdwmalone		    quit(0);
78286042Sdwmalone		if (sel_ret > 0)
78324139Sjoerg		{
78424139Sjoerg		    int newval;
78524139Sjoerg		    char *errmsg;
78624139Sjoerg
78724139Sjoerg		    /* something to read -- clear the message area first */
78824139Sjoerg		    clear_message();
78924139Sjoerg
79024139Sjoerg		    /* now read it and convert to command strchr */
79124139Sjoerg		    /* (use "change" as a temporary to hold strchr) */
79286042Sdwmalone		    if (read(0, &ch, 1) != 1)
79389757Sdwmalone		    {
79489757Sdwmalone			/* read error: either 0 or -1 */
79589757Sdwmalone			new_message(MT_standout, " Read error on stdin");
79689757Sdwmalone			putchar('\r');
79789757Sdwmalone			quit(1);
79889757Sdwmalone			/*NOTREACHED*/
79989757Sdwmalone		    }
80024139Sjoerg		    if ((iptr = strchr(command_chars, ch)) == NULL)
80124139Sjoerg		    {
80224142Sjoerg			if (ch != '\r' && ch != '\n')
80324142Sjoerg			{
80424142Sjoerg			    /* illegal command */
80524142Sjoerg			    new_message(MT_standout, " Command not understood");
80624142Sjoerg			}
80724139Sjoerg			putchar('\r');
80824139Sjoerg			no_command = Yes;
80924139Sjoerg		    }
81024139Sjoerg		    else
81124139Sjoerg		    {
81224139Sjoerg			change = iptr - command_chars;
81324139Sjoerg			if (overstrike && change > CMD_OSLIMIT)
81424139Sjoerg			{
81524139Sjoerg			    /* error */
81624139Sjoerg			    new_message(MT_standout,
81724139Sjoerg			    " Command cannot be handled by this terminal");
81824139Sjoerg			    putchar('\r');
81924139Sjoerg			    no_command = Yes;
82024139Sjoerg			}
82124139Sjoerg			else switch(change)
82224139Sjoerg			{
82324139Sjoerg			    case CMD_redraw:	/* redraw screen */
82424139Sjoerg				reset_display();
82524139Sjoerg				break;
82624139Sjoerg
82724139Sjoerg			    case CMD_update:	/* merely update display */
82824139Sjoerg				/* is the load average high? */
82924139Sjoerg				if (system_info.load_avg[0] > LoadMax)
83024139Sjoerg				{
83124139Sjoerg				    /* yes, go home for visual feedback */
83224139Sjoerg				    go_home();
83324139Sjoerg				    fflush(stdout);
83424139Sjoerg				}
83524139Sjoerg				break;
83624139Sjoerg
83724139Sjoerg			    case CMD_quit:	/* quit */
83824139Sjoerg				quit(0);
83924139Sjoerg				/*NOTREACHED*/
84024139Sjoerg				break;
84124139Sjoerg
84224139Sjoerg			    case CMD_help1:	/* help */
84324139Sjoerg			    case CMD_help2:
84424139Sjoerg				reset_display();
84524139Sjoerg				clear();
84624139Sjoerg				show_help();
84724139Sjoerg				standout("Hit any key to continue: ");
84824139Sjoerg				fflush(stdout);
84924139Sjoerg				(void) read(0, &ch, 1);
85024139Sjoerg				break;
85124139Sjoerg
85224139Sjoerg			    case CMD_errors:	/* show errors */
85324139Sjoerg				if (error_count() == 0)
85424139Sjoerg				{
85524139Sjoerg				    new_message(MT_standout,
85624139Sjoerg					" Currently no errors to report.");
85724139Sjoerg				    putchar('\r');
85824139Sjoerg				    no_command = Yes;
85924139Sjoerg				}
86024139Sjoerg				else
86124139Sjoerg				{
86224139Sjoerg				    reset_display();
86324139Sjoerg				    clear();
86424139Sjoerg				    show_errors();
86524139Sjoerg				    standout("Hit any key to continue: ");
86624139Sjoerg				    fflush(stdout);
86724139Sjoerg				    (void) read(0, &ch, 1);
86824139Sjoerg				}
86924139Sjoerg				break;
87024139Sjoerg
87124139Sjoerg			    case CMD_number1:	/* new number */
87224139Sjoerg			    case CMD_number2:
87324139Sjoerg				new_message(MT_standout,
87424139Sjoerg				    "Number of processes to show: ");
87524139Sjoerg				newval = readline(tempbuf1, 8, Yes);
87624139Sjoerg				if (newval > -1)
87724139Sjoerg				{
87824139Sjoerg				    if (newval > max_topn)
87924139Sjoerg				    {
88024139Sjoerg					new_message(MT_standout | MT_delayed,
88124139Sjoerg					  " This terminal can only display %d processes.",
88224139Sjoerg					  max_topn);
88324139Sjoerg					putchar('\r');
88424139Sjoerg				    }
88524139Sjoerg
88624139Sjoerg				    if (newval == 0)
88724139Sjoerg				    {
88824139Sjoerg					/* inhibit the header */
88924139Sjoerg					display_header(No);
89024139Sjoerg				    }
89124139Sjoerg				    else if (newval > topn && topn == 0)
89224139Sjoerg				    {
89324139Sjoerg					/* redraw the header */
89424139Sjoerg					display_header(Yes);
89524139Sjoerg					d_header = i_header;
89624139Sjoerg				    }
89724139Sjoerg				    topn = newval;
89824139Sjoerg				}
89924139Sjoerg				break;
90024139Sjoerg
90124139Sjoerg			    case CMD_delay:	/* new seconds delay */
90224139Sjoerg				new_message(MT_standout, "Seconds to delay: ");
90324139Sjoerg				if ((i = readline(tempbuf1, 8, Yes)) > -1)
90424139Sjoerg				{
90589757Sdwmalone				    if ((delay = i) == 0 && getuid() != 0)
90689757Sdwmalone				    {
90789757Sdwmalone					delay = 1;
90889757Sdwmalone				    }
90924139Sjoerg				}
91024139Sjoerg				clear_message();
91124139Sjoerg				break;
91224139Sjoerg
91324139Sjoerg			    case CMD_displays:	/* change display count */
91424139Sjoerg				new_message(MT_standout,
91524139Sjoerg					"Displays to show (currently %s): ",
91624139Sjoerg					displays == -1 ? "infinite" :
91724139Sjoerg							 itoa(displays));
91824139Sjoerg				if ((i = readline(tempbuf1, 10, Yes)) > 0)
91924139Sjoerg				{
92024139Sjoerg				    displays = i;
92124139Sjoerg				}
92224139Sjoerg				else if (i == 0)
92324139Sjoerg				{
92424139Sjoerg				    quit(0);
92524139Sjoerg				}
92624139Sjoerg				clear_message();
92724139Sjoerg				break;
92824139Sjoerg
92924139Sjoerg			    case CMD_kill:	/* kill program */
93024139Sjoerg				new_message(0, "kill ");
93124139Sjoerg				if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
93224139Sjoerg				{
93324139Sjoerg				    if ((errmsg = kill_procs(tempbuf2)) != NULL)
93424139Sjoerg				    {
93566641Simp					new_message(MT_standout, "%s", errmsg);
93624139Sjoerg					putchar('\r');
93724139Sjoerg					no_command = Yes;
93824139Sjoerg				    }
93924139Sjoerg				}
94024139Sjoerg				else
94124139Sjoerg				{
94224139Sjoerg				    clear_message();
94324139Sjoerg				}
94424139Sjoerg				break;
94524139Sjoerg
94624139Sjoerg			    case CMD_renice:	/* renice program */
94724139Sjoerg				new_message(0, "renice ");
94824139Sjoerg				if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
94924139Sjoerg				{
95024139Sjoerg				    if ((errmsg = renice_procs(tempbuf2)) != NULL)
95124139Sjoerg				    {
95268293Simp					new_message(MT_standout, "%s", errmsg);
95324139Sjoerg					putchar('\r');
95424139Sjoerg					no_command = Yes;
95524139Sjoerg				    }
95624139Sjoerg				}
95724139Sjoerg				else
95824139Sjoerg				{
95924139Sjoerg				    clear_message();
96024139Sjoerg				}
96124139Sjoerg				break;
96224139Sjoerg
96324139Sjoerg			    case CMD_idletog:
96424139Sjoerg			    case CMD_idletog2:
96524139Sjoerg				ps.idle = !ps.idle;
96624139Sjoerg				new_message(MT_standout | MT_delayed,
96724139Sjoerg				    " %sisplaying idle processes.",
96824139Sjoerg				    ps.idle ? "D" : "Not d");
96924139Sjoerg				putchar('\r');
97024139Sjoerg				break;
97124139Sjoerg
97238090Sdes			    case CMD_selftog:
97338090Sdes				ps.self = (ps.self == -1) ? getpid() : -1;
97438090Sdes				new_message(MT_standout | MT_delayed,
97538090Sdes				    " %sisplaying self.",
97638090Sdes				    (ps.self == -1) ? "D" : "Not d");
97738090Sdes				putchar('\r');
97838090Sdes				break;
97938090Sdes
98024139Sjoerg			    case CMD_user:
98124139Sjoerg				new_message(MT_standout,
98224139Sjoerg				    "Username to show: ");
98324139Sjoerg				if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
98424139Sjoerg				{
98524139Sjoerg				    if (tempbuf2[0] == '+' &&
98624139Sjoerg					tempbuf2[1] == '\0')
98724139Sjoerg				    {
98824139Sjoerg					ps.uid = -1;
98924139Sjoerg				    }
99024139Sjoerg				    else if ((i = userid(tempbuf2)) == -1)
99124139Sjoerg				    {
99224139Sjoerg					new_message(MT_standout,
99324139Sjoerg					    " %s: unknown user", tempbuf2);
99424139Sjoerg					no_command = Yes;
99524139Sjoerg				    }
99624139Sjoerg				    else
99724139Sjoerg				    {
99824139Sjoerg					ps.uid = i;
99924139Sjoerg				    }
100024139Sjoerg				    putchar('\r');
100124139Sjoerg				}
100224139Sjoerg				else
100324139Sjoerg				{
100424139Sjoerg				    clear_message();
100524139Sjoerg				}
100624139Sjoerg				break;
100724139Sjoerg
1008117709Sjulian			    case CMD_thrtog:
1009117709Sjulian				ps.thread = !ps.thread;
1010117709Sjulian				new_message(MT_standout | MT_delayed,
1011145073Skeramida				    "Displaying threads %s",
1012145073Skeramida				    ps.thread ? "separately" : "as a count");
1013145073Skeramida				header_text = format_header(uname_field);
1014145073Skeramida				reset_display();
1015117709Sjulian				putchar('\r');
1016117709Sjulian				break;
1017146342Skeramida			    case CMD_wcputog:
1018146342Skeramida				ps.wcpu = !ps.wcpu;
1019146342Skeramida				new_message(MT_standout | MT_delayed,
1020146342Skeramida				    "Displaying %sCPU",
1021146342Skeramida				    ps.wcpu ? "W" : "");
1022146342Skeramida				header_text = format_header(uname_field);
1023146342Skeramida				reset_display();
1024146342Skeramida				putchar('\r');
1025146342Skeramida				break;
1026131402Salfred			    case CMD_viewtog:
1027131402Salfred				if (++displaymode == DISP_MAX)
1028131402Salfred					displaymode = 0;
1029131402Salfred				header_text = format_header(uname_field);
1030131402Salfred				display_header(Yes);
1031131402Salfred				d_header = i_header;
1032131402Salfred				reset_display();
1033131402Salfred				break;
1034132005Salfred			    case CMD_viewsys:
1035132005Salfred				ps.system = !ps.system;
1036132005Salfred				break;
1037168710Sstas			    case CMD_showargs:
1038168710Sstas				fmt_flags ^= FMT_SHOWARGS;
1039168710Sstas				break;
104024139Sjoerg#ifdef ORDER
104124139Sjoerg			    case CMD_order:
104224139Sjoerg				new_message(MT_standout,
104324139Sjoerg				    "Order to sort: ");
104424139Sjoerg				if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
104524139Sjoerg				{
104624139Sjoerg				  if ((i = string_index(tempbuf2, statics.order_names)) == -1)
104724139Sjoerg					{
104824139Sjoerg					  new_message(MT_standout,
104924139Sjoerg					      " %s: unrecognized sorting order", tempbuf2);
105024139Sjoerg					  no_command = Yes;
105124139Sjoerg				    }
105224139Sjoerg				    else
105324139Sjoerg				    {
105424139Sjoerg					order_index = i;
105524139Sjoerg				    }
105624139Sjoerg				    putchar('\r');
105724139Sjoerg				}
105824139Sjoerg				else
105924139Sjoerg				{
106024139Sjoerg				    clear_message();
106124139Sjoerg				}
106224139Sjoerg				break;
106324139Sjoerg#endif
1064168799Srafan			    case CMD_jidtog:
1065168799Srafan				ps.jail = !ps.jail;
1066168799Srafan				new_message(MT_standout | MT_delayed,
1067168799Srafan				    " %sisplaying jail id.",
1068168799Srafan				    ps.jail ? "D" : "Not d");
1069168799Srafan				header_text = format_header(uname_field);
1070168799Srafan				reset_display();
1071168799Srafan				putchar('\r');
1072168799Srafan				break;
107324139Sjoerg
107424139Sjoerg			    default:
107524139Sjoerg				new_message(MT_standout, " BAD CASE IN SWITCH!");
107624139Sjoerg				putchar('\r');
107724139Sjoerg			}
107824139Sjoerg		    }
107924139Sjoerg
108024139Sjoerg		    /* flush out stuff that may have been written */
108124139Sjoerg		    fflush(stdout);
108224139Sjoerg		}
108324139Sjoerg	    }
108424139Sjoerg	}
108524139Sjoerg    }
108624139Sjoerg
108789757Sdwmalone#ifdef DEBUG
108889757Sdwmalone    fclose(debug);
108989757Sdwmalone#endif
109024139Sjoerg    quit(0);
109124139Sjoerg    /*NOTREACHED*/
109224139Sjoerg}
109324139Sjoerg
109424139Sjoerg/*
109524139Sjoerg *  reset_display() - reset all the display routine pointers so that entire
109624139Sjoerg *	screen will get redrawn.
109724139Sjoerg */
109824139Sjoerg
109924139Sjoergreset_display()
110024139Sjoerg
110124139Sjoerg{
110224139Sjoerg    d_loadave    = i_loadave;
110324139Sjoerg    d_procstates = i_procstates;
110424139Sjoerg    d_cpustates  = i_cpustates;
110524139Sjoerg    d_memory     = i_memory;
110624142Sjoerg    d_swap       = i_swap;
110724139Sjoerg    d_message	 = i_message;
110824139Sjoerg    d_header	 = i_header;
110924139Sjoerg    d_process	 = i_process;
111024139Sjoerg}
111124139Sjoerg
111224139Sjoerg/*
111324139Sjoerg *  signal handlers
111424139Sjoerg */
111524139Sjoerg
111624139Sjoergsigret_t leave()	/* exit under normal conditions -- INT handler */
111724139Sjoerg
111824139Sjoerg{
111981187Skris    leaveflag = 1;
112024139Sjoerg}
112124139Sjoerg
112224139Sjoergsigret_t tstop(i)	/* SIGTSTP handler */
112324139Sjoerg
112424139Sjoergint i;
112524139Sjoerg
112624139Sjoerg{
112781187Skris    tstopflag = 1;
112824139Sjoerg}
112924139Sjoerg
113024139Sjoerg#ifdef SIGWINCH
113124139Sjoergsigret_t winch(i)		/* SIGWINCH handler */
113224139Sjoerg
113324139Sjoergint i;
113424139Sjoerg
113524139Sjoerg{
113681187Skris    winchflag = 1;
113724139Sjoerg}
113824139Sjoerg#endif
113924139Sjoerg
114024139Sjoergvoid quit(status)		/* exit under duress */
114124139Sjoerg
114224139Sjoergint status;
114324139Sjoerg
114424139Sjoerg{
114524139Sjoerg    end_screen();
114624139Sjoerg    exit(status);
114724139Sjoerg    /*NOTREACHED*/
114824139Sjoerg}
114924139Sjoerg
115024139Sjoergsigret_t onalrm()	/* SIGALRM handler */
115124139Sjoerg
115224139Sjoerg{
115324139Sjoerg    /* this is only used in batch mode to break out of the pause() */
115424139Sjoerg    /* return; */
115524139Sjoerg}
115624139Sjoerg
1157