top.c revision 307757
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: stable/11/contrib/top/top.c 307757 2016-10-22 00:35:40Z des $ 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" 37300395Sngie 38265249Sbdrewery#include <sys/jail.h> 3924139Sjoerg#include <sys/time.h> 40300395Sngie 41300395Sngie#include <ctype.h> 42300395Sngie#include <errno.h> 43265249Sbdrewery#include <jail.h> 44300395Sngie#include <setjmp.h> 45300395Sngie#include <signal.h> 46300395Sngie#include <unistd.h> 4724139Sjoerg 4824139Sjoerg/* includes specific to top */ 49300395Sngie#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" 57300395Sngie#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 */ 123300395Sngievoid (*d_loadave)() = i_loadave; 124300395Sngievoid (*d_procstates)() = i_procstates; 125300395Sngievoid (*d_cpustates)() = i_cpustates; 126300395Sngievoid (*d_memory)() = i_memory; 127300395Sngievoid (*d_arc)() = i_arc; 128300395Sngievoid (*d_swap)() = i_swap; 129300395Sngievoid (*d_message)() = i_message; 130300395Sngievoid (*d_header)() = i_header; 131300395Sngievoid (*d_process)() = i_process; 13224139Sjoerg 133300395Sngievoid reset_display(void); 13424139Sjoerg 135300395Sngie 136300395Sngieint 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 191307757Sdes static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwo"; 19224139Sjoerg#else 193307757Sdes static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJw"; 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 221265249Sbdrewery#define CMD_jail 24 222307757Sdes#define CMD_swaptog 25 22324139Sjoerg#ifdef ORDER 224307757Sdes#define CMD_order 26 22524139Sjoerg#endif 22624139Sjoerg 22724139Sjoerg /* set the buffer for stdout */ 22824139Sjoerg#ifdef DEBUG 22989757Sdwmalone extern FILE *debug; 23089757Sdwmalone debug = fopen("debug.run", "w"); 23124139Sjoerg setbuffer(stdout, NULL, 0); 23224139Sjoerg#else 23324139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 23424139Sjoerg#endif 23524139Sjoerg 23624139Sjoerg /* get our name */ 23724139Sjoerg if (argc > 0) 23824139Sjoerg { 23924139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 24024139Sjoerg { 24124139Sjoerg myname = argv[0]; 24224139Sjoerg } 24324139Sjoerg else 24424139Sjoerg { 24524139Sjoerg myname++; 24624139Sjoerg } 24724139Sjoerg } 24824139Sjoerg 24924139Sjoerg /* initialize some selection options */ 25024139Sjoerg ps.idle = Yes; 25138090Sdes ps.self = -1; 25224139Sjoerg ps.system = No; 25324139Sjoerg ps.uid = -1; 254117709Sjulian ps.thread = No; 255146342Skeramida ps.wcpu = 1; 256265249Sbdrewery ps.jid = -1; 257168799Srafan ps.jail = No; 258307757Sdes ps.swap = No; 259222530Sjhb ps.kidle = Yes; 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 285307757Sdes while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:tw")) != 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 410265249Sbdrewery case 'J': /* display only jail's processes */ 411265249Sbdrewery if ((ps.jid = jail_getid(optarg)) == -1) 412265249Sbdrewery { 413265249Sbdrewery fprintf(stderr, "%s: unknown jail\n", optarg); 414265249Sbdrewery exit(1); 415265249Sbdrewery } 416265249Sbdrewery ps.jail = 1; 417265249Sbdrewery break; 418265249Sbdrewery 419175420Speter case 'P': 420223936Sjhb pcpu_stats = !pcpu_stats; 421175420Speter break; 422175420Speter 423307757Sdes case 'w': 424307757Sdes ps.swap = 1; 425307757Sdes break; 426307757Sdes 427222530Sjhb case 'z': 428222530Sjhb ps.kidle = !ps.kidle; 429222530Sjhb break; 430222530Sjhb 43124139Sjoerg default: 432157842Sru fprintf(stderr, 433157842Sru"Top version %s\n" 434222530Sjhb"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 435265249Sbdrewery" [-J jail] [-U username] [number]\n", 43624139Sjoerg version_string(), myname); 43724139Sjoerg exit(1); 43824139Sjoerg } 43924139Sjoerg } 44024139Sjoerg 44124139Sjoerg /* get count of top processes to display (if any) */ 44224139Sjoerg if (optind < ac) 44324139Sjoerg { 44424139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 44524139Sjoerg { 44624139Sjoerg fprintf(stderr, 44724139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 44824139Sjoerg myname); 44924139Sjoerg warnings++; 45024139Sjoerg } 45124139Sjoerg#if Default_TOPN == Infinity 45224139Sjoerg else 45324139Sjoerg { 45424139Sjoerg topn_specified = Yes; 45524139Sjoerg } 45624139Sjoerg#endif 45724139Sjoerg } 45824139Sjoerg 45924139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 46024139Sjoerg i = preset_argc; 46124139Sjoerg preset_argc = 0; 46224139Sjoerg 46324139Sjoerg /* repeat only if we really did the preset arguments */ 46424139Sjoerg } while (i != 0); 46524139Sjoerg 46624139Sjoerg /* set constants for username/uid display correctly */ 46724139Sjoerg if (!do_unames) 46824139Sjoerg { 46924139Sjoerg uname_field = " UID "; 47024139Sjoerg get_userid = itoa7; 47124139Sjoerg } 47224139Sjoerg 47324139Sjoerg /* initialize the kernel memory interface */ 474175195Sobrien if (machine_init(&statics, do_unames) == -1) 47524139Sjoerg { 47624139Sjoerg exit(1); 47724139Sjoerg } 47824139Sjoerg 47924139Sjoerg#ifdef ORDER 48024139Sjoerg /* determine sorting order index, if necessary */ 48124139Sjoerg if (order_name != NULL) 48224139Sjoerg { 48324139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 48424139Sjoerg { 48524139Sjoerg char **pp; 48624139Sjoerg 48724139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 48824139Sjoerg myname, order_name); 48924139Sjoerg fprintf(stderr, "\tTry one of these:"); 49024139Sjoerg pp = statics.order_names; 49124139Sjoerg while (*pp != NULL) 49224139Sjoerg { 49324139Sjoerg fprintf(stderr, " %s", *pp++); 49424139Sjoerg } 49524139Sjoerg fputc('\n', stderr); 49624139Sjoerg exit(1); 49724139Sjoerg } 49824139Sjoerg } 49924139Sjoerg#endif 50024139Sjoerg 50124139Sjoerg#ifdef no_initialization_needed 50224139Sjoerg /* initialize the hashing stuff */ 50324139Sjoerg if (do_unames) 50424139Sjoerg { 50524139Sjoerg init_hash(); 50624139Sjoerg } 50724139Sjoerg#endif 50824139Sjoerg 50924139Sjoerg /* initialize termcap */ 51024139Sjoerg init_termcap(interactive); 51124139Sjoerg 51224139Sjoerg /* get the string to use for the process area header */ 51324139Sjoerg header_text = format_header(uname_field); 51424139Sjoerg 51524139Sjoerg /* initialize display interface */ 51624139Sjoerg if ((max_topn = display_init(&statics)) == -1) 51724139Sjoerg { 51824139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 51924139Sjoerg exit(4); 52024139Sjoerg } 52124139Sjoerg 52224139Sjoerg /* print warning if user requested more processes than we can display */ 52324139Sjoerg if (topn > max_topn) 52424139Sjoerg { 52524139Sjoerg fprintf(stderr, 52624139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 52724139Sjoerg myname, max_topn); 52824139Sjoerg warnings++; 52924139Sjoerg } 53024139Sjoerg 53124139Sjoerg /* adjust for topn == Infinity */ 53224139Sjoerg if (topn == Infinity) 53324139Sjoerg { 53424139Sjoerg /* 53524139Sjoerg * For smart terminals, infinity really means everything that can 53624139Sjoerg * be displayed, or Largest. 53724139Sjoerg * On dumb terminals, infinity means every process in the system! 53824139Sjoerg * We only really want to do that if it was explicitly specified. 53924139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 54024139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 54124139Sjoerg * and the default is Infinity, then (and only then) we use 54224139Sjoerg * "Nominal_TOPN" instead. 54324139Sjoerg */ 54424139Sjoerg#if Default_TOPN == Infinity 54524139Sjoerg topn = smart_terminal ? Largest : 54624139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 54724139Sjoerg#else 54824139Sjoerg topn = Largest; 54924139Sjoerg#endif 55024139Sjoerg } 55124139Sjoerg 55224139Sjoerg /* set header display accordingly */ 55324139Sjoerg display_header(topn > 0); 55424139Sjoerg 55524139Sjoerg /* determine interactive state */ 55624139Sjoerg if (interactive == Maybe) 55724139Sjoerg { 55824139Sjoerg interactive = smart_terminal; 55924139Sjoerg } 56024139Sjoerg 56124139Sjoerg /* if # of displays not specified, fill it in */ 56224139Sjoerg if (displays == 0) 56324139Sjoerg { 56424139Sjoerg displays = smart_terminal ? Infinity : 1; 56524139Sjoerg } 56624139Sjoerg 56724139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 56824139Sjoerg#ifdef SIGHOLD 56924139Sjoerg sighold(SIGINT); 57024139Sjoerg sighold(SIGQUIT); 57124139Sjoerg sighold(SIGTSTP); 57224139Sjoerg#else 57324139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 57424139Sjoerg#endif 57524139Sjoerg init_screen(); 57624139Sjoerg (void) signal(SIGINT, leave); 57724139Sjoerg (void) signal(SIGQUIT, leave); 57824139Sjoerg (void) signal(SIGTSTP, tstop); 57924139Sjoerg#ifdef SIGWINCH 58024139Sjoerg (void) signal(SIGWINCH, winch); 58124139Sjoerg#endif 58224139Sjoerg#ifdef SIGRELSE 58324139Sjoerg sigrelse(SIGINT); 58424139Sjoerg sigrelse(SIGQUIT); 58524139Sjoerg sigrelse(SIGTSTP); 58624139Sjoerg#else 58724139Sjoerg (void) sigsetmask(old_sigmask); 58824139Sjoerg#endif 58924139Sjoerg if (warnings) 59024139Sjoerg { 59124139Sjoerg fputs("....", stderr); 59224139Sjoerg fflush(stderr); /* why must I do this? */ 59324139Sjoerg sleep((unsigned)(3 * warnings)); 59424139Sjoerg fputc('\n', stderr); 59524139Sjoerg } 59624139Sjoerg 59781187Skrisrestart: 59824139Sjoerg 59924139Sjoerg /* 60024139Sjoerg * main loop -- repeat while display count is positive or while it 60124139Sjoerg * indicates infinity (by being -1) 60224139Sjoerg */ 60324139Sjoerg 60424139Sjoerg while ((displays == -1) || (displays-- > 0)) 60524139Sjoerg { 606131402Salfred int (*compare)(); 607131402Salfred 608131402Salfred 60924139Sjoerg /* get the current stats */ 61024139Sjoerg get_system_info(&system_info); 61124139Sjoerg 61224139Sjoerg#ifdef ORDER 613133817Salfred compare = compares[order_index]; 61424139Sjoerg#else 615131829Skeramida if (displaymode == DISP_CPU) 616131402Salfred compare = proc_compare; 617131829Skeramida else 618131829Skeramida compare = io_compare; 61924139Sjoerg#endif 62024139Sjoerg 621131402Salfred /* get the current set of processes */ 622131402Salfred processes = 623131402Salfred get_process_info(&system_info, &ps, compare); 624131402Salfred 62524139Sjoerg /* display the load averages */ 62624139Sjoerg (*d_loadave)(system_info.last_pid, 62724139Sjoerg system_info.load_avg); 62824139Sjoerg 62924139Sjoerg /* display the current time */ 63024139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 63124139Sjoerg time(&curr_time); 63242447Sobrien i_uptime(&system_info.boottime, &curr_time); 63324139Sjoerg i_timeofday(&curr_time); 63424139Sjoerg 63524139Sjoerg /* display process state breakdown */ 63624139Sjoerg (*d_procstates)(system_info.p_total, 63724139Sjoerg system_info.procstates); 63824139Sjoerg 63924139Sjoerg /* display the cpu state percentage breakdown */ 64024139Sjoerg if (dostates) /* but not the first time */ 64124139Sjoerg { 64224139Sjoerg (*d_cpustates)(system_info.cpustates); 64324139Sjoerg } 64424139Sjoerg else 64524139Sjoerg { 64624139Sjoerg /* we'll do it next time */ 64724139Sjoerg if (smart_terminal) 64824139Sjoerg { 64924139Sjoerg z_cpustates(); 65024139Sjoerg } 65124139Sjoerg else 65224139Sjoerg { 65324139Sjoerg putchar('\n'); 65424139Sjoerg } 65524139Sjoerg dostates = Yes; 65624139Sjoerg } 65724139Sjoerg 65824139Sjoerg /* display memory stats */ 65924139Sjoerg (*d_memory)(system_info.memory); 660237656Sjhb (*d_arc)(system_info.arc); 66124139Sjoerg 66224142Sjoerg /* display swap stats */ 66324142Sjoerg (*d_swap)(system_info.swap); 66424142Sjoerg 66524139Sjoerg /* handle message area */ 66624139Sjoerg (*d_message)(); 66724139Sjoerg 66824139Sjoerg /* update the header area */ 66924139Sjoerg (*d_header)(header_text); 67024139Sjoerg 67124139Sjoerg if (topn > 0) 67224139Sjoerg { 67324139Sjoerg /* determine number of processes to actually display */ 67424139Sjoerg /* this number will be the smallest of: active processes, 67524139Sjoerg number user requested, number current screen accomodates */ 67689757Sdwmalone active_procs = system_info.P_ACTIVE; 67724139Sjoerg if (active_procs > topn) 67824139Sjoerg { 67924139Sjoerg active_procs = topn; 68024139Sjoerg } 68124139Sjoerg if (active_procs > max_topn) 68224139Sjoerg { 68324139Sjoerg active_procs = max_topn; 68424139Sjoerg } 68524139Sjoerg 68624139Sjoerg /* now show the top "n" processes. */ 68724139Sjoerg for (i = 0; i < active_procs; i++) 68824139Sjoerg { 689168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 690168710Sstas fmt_flags)); 69124139Sjoerg } 69224139Sjoerg } 69324139Sjoerg else 69424139Sjoerg { 69524139Sjoerg i = 0; 69624139Sjoerg } 69724139Sjoerg 69824139Sjoerg /* do end-screen processing */ 69924139Sjoerg u_endscreen(i); 70024139Sjoerg 70124139Sjoerg /* now, flush the output buffer */ 70289757Sdwmalone if (fflush(stdout) != 0) 70389757Sdwmalone { 70489757Sdwmalone new_message(MT_standout, " Write error on stdout"); 70589757Sdwmalone putchar('\r'); 70689757Sdwmalone quit(1); 70789757Sdwmalone /*NOTREACHED*/ 70889757Sdwmalone } 70924139Sjoerg 71024139Sjoerg /* only do the rest if we have more displays to show */ 71124139Sjoerg if (displays) 71224139Sjoerg { 71324139Sjoerg /* switch out for new display on smart terminals */ 71424139Sjoerg if (smart_terminal) 71524139Sjoerg { 71624139Sjoerg if (overstrike) 71724139Sjoerg { 71824139Sjoerg reset_display(); 71924139Sjoerg } 72024139Sjoerg else 72124139Sjoerg { 72224139Sjoerg d_loadave = u_loadave; 72324139Sjoerg d_procstates = u_procstates; 72424139Sjoerg d_cpustates = u_cpustates; 72524139Sjoerg d_memory = u_memory; 726237656Sjhb d_arc = u_arc; 72724142Sjoerg d_swap = u_swap; 72824139Sjoerg d_message = u_message; 72924139Sjoerg d_header = u_header; 73024139Sjoerg d_process = u_process; 73124139Sjoerg } 73224139Sjoerg } 73324139Sjoerg 73424139Sjoerg no_command = Yes; 73524139Sjoerg if (!interactive) 73624139Sjoerg { 737232239Skib sleep(delay); 738232660Skib if (leaveflag) { 739232660Skib end_screen(); 740232660Skib exit(0); 741232660Skib } 74224139Sjoerg } 74324139Sjoerg else while (no_command) 74424139Sjoerg { 74524139Sjoerg /* assume valid command unless told otherwise */ 74624139Sjoerg no_command = No; 74724139Sjoerg 74824139Sjoerg /* set up arguments for select with timeout */ 74924139Sjoerg FD_ZERO(&readfds); 75089757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 75124139Sjoerg timeout.tv_sec = delay; 75224139Sjoerg timeout.tv_usec = 0; 75324139Sjoerg 75481187Skris if (leaveflag) { 75581187Skris end_screen(); 75681187Skris exit(0); 75781187Skris } 75881187Skris 75981187Skris if (tstopflag) { 76081187Skris /* move to the lower left */ 76181187Skris end_screen(); 76281187Skris fflush(stdout); 76381187Skris 76481187Skris /* default the signal handler action */ 76581187Skris (void) signal(SIGTSTP, SIG_DFL); 76681187Skris 76781187Skris /* unblock the signal and send ourselves one */ 76881187Skris#ifdef SIGRELSE 76981187Skris sigrelse(SIGTSTP); 77081187Skris#else 77181187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 77281187Skris#endif 77381187Skris (void) kill(0, SIGTSTP); 77481187Skris 77581187Skris /* reset the signal handler */ 77681187Skris (void) signal(SIGTSTP, tstop); 77781187Skris 77881187Skris /* reinit screen */ 77981187Skris reinit_screen(); 78081187Skris reset_display(); 78181187Skris tstopflag = 0; 78281187Skris goto restart; 78381187Skris } 78481187Skris 78581187Skris if (winchflag) { 78681187Skris /* reascertain the screen dimensions */ 78781187Skris get_screensize(); 78881187Skris 78981187Skris /* tell display to resize */ 79081187Skris max_topn = display_resize(); 79181187Skris 79281187Skris /* reset the signal handler */ 79381187Skris (void) signal(SIGWINCH, winch); 79481187Skris 79581187Skris reset_display(); 79681187Skris winchflag = 0; 79781187Skris goto restart; 79881187Skris } 79981187Skris 80024139Sjoerg /* wait for either input or the end of the delay period */ 80186042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 80286042Sdwmalone if (sel_ret < 0 && errno != EINTR) 80386042Sdwmalone quit(0); 80486042Sdwmalone if (sel_ret > 0) 80524139Sjoerg { 80624139Sjoerg int newval; 80724139Sjoerg char *errmsg; 80824139Sjoerg 80924139Sjoerg /* something to read -- clear the message area first */ 81024139Sjoerg clear_message(); 81124139Sjoerg 81224139Sjoerg /* now read it and convert to command strchr */ 81324139Sjoerg /* (use "change" as a temporary to hold strchr) */ 81486042Sdwmalone if (read(0, &ch, 1) != 1) 81589757Sdwmalone { 81689757Sdwmalone /* read error: either 0 or -1 */ 81789757Sdwmalone new_message(MT_standout, " Read error on stdin"); 81889757Sdwmalone putchar('\r'); 81989757Sdwmalone quit(1); 82089757Sdwmalone /*NOTREACHED*/ 82189757Sdwmalone } 82224139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 82324139Sjoerg { 82424142Sjoerg if (ch != '\r' && ch != '\n') 82524142Sjoerg { 82624142Sjoerg /* illegal command */ 82724142Sjoerg new_message(MT_standout, " Command not understood"); 82824142Sjoerg } 82924139Sjoerg putchar('\r'); 83024139Sjoerg no_command = Yes; 83124139Sjoerg } 83224139Sjoerg else 83324139Sjoerg { 83424139Sjoerg change = iptr - command_chars; 83524139Sjoerg if (overstrike && change > CMD_OSLIMIT) 83624139Sjoerg { 83724139Sjoerg /* error */ 83824139Sjoerg new_message(MT_standout, 83924139Sjoerg " Command cannot be handled by this terminal"); 84024139Sjoerg putchar('\r'); 84124139Sjoerg no_command = Yes; 84224139Sjoerg } 84324139Sjoerg else switch(change) 84424139Sjoerg { 84524139Sjoerg case CMD_redraw: /* redraw screen */ 84624139Sjoerg reset_display(); 84724139Sjoerg break; 84824139Sjoerg 84924139Sjoerg case CMD_update: /* merely update display */ 85024139Sjoerg /* is the load average high? */ 85124139Sjoerg if (system_info.load_avg[0] > LoadMax) 85224139Sjoerg { 85324139Sjoerg /* yes, go home for visual feedback */ 85424139Sjoerg go_home(); 85524139Sjoerg fflush(stdout); 85624139Sjoerg } 85724139Sjoerg break; 85824139Sjoerg 85924139Sjoerg case CMD_quit: /* quit */ 86024139Sjoerg quit(0); 86124139Sjoerg /*NOTREACHED*/ 86224139Sjoerg break; 86324139Sjoerg 86424139Sjoerg case CMD_help1: /* help */ 86524139Sjoerg case CMD_help2: 86624139Sjoerg reset_display(); 86724139Sjoerg clear(); 86824139Sjoerg show_help(); 86924139Sjoerg standout("Hit any key to continue: "); 87024139Sjoerg fflush(stdout); 87124139Sjoerg (void) read(0, &ch, 1); 87224139Sjoerg break; 87324139Sjoerg 87424139Sjoerg case CMD_errors: /* show errors */ 87524139Sjoerg if (error_count() == 0) 87624139Sjoerg { 87724139Sjoerg new_message(MT_standout, 87824139Sjoerg " Currently no errors to report."); 87924139Sjoerg putchar('\r'); 88024139Sjoerg no_command = Yes; 88124139Sjoerg } 88224139Sjoerg else 88324139Sjoerg { 88424139Sjoerg reset_display(); 88524139Sjoerg clear(); 88624139Sjoerg show_errors(); 88724139Sjoerg standout("Hit any key to continue: "); 88824139Sjoerg fflush(stdout); 88924139Sjoerg (void) read(0, &ch, 1); 89024139Sjoerg } 89124139Sjoerg break; 89224139Sjoerg 89324139Sjoerg case CMD_number1: /* new number */ 89424139Sjoerg case CMD_number2: 89524139Sjoerg new_message(MT_standout, 89624139Sjoerg "Number of processes to show: "); 89724139Sjoerg newval = readline(tempbuf1, 8, Yes); 89824139Sjoerg if (newval > -1) 89924139Sjoerg { 90024139Sjoerg if (newval > max_topn) 90124139Sjoerg { 90224139Sjoerg new_message(MT_standout | MT_delayed, 90324139Sjoerg " This terminal can only display %d processes.", 90424139Sjoerg max_topn); 90524139Sjoerg putchar('\r'); 90624139Sjoerg } 90724139Sjoerg 90824139Sjoerg if (newval == 0) 90924139Sjoerg { 91024139Sjoerg /* inhibit the header */ 91124139Sjoerg display_header(No); 91224139Sjoerg } 91324139Sjoerg else if (newval > topn && topn == 0) 91424139Sjoerg { 91524139Sjoerg /* redraw the header */ 91624139Sjoerg display_header(Yes); 91724139Sjoerg d_header = i_header; 91824139Sjoerg } 91924139Sjoerg topn = newval; 92024139Sjoerg } 92124139Sjoerg break; 92224139Sjoerg 92324139Sjoerg case CMD_delay: /* new seconds delay */ 92424139Sjoerg new_message(MT_standout, "Seconds to delay: "); 92524139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 92624139Sjoerg { 92789757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 92889757Sdwmalone { 92989757Sdwmalone delay = 1; 93089757Sdwmalone } 93124139Sjoerg } 93224139Sjoerg clear_message(); 93324139Sjoerg break; 93424139Sjoerg 93524139Sjoerg case CMD_displays: /* change display count */ 93624139Sjoerg new_message(MT_standout, 93724139Sjoerg "Displays to show (currently %s): ", 93824139Sjoerg displays == -1 ? "infinite" : 93924139Sjoerg itoa(displays)); 94024139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 94124139Sjoerg { 94224139Sjoerg displays = i; 94324139Sjoerg } 94424139Sjoerg else if (i == 0) 94524139Sjoerg { 94624139Sjoerg quit(0); 94724139Sjoerg } 94824139Sjoerg clear_message(); 94924139Sjoerg break; 95024139Sjoerg 95124139Sjoerg case CMD_kill: /* kill program */ 95224139Sjoerg new_message(0, "kill "); 95324139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 95424139Sjoerg { 95524139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 95624139Sjoerg { 95766641Simp new_message(MT_standout, "%s", errmsg); 95824139Sjoerg putchar('\r'); 95924139Sjoerg no_command = Yes; 96024139Sjoerg } 96124139Sjoerg } 96224139Sjoerg else 96324139Sjoerg { 96424139Sjoerg clear_message(); 96524139Sjoerg } 96624139Sjoerg break; 96724139Sjoerg 96824139Sjoerg case CMD_renice: /* renice program */ 96924139Sjoerg new_message(0, "renice "); 97024139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 97124139Sjoerg { 97224139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 97324139Sjoerg { 97468293Simp new_message(MT_standout, "%s", errmsg); 97524139Sjoerg putchar('\r'); 97624139Sjoerg no_command = Yes; 97724139Sjoerg } 97824139Sjoerg } 97924139Sjoerg else 98024139Sjoerg { 98124139Sjoerg clear_message(); 98224139Sjoerg } 98324139Sjoerg break; 98424139Sjoerg 98524139Sjoerg case CMD_idletog: 98624139Sjoerg case CMD_idletog2: 98724139Sjoerg ps.idle = !ps.idle; 98824139Sjoerg new_message(MT_standout | MT_delayed, 98924139Sjoerg " %sisplaying idle processes.", 99024139Sjoerg ps.idle ? "D" : "Not d"); 99124139Sjoerg putchar('\r'); 99224139Sjoerg break; 99324139Sjoerg 99438090Sdes case CMD_selftog: 99538090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 99638090Sdes new_message(MT_standout | MT_delayed, 99738090Sdes " %sisplaying self.", 99838090Sdes (ps.self == -1) ? "D" : "Not d"); 99938090Sdes putchar('\r'); 100038090Sdes break; 100138090Sdes 100224139Sjoerg case CMD_user: 100324139Sjoerg new_message(MT_standout, 1004265250Sbdrewery "Username to show (+ for all): "); 100524139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 100624139Sjoerg { 100724139Sjoerg if (tempbuf2[0] == '+' && 100824139Sjoerg tempbuf2[1] == '\0') 100924139Sjoerg { 101024139Sjoerg ps.uid = -1; 101124139Sjoerg } 101224139Sjoerg else if ((i = userid(tempbuf2)) == -1) 101324139Sjoerg { 101424139Sjoerg new_message(MT_standout, 101524139Sjoerg " %s: unknown user", tempbuf2); 101624139Sjoerg no_command = Yes; 101724139Sjoerg } 101824139Sjoerg else 101924139Sjoerg { 102024139Sjoerg ps.uid = i; 102124139Sjoerg } 102224139Sjoerg putchar('\r'); 102324139Sjoerg } 102424139Sjoerg else 102524139Sjoerg { 102624139Sjoerg clear_message(); 102724139Sjoerg } 102824139Sjoerg break; 102924139Sjoerg 1030117709Sjulian case CMD_thrtog: 1031117709Sjulian ps.thread = !ps.thread; 1032117709Sjulian new_message(MT_standout | MT_delayed, 1033223937Sjhb " Displaying threads %s", 1034145073Skeramida ps.thread ? "separately" : "as a count"); 1035145073Skeramida header_text = format_header(uname_field); 1036145073Skeramida reset_display(); 1037117709Sjulian putchar('\r'); 1038117709Sjulian break; 1039146342Skeramida case CMD_wcputog: 1040146342Skeramida ps.wcpu = !ps.wcpu; 1041146342Skeramida new_message(MT_standout | MT_delayed, 1042224204Sjhb " Displaying %s CPU", 1043224204Sjhb ps.wcpu ? "weighted" : "raw"); 1044146342Skeramida header_text = format_header(uname_field); 1045146342Skeramida reset_display(); 1046146342Skeramida putchar('\r'); 1047146342Skeramida break; 1048131402Salfred case CMD_viewtog: 1049131402Salfred if (++displaymode == DISP_MAX) 1050131402Salfred displaymode = 0; 1051131402Salfred header_text = format_header(uname_field); 1052131402Salfred display_header(Yes); 1053131402Salfred d_header = i_header; 1054131402Salfred reset_display(); 1055131402Salfred break; 1056132005Salfred case CMD_viewsys: 1057132005Salfred ps.system = !ps.system; 1058132005Salfred break; 1059168710Sstas case CMD_showargs: 1060168710Sstas fmt_flags ^= FMT_SHOWARGS; 1061168710Sstas break; 106224139Sjoerg#ifdef ORDER 106324139Sjoerg case CMD_order: 106424139Sjoerg new_message(MT_standout, 106524139Sjoerg "Order to sort: "); 106624139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 106724139Sjoerg { 106824139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 106924139Sjoerg { 107024139Sjoerg new_message(MT_standout, 107124139Sjoerg " %s: unrecognized sorting order", tempbuf2); 107224139Sjoerg no_command = Yes; 107324139Sjoerg } 107424139Sjoerg else 107524139Sjoerg { 107624139Sjoerg order_index = i; 107724139Sjoerg } 107824139Sjoerg putchar('\r'); 107924139Sjoerg } 108024139Sjoerg else 108124139Sjoerg { 108224139Sjoerg clear_message(); 108324139Sjoerg } 108424139Sjoerg break; 108524139Sjoerg#endif 1086168799Srafan case CMD_jidtog: 1087168799Srafan ps.jail = !ps.jail; 1088168799Srafan new_message(MT_standout | MT_delayed, 1089169257Srafan " %sisplaying jail ID.", 1090168799Srafan ps.jail ? "D" : "Not d"); 1091168799Srafan header_text = format_header(uname_field); 1092168799Srafan reset_display(); 1093168799Srafan putchar('\r'); 1094168799Srafan break; 1095265249Sbdrewery 1096265249Sbdrewery case CMD_jail: 1097265249Sbdrewery new_message(MT_standout, 1098265250Sbdrewery "Jail to show (+ for all): "); 1099265249Sbdrewery if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 1100265249Sbdrewery { 1101265249Sbdrewery if (tempbuf2[0] == '+' && 1102265249Sbdrewery tempbuf2[1] == '\0') 1103265249Sbdrewery { 1104265249Sbdrewery ps.jid = -1; 1105265249Sbdrewery } 1106265249Sbdrewery else if ((i = jail_getid(tempbuf2)) == -1) 1107265249Sbdrewery { 1108265249Sbdrewery new_message(MT_standout, 1109265249Sbdrewery " %s: unknown jail", tempbuf2); 1110265249Sbdrewery no_command = Yes; 1111265249Sbdrewery } 1112265249Sbdrewery else 1113265249Sbdrewery { 1114265249Sbdrewery ps.jid = i; 1115265249Sbdrewery } 1116265249Sbdrewery if (ps.jail == 0) { 1117265249Sbdrewery ps.jail = 1; 1118265249Sbdrewery new_message(MT_standout | 1119265249Sbdrewery MT_delayed, " Displaying jail " 1120265249Sbdrewery "ID."); 1121265249Sbdrewery header_text = 1122265249Sbdrewery format_header(uname_field); 1123265249Sbdrewery reset_display(); 1124265249Sbdrewery } 1125265249Sbdrewery putchar('\r'); 1126265249Sbdrewery } 1127265249Sbdrewery else 1128265249Sbdrewery { 1129265249Sbdrewery clear_message(); 1130265249Sbdrewery } 1131265249Sbdrewery break; 1132265249Sbdrewery 1133222530Sjhb case CMD_kidletog: 1134222530Sjhb ps.kidle = !ps.kidle; 1135222530Sjhb new_message(MT_standout | MT_delayed, 1136222530Sjhb " %sisplaying system idle process.", 1137222530Sjhb ps.kidle ? "D" : "Not d"); 1138222530Sjhb putchar('\r'); 1139222530Sjhb break; 1140223936Sjhb case CMD_pcputog: 1141223936Sjhb pcpu_stats = !pcpu_stats; 1142223936Sjhb new_message(MT_standout | MT_delayed, 1143223936Sjhb " Displaying %sCPU statistics.", 1144223936Sjhb pcpu_stats ? "per-" : "global "); 1145224205Sjhb toggle_pcpustats(); 1146223936Sjhb max_topn = display_updatecpus(&statics); 1147223936Sjhb reset_display(); 1148223936Sjhb putchar('\r'); 1149223936Sjhb break; 1150307757Sdes case CMD_swaptog: 1151307757Sdes ps.swap = !ps.swap; 1152307757Sdes new_message(MT_standout | MT_delayed, 1153307757Sdes " %sisplaying per-process swap usage.", 1154307757Sdes ps.swap ? "D" : "Not d"); 1155307757Sdes header_text = format_header(uname_field); 1156307757Sdes reset_display(); 1157307757Sdes putchar('\r'); 1158307757Sdes break; 115924139Sjoerg default: 116024139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 116124139Sjoerg putchar('\r'); 116224139Sjoerg } 116324139Sjoerg } 116424139Sjoerg 116524139Sjoerg /* flush out stuff that may have been written */ 116624139Sjoerg fflush(stdout); 116724139Sjoerg } 116824139Sjoerg } 116924139Sjoerg } 117024139Sjoerg } 117124139Sjoerg 117289757Sdwmalone#ifdef DEBUG 117389757Sdwmalone fclose(debug); 117489757Sdwmalone#endif 117524139Sjoerg quit(0); 117624139Sjoerg /*NOTREACHED*/ 117724139Sjoerg} 117824139Sjoerg 117924139Sjoerg/* 118024139Sjoerg * reset_display() - reset all the display routine pointers so that entire 118124139Sjoerg * screen will get redrawn. 118224139Sjoerg */ 118324139Sjoerg 1184300395Sngievoid 118524139Sjoergreset_display() 118624139Sjoerg 118724139Sjoerg{ 118824139Sjoerg d_loadave = i_loadave; 118924139Sjoerg d_procstates = i_procstates; 119024139Sjoerg d_cpustates = i_cpustates; 119124139Sjoerg d_memory = i_memory; 1192237656Sjhb d_arc = i_arc; 119324142Sjoerg d_swap = i_swap; 119424139Sjoerg d_message = i_message; 119524139Sjoerg d_header = i_header; 119624139Sjoerg d_process = i_process; 119724139Sjoerg} 119824139Sjoerg 119924139Sjoerg/* 120024139Sjoerg * signal handlers 120124139Sjoerg */ 120224139Sjoerg 120324139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 120424139Sjoerg 120524139Sjoerg{ 120681187Skris leaveflag = 1; 120724139Sjoerg} 120824139Sjoerg 120924139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 121024139Sjoerg 121124139Sjoergint i; 121224139Sjoerg 121324139Sjoerg{ 121481187Skris tstopflag = 1; 121524139Sjoerg} 121624139Sjoerg 121724139Sjoerg#ifdef SIGWINCH 121824139Sjoergsigret_t winch(i) /* SIGWINCH handler */ 121924139Sjoerg 122024139Sjoergint i; 122124139Sjoerg 122224139Sjoerg{ 122381187Skris winchflag = 1; 122424139Sjoerg} 122524139Sjoerg#endif 122624139Sjoerg 122724139Sjoergvoid quit(status) /* exit under duress */ 122824139Sjoerg 122924139Sjoergint status; 123024139Sjoerg 123124139Sjoerg{ 123224139Sjoerg end_screen(); 123324139Sjoerg exit(status); 123424139Sjoerg /*NOTREACHED*/ 123524139Sjoerg} 1236