124139Sjoergchar *copyright = 224139Sjoerg "Copyright (c) 1984 through 1996, William LeFebvre"; 324139Sjoerg 424139Sjoerg/* 524139Sjoerg * Top users/processes display for Unix 624139Sjoerg * Version 3 724139Sjoerg * 824139Sjoerg * This program may be freely redistributed, 924139Sjoerg * but this entire comment MUST remain intact. 1024139Sjoerg * 1124139Sjoerg * Copyright (c) 1984, 1989, William LeFebvre, Rice University 1289757Sdwmalone * Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University 1389757Sdwmalone * Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory 1489757Sdwmalone * Copyright (c) 1996, William LeFebvre, Group sys Consulting 1566641Simp * 1666641Simp * $FreeBSD$ 1724139Sjoerg */ 1824139Sjoerg 1924139Sjoerg/* 2024139Sjoerg * See the file "Changes" for information on version-to-version changes. 2124139Sjoerg */ 2224139Sjoerg 2324139Sjoerg/* 2424139Sjoerg * This file contains "main" and other high-level routines. 2524139Sjoerg */ 2624139Sjoerg 2724139Sjoerg/* 2824139Sjoerg * The following preprocessor variables, when defined, are used to 2924139Sjoerg * distinguish between different Unix implementations: 3024139Sjoerg * 3124139Sjoerg * SIGHOLD - use SVR4 sighold function when defined 3224139Sjoerg * SIGRELSE - use SVR4 sigrelse function when defined 3324139Sjoerg * FD_SET - macros FD_SET and FD_ZERO are used when defined 3424139Sjoerg */ 3524139Sjoerg 3624139Sjoerg#include "os.h" 37301836Sngie 38266280Sbdrewery#include <sys/jail.h> 3924139Sjoerg#include <sys/time.h> 40301836Sngie 41301836Sngie#include <ctype.h> 42301836Sngie#include <errno.h> 43266280Sbdrewery#include <jail.h> 44301836Sngie#include <setjmp.h> 45301836Sngie#include <signal.h> 46301836Sngie#include <unistd.h> 4724139Sjoerg 4824139Sjoerg/* includes specific to top */ 49301836Sngie#include "commands.h" 5024139Sjoerg#include "display.h" /* interface to display package */ 5124139Sjoerg#include "screen.h" /* interface to screen package */ 5224139Sjoerg#include "top.h" 5324139Sjoerg#include "top.local.h" 5424139Sjoerg#include "boolean.h" 5524139Sjoerg#include "machine.h" 5624139Sjoerg#include "utils.h" 57301836Sngie#include "username.h" 5824139Sjoerg 5924139Sjoerg/* Size of the stdio buffer given to stdout */ 6024139Sjoerg#define Buffersize 2048 6124139Sjoerg 6224139Sjoerg/* The buffer that stdio will use */ 6324139Sjoergchar stdoutbuf[Buffersize]; 6424139Sjoerg 6524139Sjoerg/* build Signal masks */ 6624139Sjoerg#define Smask(s) (1 << ((s) - 1)) 6724139Sjoerg 6824139Sjoerg/* for getopt: */ 6924139Sjoergextern int optind; 7024139Sjoergextern char *optarg; 7124139Sjoerg 7224139Sjoerg/* imported from screen.c */ 7324139Sjoergextern int overstrike; 7424139Sjoerg 75168710Sstasstatic int fmt_flags = 0; 76175420Speterint pcpu_stats = No; 77168710Sstas 7824139Sjoerg/* signal handling routines */ 7924139Sjoergsigret_t leave(); 8024139Sjoergsigret_t tstop(); 8124139Sjoerg#ifdef SIGWINCH 8224139Sjoergsigret_t winch(); 8324139Sjoerg#endif 8424139Sjoerg 8581187Skrisvolatile sig_atomic_t leaveflag; 8681187Skrisvolatile sig_atomic_t tstopflag; 8781187Skrisvolatile sig_atomic_t winchflag; 8881187Skris 8924139Sjoerg/* internal routines */ 9024139Sjoergvoid quit(); 9124139Sjoerg 9224139Sjoerg/* values which need to be accessed by signal handlers */ 9324139Sjoergstatic int max_topn; /* maximum displayable processes */ 9424139Sjoerg 9524139Sjoerg/* miscellaneous things */ 96145073Skeramidastruct process_select ps; 9724139Sjoergchar *myname = "top"; 9824139Sjoergjmp_buf jmp_int; 9924139Sjoerg 10024139Sjoerg/* routines that don't return int */ 10124139Sjoerg 10224139Sjoergchar *username(); 10324139Sjoergchar *ctime(); 10424139Sjoergchar *kill_procs(); 10524139Sjoergchar *renice_procs(); 10624139Sjoerg 10724139Sjoerg#ifdef ORDER 108133817Salfredextern int (*compares[])(); 10924139Sjoerg#else 11024139Sjoergextern int proc_compare(); 111131829Skeramidaextern int io_compare(); 11224139Sjoerg#endif 11324139Sjoergtime_t time(); 11424139Sjoerg 11524139Sjoergcaddr_t get_process_info(); 11624139Sjoerg 11724139Sjoerg/* different routines for displaying the user's identification */ 11824139Sjoerg/* (values assigned to get_userid) */ 11924139Sjoergchar *username(); 12024139Sjoergchar *itoa7(); 12124139Sjoerg 12224139Sjoerg/* pointers to display routines */ 123301836Sngievoid (*d_loadave)() = i_loadave; 124301836Sngievoid (*d_procstates)() = i_procstates; 125301836Sngievoid (*d_cpustates)() = i_cpustates; 126301836Sngievoid (*d_memory)() = i_memory; 127301836Sngievoid (*d_arc)() = i_arc; 128301836Sngievoid (*d_swap)() = i_swap; 129301836Sngievoid (*d_message)() = i_message; 130301836Sngievoid (*d_header)() = i_header; 131301836Sngievoid (*d_process)() = i_process; 13224139Sjoerg 133301836Sngievoid reset_display(void); 13424139Sjoerg 135301836Sngie 136301836Sngieint 13724139Sjoergmain(argc, argv) 13824139Sjoerg 13924139Sjoergint argc; 14024139Sjoergchar *argv[]; 14124139Sjoerg 14224139Sjoerg{ 14324139Sjoerg register int i; 14424139Sjoerg register int active_procs; 14524139Sjoerg register int change; 14624139Sjoerg 14724139Sjoerg struct system_info system_info; 14824139Sjoerg struct statics statics; 14924139Sjoerg caddr_t processes; 15024139Sjoerg 15124139Sjoerg static char tempbuf1[50]; 15224139Sjoerg static char tempbuf2[50]; 15324139Sjoerg int old_sigmask; /* only used for BSD-style signals */ 15424139Sjoerg int topn = Default_TOPN; 15524139Sjoerg int delay = Default_DELAY; 15624139Sjoerg int displays = 0; /* indicates unspecified */ 15786042Sdwmalone int sel_ret = 0; 15824139Sjoerg time_t curr_time; 15924139Sjoerg char *(*get_userid)() = username; 16024139Sjoerg char *uname_field = "USERNAME"; 16124139Sjoerg char *header_text; 16224139Sjoerg char *env_top; 16324139Sjoerg char **preset_argv; 16424139Sjoerg int preset_argc = 0; 16524139Sjoerg char **av; 16624139Sjoerg int ac; 16724139Sjoerg char dostates = No; 16824139Sjoerg char do_unames = Yes; 16924139Sjoerg char interactive = Maybe; 17024139Sjoerg char warnings = 0; 17124139Sjoerg#if Default_TOPN == Infinity 17224139Sjoerg char topn_specified = No; 17324139Sjoerg#endif 17424139Sjoerg char ch; 17524139Sjoerg char *iptr; 17624139Sjoerg char no_command = 1; 17724139Sjoerg struct timeval timeout; 17824139Sjoerg#ifdef ORDER 17924139Sjoerg char *order_name = NULL; 18024139Sjoerg int order_index = 0; 18124139Sjoerg#endif 18224139Sjoerg#ifndef FD_SET 18324139Sjoerg /* FD_SET and friends are not present: fake it */ 18424139Sjoerg typedef int fd_set; 18524139Sjoerg#define FD_ZERO(x) (*(x) = 0) 18689757Sdwmalone#define FD_SET(f, x) (*(x) = 1<<f) 18724139Sjoerg#endif 18824139Sjoerg fd_set readfds; 18924139Sjoerg 19024139Sjoerg#ifdef ORDER 191266280Sbdrewery static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJo"; 19224139Sjoerg#else 193266280Sbdrewery static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJ"; 19424139Sjoerg#endif 19524139Sjoerg/* these defines enumerate the "strchr"s of the commands in command_chars */ 19624139Sjoerg#define CMD_redraw 0 19724139Sjoerg#define CMD_update 1 19824139Sjoerg#define CMD_quit 2 19924139Sjoerg#define CMD_help1 3 20024139Sjoerg#define CMD_help2 4 20124139Sjoerg#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ 20224139Sjoerg#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ 20324139Sjoerg#define CMD_number1 6 20424139Sjoerg#define CMD_number2 7 20524139Sjoerg#define CMD_delay 8 20624139Sjoerg#define CMD_displays 9 20724139Sjoerg#define CMD_kill 10 20824139Sjoerg#define CMD_renice 11 20924139Sjoerg#define CMD_idletog 12 21024139Sjoerg#define CMD_idletog2 13 21124139Sjoerg#define CMD_user 14 21238090Sdes#define CMD_selftog 15 213117709Sjulian#define CMD_thrtog 16 214131402Salfred#define CMD_viewtog 17 215132005Salfred#define CMD_viewsys 18 216146342Skeramida#define CMD_wcputog 19 217168710Sstas#define CMD_showargs 20 218168799Srafan#define CMD_jidtog 21 219222530Sjhb#define CMD_kidletog 22 220223936Sjhb#define CMD_pcputog 23 221266280Sbdrewery#define CMD_jail 24 22224139Sjoerg#ifdef ORDER 223266280Sbdrewery#define CMD_order 25 22424139Sjoerg#endif 22524139Sjoerg 22624139Sjoerg /* set the buffer for stdout */ 22724139Sjoerg#ifdef DEBUG 22889757Sdwmalone extern FILE *debug; 22989757Sdwmalone debug = fopen("debug.run", "w"); 23024139Sjoerg setbuffer(stdout, NULL, 0); 23124139Sjoerg#else 23224139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 23324139Sjoerg#endif 23424139Sjoerg 23524139Sjoerg /* get our name */ 23624139Sjoerg if (argc > 0) 23724139Sjoerg { 23824139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 23924139Sjoerg { 24024139Sjoerg myname = argv[0]; 24124139Sjoerg } 24224139Sjoerg else 24324139Sjoerg { 24424139Sjoerg myname++; 24524139Sjoerg } 24624139Sjoerg } 24724139Sjoerg 24824139Sjoerg /* initialize some selection options */ 24924139Sjoerg ps.idle = Yes; 25038090Sdes ps.self = -1; 25124139Sjoerg ps.system = No; 25224139Sjoerg ps.uid = -1; 253117709Sjulian ps.thread = No; 254146342Skeramida ps.wcpu = 1; 255266280Sbdrewery ps.jid = -1; 256168799Srafan ps.jail = No; 257222530Sjhb ps.kidle = Yes; 25824139Sjoerg ps.command = NULL; 25924139Sjoerg 26024139Sjoerg /* get preset options from the environment */ 26124139Sjoerg if ((env_top = getenv("TOP")) != NULL) 26224139Sjoerg { 26324139Sjoerg av = preset_argv = argparse(env_top, &preset_argc); 26424139Sjoerg ac = preset_argc; 26524139Sjoerg 26624139Sjoerg /* set the dummy argument to an explanatory message, in case 26724139Sjoerg getopt encounters a bad argument */ 26824139Sjoerg preset_argv[0] = "while processing environment"; 26924139Sjoerg } 27024139Sjoerg 27124139Sjoerg /* process options */ 27224139Sjoerg do { 27324139Sjoerg /* if we're done doing the presets, then process the real arguments */ 27424139Sjoerg if (preset_argc == 0) 27524139Sjoerg { 27624139Sjoerg ac = argc; 27724139Sjoerg av = argv; 27824139Sjoerg 27924139Sjoerg /* this should keep getopt happy... */ 28024139Sjoerg optind = 1; 28124139Sjoerg } 28224139Sjoerg 283266280Sbdrewery while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:t")) != EOF) 28424139Sjoerg { 28524139Sjoerg switch(i) 28624139Sjoerg { 28789757Sdwmalone case 'v': /* show version number */ 28889757Sdwmalone fprintf(stderr, "%s: version %s\n", 28989757Sdwmalone myname, version_string()); 29089757Sdwmalone exit(1); 29189757Sdwmalone break; 29289757Sdwmalone 29324139Sjoerg case 'u': /* toggle uid/username display */ 29424139Sjoerg do_unames = !do_unames; 29524139Sjoerg break; 29624139Sjoerg 29724139Sjoerg case 'U': /* display only username's processes */ 29824139Sjoerg if ((ps.uid = userid(optarg)) == -1) 29924139Sjoerg { 30024139Sjoerg fprintf(stderr, "%s: unknown user\n", optarg); 30124139Sjoerg exit(1); 30224139Sjoerg } 30324139Sjoerg break; 30424139Sjoerg 30524139Sjoerg case 'S': /* show system processes */ 30624139Sjoerg ps.system = !ps.system; 30724139Sjoerg break; 30824139Sjoerg 30924139Sjoerg case 'I': /* show idle processes */ 31024139Sjoerg ps.idle = !ps.idle; 31124139Sjoerg break; 31224139Sjoerg 31324139Sjoerg case 'i': /* go interactive regardless */ 31424139Sjoerg interactive = Yes; 31524139Sjoerg break; 31624139Sjoerg 31724139Sjoerg case 'n': /* batch, or non-interactive */ 31824139Sjoerg case 'b': 31924139Sjoerg interactive = No; 32024139Sjoerg break; 32124139Sjoerg 322168710Sstas case 'a': 323168710Sstas fmt_flags ^= FMT_SHOWARGS; 324168710Sstas break; 325168710Sstas 32624139Sjoerg case 'd': /* number of displays to show */ 32724139Sjoerg if ((i = atoiwi(optarg)) == Invalid || i == 0) 32824139Sjoerg { 32924139Sjoerg fprintf(stderr, 33024139Sjoerg "%s: warning: display count should be positive -- option ignored\n", 33124139Sjoerg myname); 33224139Sjoerg warnings++; 33324139Sjoerg } 33424139Sjoerg else 33524139Sjoerg { 33624139Sjoerg displays = i; 33724139Sjoerg } 33824139Sjoerg break; 33924139Sjoerg 34024139Sjoerg case 's': 34189757Sdwmalone if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) 34224139Sjoerg { 34324139Sjoerg fprintf(stderr, 34489757Sdwmalone "%s: warning: seconds delay should be positive -- using default\n", 34524139Sjoerg myname); 34624139Sjoerg delay = Default_DELAY; 34724139Sjoerg warnings++; 34824139Sjoerg } 34924139Sjoerg break; 35024139Sjoerg 35124139Sjoerg case 'q': /* be quick about it */ 35224139Sjoerg /* only allow this if user is really root */ 35324139Sjoerg if (getuid() == 0) 35424139Sjoerg { 35524139Sjoerg /* be very un-nice! */ 35624139Sjoerg (void) nice(-20); 35724139Sjoerg } 35824139Sjoerg else 35924139Sjoerg { 36024139Sjoerg fprintf(stderr, 36124139Sjoerg "%s: warning: `-q' option can only be used by root\n", 36224139Sjoerg myname); 36324139Sjoerg warnings++; 36424139Sjoerg } 36524139Sjoerg break; 36624139Sjoerg 367131616Sdes case 'm': /* select display mode */ 368131402Salfred if (strcmp(optarg, "io") == 0) { 369131402Salfred displaymode = DISP_IO; 370131402Salfred } else if (strcmp(optarg, "cpu") == 0) { 371131402Salfred displaymode = DISP_CPU; 372131402Salfred } else { 373131402Salfred fprintf(stderr, 374131402Salfred "%s: warning: `-m' option can only take args " 375131402Salfred "'io' or 'cpu'\n", 376131402Salfred myname); 377131402Salfred exit(1); 378131402Salfred } 379131402Salfred break; 380131402Salfred 38124139Sjoerg case 'o': /* select sort order */ 38224139Sjoerg#ifdef ORDER 38324139Sjoerg order_name = optarg; 38424139Sjoerg#else 38524139Sjoerg fprintf(stderr, 38624139Sjoerg "%s: this platform does not support arbitrary ordering. Sorry.\n", 38724139Sjoerg myname); 38824139Sjoerg warnings++; 38924139Sjoerg#endif 39024139Sjoerg break; 39124139Sjoerg 39238090Sdes case 't': 39338090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 39438090Sdes break; 395146342Skeramida 396146342Skeramida case 'C': 397146342Skeramida ps.wcpu = !ps.wcpu; 398146342Skeramida break; 399146342Skeramida 400117709Sjulian case 'H': 401117709Sjulian ps.thread = !ps.thread; 402117709Sjulian break; 403146342Skeramida 404168799Srafan case 'j': 405168799Srafan ps.jail = !ps.jail; 406168799Srafan break; 407168799Srafan 408266280Sbdrewery case 'J': /* display only jail's processes */ 409266280Sbdrewery if ((ps.jid = jail_getid(optarg)) == -1) 410266280Sbdrewery { 411266280Sbdrewery fprintf(stderr, "%s: unknown jail\n", optarg); 412266280Sbdrewery exit(1); 413266280Sbdrewery } 414266280Sbdrewery ps.jail = 1; 415266280Sbdrewery break; 416266280Sbdrewery 417175420Speter case 'P': 418223936Sjhb pcpu_stats = !pcpu_stats; 419175420Speter break; 420175420Speter 421222530Sjhb case 'z': 422222530Sjhb ps.kidle = !ps.kidle; 423222530Sjhb break; 424222530Sjhb 42524139Sjoerg default: 426157842Sru fprintf(stderr, 427157842Sru"Top version %s\n" 428222530Sjhb"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 429266280Sbdrewery" [-J jail] [-U username] [number]\n", 43024139Sjoerg version_string(), myname); 43124139Sjoerg exit(1); 43224139Sjoerg } 43324139Sjoerg } 43424139Sjoerg 43524139Sjoerg /* get count of top processes to display (if any) */ 43624139Sjoerg if (optind < ac) 43724139Sjoerg { 43824139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 43924139Sjoerg { 44024139Sjoerg fprintf(stderr, 44124139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 44224139Sjoerg myname); 44324139Sjoerg warnings++; 44424139Sjoerg } 44524139Sjoerg#if Default_TOPN == Infinity 44624139Sjoerg else 44724139Sjoerg { 44824139Sjoerg topn_specified = Yes; 44924139Sjoerg } 45024139Sjoerg#endif 45124139Sjoerg } 45224139Sjoerg 45324139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 45424139Sjoerg i = preset_argc; 45524139Sjoerg preset_argc = 0; 45624139Sjoerg 45724139Sjoerg /* repeat only if we really did the preset arguments */ 45824139Sjoerg } while (i != 0); 45924139Sjoerg 46024139Sjoerg /* set constants for username/uid display correctly */ 46124139Sjoerg if (!do_unames) 46224139Sjoerg { 46324139Sjoerg uname_field = " UID "; 46424139Sjoerg get_userid = itoa7; 46524139Sjoerg } 46624139Sjoerg 46724139Sjoerg /* initialize the kernel memory interface */ 468175195Sobrien if (machine_init(&statics, do_unames) == -1) 46924139Sjoerg { 47024139Sjoerg exit(1); 47124139Sjoerg } 47224139Sjoerg 47324139Sjoerg#ifdef ORDER 47424139Sjoerg /* determine sorting order index, if necessary */ 47524139Sjoerg if (order_name != NULL) 47624139Sjoerg { 47724139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 47824139Sjoerg { 47924139Sjoerg char **pp; 48024139Sjoerg 48124139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 48224139Sjoerg myname, order_name); 48324139Sjoerg fprintf(stderr, "\tTry one of these:"); 48424139Sjoerg pp = statics.order_names; 48524139Sjoerg while (*pp != NULL) 48624139Sjoerg { 48724139Sjoerg fprintf(stderr, " %s", *pp++); 48824139Sjoerg } 48924139Sjoerg fputc('\n', stderr); 49024139Sjoerg exit(1); 49124139Sjoerg } 49224139Sjoerg } 49324139Sjoerg#endif 49424139Sjoerg 49524139Sjoerg#ifdef no_initialization_needed 49624139Sjoerg /* initialize the hashing stuff */ 49724139Sjoerg if (do_unames) 49824139Sjoerg { 49924139Sjoerg init_hash(); 50024139Sjoerg } 50124139Sjoerg#endif 50224139Sjoerg 50324139Sjoerg /* initialize termcap */ 50424139Sjoerg init_termcap(interactive); 50524139Sjoerg 50624139Sjoerg /* get the string to use for the process area header */ 50724139Sjoerg header_text = format_header(uname_field); 50824139Sjoerg 50924139Sjoerg /* initialize display interface */ 51024139Sjoerg if ((max_topn = display_init(&statics)) == -1) 51124139Sjoerg { 51224139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 51324139Sjoerg exit(4); 51424139Sjoerg } 51524139Sjoerg 51624139Sjoerg /* print warning if user requested more processes than we can display */ 51724139Sjoerg if (topn > max_topn) 51824139Sjoerg { 51924139Sjoerg fprintf(stderr, 52024139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 52124139Sjoerg myname, max_topn); 52224139Sjoerg warnings++; 52324139Sjoerg } 52424139Sjoerg 52524139Sjoerg /* adjust for topn == Infinity */ 52624139Sjoerg if (topn == Infinity) 52724139Sjoerg { 52824139Sjoerg /* 52924139Sjoerg * For smart terminals, infinity really means everything that can 53024139Sjoerg * be displayed, or Largest. 53124139Sjoerg * On dumb terminals, infinity means every process in the system! 53224139Sjoerg * We only really want to do that if it was explicitly specified. 53324139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 53424139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 53524139Sjoerg * and the default is Infinity, then (and only then) we use 53624139Sjoerg * "Nominal_TOPN" instead. 53724139Sjoerg */ 53824139Sjoerg#if Default_TOPN == Infinity 53924139Sjoerg topn = smart_terminal ? Largest : 54024139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 54124139Sjoerg#else 54224139Sjoerg topn = Largest; 54324139Sjoerg#endif 54424139Sjoerg } 54524139Sjoerg 54624139Sjoerg /* set header display accordingly */ 54724139Sjoerg display_header(topn > 0); 54824139Sjoerg 54924139Sjoerg /* determine interactive state */ 55024139Sjoerg if (interactive == Maybe) 55124139Sjoerg { 55224139Sjoerg interactive = smart_terminal; 55324139Sjoerg } 55424139Sjoerg 55524139Sjoerg /* if # of displays not specified, fill it in */ 55624139Sjoerg if (displays == 0) 55724139Sjoerg { 55824139Sjoerg displays = smart_terminal ? Infinity : 1; 55924139Sjoerg } 56024139Sjoerg 56124139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 56224139Sjoerg#ifdef SIGHOLD 56324139Sjoerg sighold(SIGINT); 56424139Sjoerg sighold(SIGQUIT); 56524139Sjoerg sighold(SIGTSTP); 56624139Sjoerg#else 56724139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 56824139Sjoerg#endif 56924139Sjoerg init_screen(); 57024139Sjoerg (void) signal(SIGINT, leave); 57124139Sjoerg (void) signal(SIGQUIT, leave); 57224139Sjoerg (void) signal(SIGTSTP, tstop); 57324139Sjoerg#ifdef SIGWINCH 57424139Sjoerg (void) signal(SIGWINCH, winch); 57524139Sjoerg#endif 57624139Sjoerg#ifdef SIGRELSE 57724139Sjoerg sigrelse(SIGINT); 57824139Sjoerg sigrelse(SIGQUIT); 57924139Sjoerg sigrelse(SIGTSTP); 58024139Sjoerg#else 58124139Sjoerg (void) sigsetmask(old_sigmask); 58224139Sjoerg#endif 58324139Sjoerg if (warnings) 58424139Sjoerg { 58524139Sjoerg fputs("....", stderr); 58624139Sjoerg fflush(stderr); /* why must I do this? */ 58724139Sjoerg sleep((unsigned)(3 * warnings)); 58824139Sjoerg fputc('\n', stderr); 58924139Sjoerg } 59024139Sjoerg 59181187Skrisrestart: 59224139Sjoerg 59324139Sjoerg /* 59424139Sjoerg * main loop -- repeat while display count is positive or while it 59524139Sjoerg * indicates infinity (by being -1) 59624139Sjoerg */ 59724139Sjoerg 59824139Sjoerg while ((displays == -1) || (displays-- > 0)) 59924139Sjoerg { 600131402Salfred int (*compare)(); 601131402Salfred 602131402Salfred 60324139Sjoerg /* get the current stats */ 60424139Sjoerg get_system_info(&system_info); 60524139Sjoerg 60624139Sjoerg#ifdef ORDER 607133817Salfred compare = compares[order_index]; 60824139Sjoerg#else 609131829Skeramida if (displaymode == DISP_CPU) 610131402Salfred compare = proc_compare; 611131829Skeramida else 612131829Skeramida compare = io_compare; 61324139Sjoerg#endif 61424139Sjoerg 615131402Salfred /* get the current set of processes */ 616131402Salfred processes = 617131402Salfred get_process_info(&system_info, &ps, compare); 618131402Salfred 61924139Sjoerg /* display the load averages */ 62024139Sjoerg (*d_loadave)(system_info.last_pid, 62124139Sjoerg system_info.load_avg); 62224139Sjoerg 62324139Sjoerg /* display the current time */ 62424139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 62524139Sjoerg time(&curr_time); 62642447Sobrien i_uptime(&system_info.boottime, &curr_time); 62724139Sjoerg i_timeofday(&curr_time); 62824139Sjoerg 62924139Sjoerg /* display process state breakdown */ 63024139Sjoerg (*d_procstates)(system_info.p_total, 63124139Sjoerg system_info.procstates); 63224139Sjoerg 63324139Sjoerg /* display the cpu state percentage breakdown */ 63424139Sjoerg if (dostates) /* but not the first time */ 63524139Sjoerg { 63624139Sjoerg (*d_cpustates)(system_info.cpustates); 63724139Sjoerg } 63824139Sjoerg else 63924139Sjoerg { 64024139Sjoerg /* we'll do it next time */ 64124139Sjoerg if (smart_terminal) 64224139Sjoerg { 64324139Sjoerg z_cpustates(); 64424139Sjoerg } 64524139Sjoerg else 64624139Sjoerg { 64724139Sjoerg putchar('\n'); 64824139Sjoerg } 64924139Sjoerg dostates = Yes; 65024139Sjoerg } 65124139Sjoerg 65224139Sjoerg /* display memory stats */ 65324139Sjoerg (*d_memory)(system_info.memory); 654237656Sjhb (*d_arc)(system_info.arc); 65524139Sjoerg 65624142Sjoerg /* display swap stats */ 65724142Sjoerg (*d_swap)(system_info.swap); 65824142Sjoerg 65924139Sjoerg /* handle message area */ 66024139Sjoerg (*d_message)(); 66124139Sjoerg 66224139Sjoerg /* update the header area */ 66324139Sjoerg (*d_header)(header_text); 66424139Sjoerg 66524139Sjoerg if (topn > 0) 66624139Sjoerg { 66724139Sjoerg /* determine number of processes to actually display */ 66824139Sjoerg /* this number will be the smallest of: active processes, 66924139Sjoerg number user requested, number current screen accomodates */ 67089757Sdwmalone active_procs = system_info.P_ACTIVE; 67124139Sjoerg if (active_procs > topn) 67224139Sjoerg { 67324139Sjoerg active_procs = topn; 67424139Sjoerg } 67524139Sjoerg if (active_procs > max_topn) 67624139Sjoerg { 67724139Sjoerg active_procs = max_topn; 67824139Sjoerg } 67924139Sjoerg 68024139Sjoerg /* now show the top "n" processes. */ 68124139Sjoerg for (i = 0; i < active_procs; i++) 68224139Sjoerg { 683168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 684168710Sstas fmt_flags)); 68524139Sjoerg } 68624139Sjoerg } 68724139Sjoerg else 68824139Sjoerg { 68924139Sjoerg i = 0; 69024139Sjoerg } 69124139Sjoerg 69224139Sjoerg /* do end-screen processing */ 69324139Sjoerg u_endscreen(i); 69424139Sjoerg 69524139Sjoerg /* now, flush the output buffer */ 69689757Sdwmalone if (fflush(stdout) != 0) 69789757Sdwmalone { 69889757Sdwmalone new_message(MT_standout, " Write error on stdout"); 69989757Sdwmalone putchar('\r'); 70089757Sdwmalone quit(1); 70189757Sdwmalone /*NOTREACHED*/ 70289757Sdwmalone } 70324139Sjoerg 70424139Sjoerg /* only do the rest if we have more displays to show */ 70524139Sjoerg if (displays) 70624139Sjoerg { 70724139Sjoerg /* switch out for new display on smart terminals */ 70824139Sjoerg if (smart_terminal) 70924139Sjoerg { 71024139Sjoerg if (overstrike) 71124139Sjoerg { 71224139Sjoerg reset_display(); 71324139Sjoerg } 71424139Sjoerg else 71524139Sjoerg { 71624139Sjoerg d_loadave = u_loadave; 71724139Sjoerg d_procstates = u_procstates; 71824139Sjoerg d_cpustates = u_cpustates; 71924139Sjoerg d_memory = u_memory; 720237656Sjhb d_arc = u_arc; 72124142Sjoerg d_swap = u_swap; 72224139Sjoerg d_message = u_message; 72324139Sjoerg d_header = u_header; 72424139Sjoerg d_process = u_process; 72524139Sjoerg } 72624139Sjoerg } 72724139Sjoerg 72824139Sjoerg no_command = Yes; 72924139Sjoerg if (!interactive) 73024139Sjoerg { 731232239Skib sleep(delay); 732232660Skib if (leaveflag) { 733232660Skib end_screen(); 734232660Skib exit(0); 735232660Skib } 73624139Sjoerg } 73724139Sjoerg else while (no_command) 73824139Sjoerg { 73924139Sjoerg /* assume valid command unless told otherwise */ 74024139Sjoerg no_command = No; 74124139Sjoerg 74224139Sjoerg /* set up arguments for select with timeout */ 74324139Sjoerg FD_ZERO(&readfds); 74489757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 74524139Sjoerg timeout.tv_sec = delay; 74624139Sjoerg timeout.tv_usec = 0; 74724139Sjoerg 74881187Skris if (leaveflag) { 74981187Skris end_screen(); 75081187Skris exit(0); 75181187Skris } 75281187Skris 75381187Skris if (tstopflag) { 75481187Skris /* move to the lower left */ 75581187Skris end_screen(); 75681187Skris fflush(stdout); 75781187Skris 75881187Skris /* default the signal handler action */ 75981187Skris (void) signal(SIGTSTP, SIG_DFL); 76081187Skris 76181187Skris /* unblock the signal and send ourselves one */ 76281187Skris#ifdef SIGRELSE 76381187Skris sigrelse(SIGTSTP); 76481187Skris#else 76581187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 76681187Skris#endif 76781187Skris (void) kill(0, SIGTSTP); 76881187Skris 76981187Skris /* reset the signal handler */ 77081187Skris (void) signal(SIGTSTP, tstop); 77181187Skris 77281187Skris /* reinit screen */ 77381187Skris reinit_screen(); 77481187Skris reset_display(); 77581187Skris tstopflag = 0; 77681187Skris goto restart; 77781187Skris } 77881187Skris 77981187Skris if (winchflag) { 78081187Skris /* reascertain the screen dimensions */ 78181187Skris get_screensize(); 78281187Skris 78381187Skris /* tell display to resize */ 78481187Skris max_topn = display_resize(); 78581187Skris 78681187Skris /* reset the signal handler */ 78781187Skris (void) signal(SIGWINCH, winch); 78881187Skris 78981187Skris reset_display(); 79081187Skris winchflag = 0; 79181187Skris goto restart; 79281187Skris } 79381187Skris 79424139Sjoerg /* wait for either input or the end of the delay period */ 79586042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 79686042Sdwmalone if (sel_ret < 0 && errno != EINTR) 79786042Sdwmalone quit(0); 79886042Sdwmalone if (sel_ret > 0) 79924139Sjoerg { 80024139Sjoerg int newval; 80124139Sjoerg char *errmsg; 80224139Sjoerg 80324139Sjoerg /* something to read -- clear the message area first */ 80424139Sjoerg clear_message(); 80524139Sjoerg 80624139Sjoerg /* now read it and convert to command strchr */ 80724139Sjoerg /* (use "change" as a temporary to hold strchr) */ 80886042Sdwmalone if (read(0, &ch, 1) != 1) 80989757Sdwmalone { 81089757Sdwmalone /* read error: either 0 or -1 */ 81189757Sdwmalone new_message(MT_standout, " Read error on stdin"); 81289757Sdwmalone putchar('\r'); 81389757Sdwmalone quit(1); 81489757Sdwmalone /*NOTREACHED*/ 81589757Sdwmalone } 81624139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 81724139Sjoerg { 81824142Sjoerg if (ch != '\r' && ch != '\n') 81924142Sjoerg { 82024142Sjoerg /* illegal command */ 82124142Sjoerg new_message(MT_standout, " Command not understood"); 82224142Sjoerg } 82324139Sjoerg putchar('\r'); 82424139Sjoerg no_command = Yes; 82524139Sjoerg } 82624139Sjoerg else 82724139Sjoerg { 82824139Sjoerg change = iptr - command_chars; 82924139Sjoerg if (overstrike && change > CMD_OSLIMIT) 83024139Sjoerg { 83124139Sjoerg /* error */ 83224139Sjoerg new_message(MT_standout, 83324139Sjoerg " Command cannot be handled by this terminal"); 83424139Sjoerg putchar('\r'); 83524139Sjoerg no_command = Yes; 83624139Sjoerg } 83724139Sjoerg else switch(change) 83824139Sjoerg { 83924139Sjoerg case CMD_redraw: /* redraw screen */ 84024139Sjoerg reset_display(); 84124139Sjoerg break; 84224139Sjoerg 84324139Sjoerg case CMD_update: /* merely update display */ 84424139Sjoerg /* is the load average high? */ 84524139Sjoerg if (system_info.load_avg[0] > LoadMax) 84624139Sjoerg { 84724139Sjoerg /* yes, go home for visual feedback */ 84824139Sjoerg go_home(); 84924139Sjoerg fflush(stdout); 85024139Sjoerg } 85124139Sjoerg break; 85224139Sjoerg 85324139Sjoerg case CMD_quit: /* quit */ 85424139Sjoerg quit(0); 85524139Sjoerg /*NOTREACHED*/ 85624139Sjoerg break; 85724139Sjoerg 85824139Sjoerg case CMD_help1: /* help */ 85924139Sjoerg case CMD_help2: 86024139Sjoerg reset_display(); 86124139Sjoerg clear(); 86224139Sjoerg show_help(); 86324139Sjoerg standout("Hit any key to continue: "); 86424139Sjoerg fflush(stdout); 86524139Sjoerg (void) read(0, &ch, 1); 86624139Sjoerg break; 86724139Sjoerg 86824139Sjoerg case CMD_errors: /* show errors */ 86924139Sjoerg if (error_count() == 0) 87024139Sjoerg { 87124139Sjoerg new_message(MT_standout, 87224139Sjoerg " Currently no errors to report."); 87324139Sjoerg putchar('\r'); 87424139Sjoerg no_command = Yes; 87524139Sjoerg } 87624139Sjoerg else 87724139Sjoerg { 87824139Sjoerg reset_display(); 87924139Sjoerg clear(); 88024139Sjoerg show_errors(); 88124139Sjoerg standout("Hit any key to continue: "); 88224139Sjoerg fflush(stdout); 88324139Sjoerg (void) read(0, &ch, 1); 88424139Sjoerg } 88524139Sjoerg break; 88624139Sjoerg 88724139Sjoerg case CMD_number1: /* new number */ 88824139Sjoerg case CMD_number2: 88924139Sjoerg new_message(MT_standout, 89024139Sjoerg "Number of processes to show: "); 89124139Sjoerg newval = readline(tempbuf1, 8, Yes); 89224139Sjoerg if (newval > -1) 89324139Sjoerg { 89424139Sjoerg if (newval > max_topn) 89524139Sjoerg { 89624139Sjoerg new_message(MT_standout | MT_delayed, 89724139Sjoerg " This terminal can only display %d processes.", 89824139Sjoerg max_topn); 89924139Sjoerg putchar('\r'); 90024139Sjoerg } 90124139Sjoerg 90224139Sjoerg if (newval == 0) 90324139Sjoerg { 90424139Sjoerg /* inhibit the header */ 90524139Sjoerg display_header(No); 90624139Sjoerg } 90724139Sjoerg else if (newval > topn && topn == 0) 90824139Sjoerg { 90924139Sjoerg /* redraw the header */ 91024139Sjoerg display_header(Yes); 91124139Sjoerg d_header = i_header; 91224139Sjoerg } 91324139Sjoerg topn = newval; 91424139Sjoerg } 91524139Sjoerg break; 91624139Sjoerg 91724139Sjoerg case CMD_delay: /* new seconds delay */ 91824139Sjoerg new_message(MT_standout, "Seconds to delay: "); 91924139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 92024139Sjoerg { 92189757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 92289757Sdwmalone { 92389757Sdwmalone delay = 1; 92489757Sdwmalone } 92524139Sjoerg } 92624139Sjoerg clear_message(); 92724139Sjoerg break; 92824139Sjoerg 92924139Sjoerg case CMD_displays: /* change display count */ 93024139Sjoerg new_message(MT_standout, 93124139Sjoerg "Displays to show (currently %s): ", 93224139Sjoerg displays == -1 ? "infinite" : 93324139Sjoerg itoa(displays)); 93424139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 93524139Sjoerg { 93624139Sjoerg displays = i; 93724139Sjoerg } 93824139Sjoerg else if (i == 0) 93924139Sjoerg { 94024139Sjoerg quit(0); 94124139Sjoerg } 94224139Sjoerg clear_message(); 94324139Sjoerg break; 94424139Sjoerg 94524139Sjoerg case CMD_kill: /* kill program */ 94624139Sjoerg new_message(0, "kill "); 94724139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 94824139Sjoerg { 94924139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 95024139Sjoerg { 95166641Simp new_message(MT_standout, "%s", errmsg); 95224139Sjoerg putchar('\r'); 95324139Sjoerg no_command = Yes; 95424139Sjoerg } 95524139Sjoerg } 95624139Sjoerg else 95724139Sjoerg { 95824139Sjoerg clear_message(); 95924139Sjoerg } 96024139Sjoerg break; 96124139Sjoerg 96224139Sjoerg case CMD_renice: /* renice program */ 96324139Sjoerg new_message(0, "renice "); 96424139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 96524139Sjoerg { 96624139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 96724139Sjoerg { 96868293Simp new_message(MT_standout, "%s", errmsg); 96924139Sjoerg putchar('\r'); 97024139Sjoerg no_command = Yes; 97124139Sjoerg } 97224139Sjoerg } 97324139Sjoerg else 97424139Sjoerg { 97524139Sjoerg clear_message(); 97624139Sjoerg } 97724139Sjoerg break; 97824139Sjoerg 97924139Sjoerg case CMD_idletog: 98024139Sjoerg case CMD_idletog2: 98124139Sjoerg ps.idle = !ps.idle; 98224139Sjoerg new_message(MT_standout | MT_delayed, 98324139Sjoerg " %sisplaying idle processes.", 98424139Sjoerg ps.idle ? "D" : "Not d"); 98524139Sjoerg putchar('\r'); 98624139Sjoerg break; 98724139Sjoerg 98838090Sdes case CMD_selftog: 98938090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 99038090Sdes new_message(MT_standout | MT_delayed, 99138090Sdes " %sisplaying self.", 99238090Sdes (ps.self == -1) ? "D" : "Not d"); 99338090Sdes putchar('\r'); 99438090Sdes break; 99538090Sdes 99624139Sjoerg case CMD_user: 99724139Sjoerg new_message(MT_standout, 998266280Sbdrewery "Username to show (+ for all): "); 99924139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 100024139Sjoerg { 100124139Sjoerg if (tempbuf2[0] == '+' && 100224139Sjoerg tempbuf2[1] == '\0') 100324139Sjoerg { 100424139Sjoerg ps.uid = -1; 100524139Sjoerg } 100624139Sjoerg else if ((i = userid(tempbuf2)) == -1) 100724139Sjoerg { 100824139Sjoerg new_message(MT_standout, 100924139Sjoerg " %s: unknown user", tempbuf2); 101024139Sjoerg no_command = Yes; 101124139Sjoerg } 101224139Sjoerg else 101324139Sjoerg { 101424139Sjoerg ps.uid = i; 101524139Sjoerg } 101624139Sjoerg putchar('\r'); 101724139Sjoerg } 101824139Sjoerg else 101924139Sjoerg { 102024139Sjoerg clear_message(); 102124139Sjoerg } 102224139Sjoerg break; 102324139Sjoerg 1024117709Sjulian case CMD_thrtog: 1025117709Sjulian ps.thread = !ps.thread; 1026117709Sjulian new_message(MT_standout | MT_delayed, 1027223937Sjhb " Displaying threads %s", 1028145073Skeramida ps.thread ? "separately" : "as a count"); 1029145073Skeramida header_text = format_header(uname_field); 1030145073Skeramida reset_display(); 1031117709Sjulian putchar('\r'); 1032117709Sjulian break; 1033146342Skeramida case CMD_wcputog: 1034146342Skeramida ps.wcpu = !ps.wcpu; 1035146342Skeramida new_message(MT_standout | MT_delayed, 1036224204Sjhb " Displaying %s CPU", 1037224204Sjhb ps.wcpu ? "weighted" : "raw"); 1038146342Skeramida header_text = format_header(uname_field); 1039146342Skeramida reset_display(); 1040146342Skeramida putchar('\r'); 1041146342Skeramida break; 1042131402Salfred case CMD_viewtog: 1043131402Salfred if (++displaymode == DISP_MAX) 1044131402Salfred displaymode = 0; 1045131402Salfred header_text = format_header(uname_field); 1046131402Salfred display_header(Yes); 1047131402Salfred d_header = i_header; 1048131402Salfred reset_display(); 1049131402Salfred break; 1050132005Salfred case CMD_viewsys: 1051132005Salfred ps.system = !ps.system; 1052132005Salfred break; 1053168710Sstas case CMD_showargs: 1054168710Sstas fmt_flags ^= FMT_SHOWARGS; 1055168710Sstas break; 105624139Sjoerg#ifdef ORDER 105724139Sjoerg case CMD_order: 105824139Sjoerg new_message(MT_standout, 105924139Sjoerg "Order to sort: "); 106024139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 106124139Sjoerg { 106224139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 106324139Sjoerg { 106424139Sjoerg new_message(MT_standout, 106524139Sjoerg " %s: unrecognized sorting order", tempbuf2); 106624139Sjoerg no_command = Yes; 106724139Sjoerg } 106824139Sjoerg else 106924139Sjoerg { 107024139Sjoerg order_index = i; 107124139Sjoerg } 107224139Sjoerg putchar('\r'); 107324139Sjoerg } 107424139Sjoerg else 107524139Sjoerg { 107624139Sjoerg clear_message(); 107724139Sjoerg } 107824139Sjoerg break; 107924139Sjoerg#endif 1080168799Srafan case CMD_jidtog: 1081168799Srafan ps.jail = !ps.jail; 1082168799Srafan new_message(MT_standout | MT_delayed, 1083169257Srafan " %sisplaying jail ID.", 1084168799Srafan ps.jail ? "D" : "Not d"); 1085168799Srafan header_text = format_header(uname_field); 1086168799Srafan reset_display(); 1087168799Srafan putchar('\r'); 1088168799Srafan break; 1089266280Sbdrewery 1090266280Sbdrewery case CMD_jail: 1091266280Sbdrewery new_message(MT_standout, 1092266280Sbdrewery "Jail to show (+ for all): "); 1093266280Sbdrewery if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 1094266280Sbdrewery { 1095266280Sbdrewery if (tempbuf2[0] == '+' && 1096266280Sbdrewery tempbuf2[1] == '\0') 1097266280Sbdrewery { 1098266280Sbdrewery ps.jid = -1; 1099266280Sbdrewery } 1100266280Sbdrewery else if ((i = jail_getid(tempbuf2)) == -1) 1101266280Sbdrewery { 1102266280Sbdrewery new_message(MT_standout, 1103266280Sbdrewery " %s: unknown jail", tempbuf2); 1104266280Sbdrewery no_command = Yes; 1105266280Sbdrewery } 1106266280Sbdrewery else 1107266280Sbdrewery { 1108266280Sbdrewery ps.jid = i; 1109266280Sbdrewery } 1110266280Sbdrewery if (ps.jail == 0) { 1111266280Sbdrewery ps.jail = 1; 1112266280Sbdrewery new_message(MT_standout | 1113266280Sbdrewery MT_delayed, " Displaying jail " 1114266280Sbdrewery "ID."); 1115266280Sbdrewery header_text = 1116266280Sbdrewery format_header(uname_field); 1117266280Sbdrewery reset_display(); 1118266280Sbdrewery } 1119266280Sbdrewery putchar('\r'); 1120266280Sbdrewery } 1121266280Sbdrewery else 1122266280Sbdrewery { 1123266280Sbdrewery clear_message(); 1124266280Sbdrewery } 1125266280Sbdrewery break; 1126266280Sbdrewery 1127222530Sjhb case CMD_kidletog: 1128222530Sjhb ps.kidle = !ps.kidle; 1129222530Sjhb new_message(MT_standout | MT_delayed, 1130222530Sjhb " %sisplaying system idle process.", 1131222530Sjhb ps.kidle ? "D" : "Not d"); 1132222530Sjhb putchar('\r'); 1133222530Sjhb break; 1134223936Sjhb case CMD_pcputog: 1135223936Sjhb pcpu_stats = !pcpu_stats; 1136223936Sjhb new_message(MT_standout | MT_delayed, 1137223936Sjhb " Displaying %sCPU statistics.", 1138223936Sjhb pcpu_stats ? "per-" : "global "); 1139224205Sjhb toggle_pcpustats(); 1140223936Sjhb max_topn = display_updatecpus(&statics); 1141223936Sjhb reset_display(); 1142223936Sjhb putchar('\r'); 1143223936Sjhb break; 114424139Sjoerg default: 114524139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 114624139Sjoerg putchar('\r'); 114724139Sjoerg } 114824139Sjoerg } 114924139Sjoerg 115024139Sjoerg /* flush out stuff that may have been written */ 115124139Sjoerg fflush(stdout); 115224139Sjoerg } 115324139Sjoerg } 115424139Sjoerg } 115524139Sjoerg } 115624139Sjoerg 115789757Sdwmalone#ifdef DEBUG 115889757Sdwmalone fclose(debug); 115989757Sdwmalone#endif 116024139Sjoerg quit(0); 116124139Sjoerg /*NOTREACHED*/ 116224139Sjoerg} 116324139Sjoerg 116424139Sjoerg/* 116524139Sjoerg * reset_display() - reset all the display routine pointers so that entire 116624139Sjoerg * screen will get redrawn. 116724139Sjoerg */ 116824139Sjoerg 1169301836Sngievoid 117024139Sjoergreset_display() 117124139Sjoerg 117224139Sjoerg{ 117324139Sjoerg d_loadave = i_loadave; 117424139Sjoerg d_procstates = i_procstates; 117524139Sjoerg d_cpustates = i_cpustates; 117624139Sjoerg d_memory = i_memory; 1177237656Sjhb d_arc = i_arc; 117824142Sjoerg d_swap = i_swap; 117924139Sjoerg d_message = i_message; 118024139Sjoerg d_header = i_header; 118124139Sjoerg d_process = i_process; 118224139Sjoerg} 118324139Sjoerg 118424139Sjoerg/* 118524139Sjoerg * signal handlers 118624139Sjoerg */ 118724139Sjoerg 118824139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 118924139Sjoerg 119024139Sjoerg{ 119181187Skris leaveflag = 1; 119224139Sjoerg} 119324139Sjoerg 119424139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 119524139Sjoerg 119624139Sjoergint i; 119724139Sjoerg 119824139Sjoerg{ 119981187Skris tstopflag = 1; 120024139Sjoerg} 120124139Sjoerg 120224139Sjoerg#ifdef SIGWINCH 120324139Sjoergsigret_t winch(i) /* SIGWINCH handler */ 120424139Sjoerg 120524139Sjoergint i; 120624139Sjoerg 120724139Sjoerg{ 120881187Skris winchflag = 1; 120924139Sjoerg} 121024139Sjoerg#endif 121124139Sjoerg 121224139Sjoergvoid quit(status) /* exit under duress */ 121324139Sjoerg 121424139Sjoergint status; 121524139Sjoerg 121624139Sjoerg{ 121724139Sjoerg end_screen(); 121824139Sjoerg exit(status); 121924139Sjoerg /*NOTREACHED*/ 122024139Sjoerg} 1221