top.c revision 265249
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 265249 2014-05-02 23:30:39Z bdrewery $ 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> 41265249Sbdrewery#include <sys/jail.h> 4224139Sjoerg#include <sys/time.h> 43265249Sbdrewery#include <jail.h> 4424139Sjoerg 4524139Sjoerg/* includes specific to top */ 4624139Sjoerg#include "display.h" /* interface to display package */ 4724139Sjoerg#include "screen.h" /* interface to screen package */ 4824139Sjoerg#include "top.h" 4924139Sjoerg#include "top.local.h" 5024139Sjoerg#include "boolean.h" 5124139Sjoerg#include "machine.h" 5224139Sjoerg#include "utils.h" 5324139Sjoerg 5424139Sjoerg/* Size of the stdio buffer given to stdout */ 5524139Sjoerg#define Buffersize 2048 5624139Sjoerg 5724139Sjoerg/* The buffer that stdio will use */ 5824139Sjoergchar stdoutbuf[Buffersize]; 5924139Sjoerg 6024139Sjoerg/* build Signal masks */ 6124139Sjoerg#define Smask(s) (1 << ((s) - 1)) 6224139Sjoerg 6324139Sjoerg/* for getopt: */ 6424139Sjoergextern int optind; 6524139Sjoergextern char *optarg; 6624139Sjoerg 6724139Sjoerg/* imported from screen.c */ 6824139Sjoergextern int overstrike; 6924139Sjoerg 70168710Sstasstatic int fmt_flags = 0; 71175420Speterint pcpu_stats = No; 72168710Sstas 7324139Sjoerg/* signal handling routines */ 7424139Sjoergsigret_t leave(); 7524139Sjoergsigret_t tstop(); 7624139Sjoerg#ifdef SIGWINCH 7724139Sjoergsigret_t winch(); 7824139Sjoerg#endif 7924139Sjoerg 8081187Skrisvolatile sig_atomic_t leaveflag; 8181187Skrisvolatile sig_atomic_t tstopflag; 8281187Skrisvolatile sig_atomic_t winchflag; 8381187Skris 8424139Sjoerg/* internal routines */ 8524139Sjoergvoid quit(); 8624139Sjoerg 8724139Sjoerg/* values which need to be accessed by signal handlers */ 8824139Sjoergstatic int max_topn; /* maximum displayable processes */ 8924139Sjoerg 9024139Sjoerg/* miscellaneous things */ 91145073Skeramidastruct process_select ps; 9224139Sjoergchar *myname = "top"; 9324139Sjoergjmp_buf jmp_int; 9424139Sjoerg 9524139Sjoerg/* routines that don't return int */ 9624139Sjoerg 9724139Sjoergchar *username(); 9824139Sjoergchar *ctime(); 9924139Sjoergchar *kill_procs(); 10024139Sjoergchar *renice_procs(); 10124139Sjoerg 10224139Sjoerg#ifdef ORDER 103133817Salfredextern int (*compares[])(); 10424139Sjoerg#else 10524139Sjoergextern int proc_compare(); 106131829Skeramidaextern int io_compare(); 10724139Sjoerg#endif 10824139Sjoergtime_t time(); 10924139Sjoerg 11024139Sjoergcaddr_t get_process_info(); 11124139Sjoerg 11224139Sjoerg/* different routines for displaying the user's identification */ 11324139Sjoerg/* (values assigned to get_userid) */ 11424139Sjoergchar *username(); 11524139Sjoergchar *itoa7(); 11624139Sjoerg 11724139Sjoerg/* display routines that need to be predeclared */ 11824139Sjoergint i_loadave(); 11924139Sjoergint u_loadave(); 12024139Sjoergint i_procstates(); 12124139Sjoergint u_procstates(); 12224139Sjoergint i_cpustates(); 12324139Sjoergint u_cpustates(); 12424139Sjoergint i_memory(); 12524139Sjoergint u_memory(); 126237656Sjhbint i_arc(); 127237656Sjhbint u_arc(); 12824142Sjoergint i_swap(); 12924142Sjoergint u_swap(); 13024139Sjoergint i_message(); 13124139Sjoergint u_message(); 13224139Sjoergint i_header(); 13324139Sjoergint u_header(); 13424139Sjoergint i_process(); 13524139Sjoergint u_process(); 13624139Sjoerg 13724139Sjoerg/* pointers to display routines */ 13824139Sjoergint (*d_loadave)() = i_loadave; 13924139Sjoergint (*d_procstates)() = i_procstates; 14024139Sjoergint (*d_cpustates)() = i_cpustates; 14124139Sjoergint (*d_memory)() = i_memory; 142237656Sjhbint (*d_arc)() = i_arc; 14324142Sjoergint (*d_swap)() = i_swap; 14424139Sjoergint (*d_message)() = i_message; 14524139Sjoergint (*d_header)() = i_header; 14624139Sjoergint (*d_process)() = i_process; 14724139Sjoerg 14824139Sjoerg 14924139Sjoergmain(argc, argv) 15024139Sjoerg 15124139Sjoergint argc; 15224139Sjoergchar *argv[]; 15324139Sjoerg 15424139Sjoerg{ 15524139Sjoerg register int i; 15624139Sjoerg register int active_procs; 15724139Sjoerg register int change; 15824139Sjoerg 15924139Sjoerg struct system_info system_info; 16024139Sjoerg struct statics statics; 16124139Sjoerg caddr_t processes; 16224139Sjoerg 16324139Sjoerg static char tempbuf1[50]; 16424139Sjoerg static char tempbuf2[50]; 16524139Sjoerg int old_sigmask; /* only used for BSD-style signals */ 16624139Sjoerg int topn = Default_TOPN; 16724139Sjoerg int delay = Default_DELAY; 16824139Sjoerg int displays = 0; /* indicates unspecified */ 16986042Sdwmalone int sel_ret = 0; 17024139Sjoerg time_t curr_time; 17124139Sjoerg char *(*get_userid)() = username; 17224139Sjoerg char *uname_field = "USERNAME"; 17324139Sjoerg char *header_text; 17424139Sjoerg char *env_top; 17524139Sjoerg char **preset_argv; 17624139Sjoerg int preset_argc = 0; 17724139Sjoerg char **av; 17824139Sjoerg int ac; 17924139Sjoerg char dostates = No; 18024139Sjoerg char do_unames = Yes; 18124139Sjoerg char interactive = Maybe; 18224139Sjoerg char warnings = 0; 18324139Sjoerg#if Default_TOPN == Infinity 18424139Sjoerg char topn_specified = No; 18524139Sjoerg#endif 18624139Sjoerg char ch; 18724139Sjoerg char *iptr; 18824139Sjoerg char no_command = 1; 18924139Sjoerg struct timeval timeout; 19024139Sjoerg#ifdef ORDER 19124139Sjoerg char *order_name = NULL; 19224139Sjoerg int order_index = 0; 19324139Sjoerg#endif 19424139Sjoerg#ifndef FD_SET 19524139Sjoerg /* FD_SET and friends are not present: fake it */ 19624139Sjoerg typedef int fd_set; 19724139Sjoerg#define FD_ZERO(x) (*(x) = 0) 19889757Sdwmalone#define FD_SET(f, x) (*(x) = 1<<f) 19924139Sjoerg#endif 20024139Sjoerg fd_set readfds; 20124139Sjoerg 20224139Sjoerg#ifdef ORDER 203265249Sbdrewery static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJo"; 20424139Sjoerg#else 205265249Sbdrewery static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJ"; 20624139Sjoerg#endif 20724139Sjoerg/* these defines enumerate the "strchr"s of the commands in command_chars */ 20824139Sjoerg#define CMD_redraw 0 20924139Sjoerg#define CMD_update 1 21024139Sjoerg#define CMD_quit 2 21124139Sjoerg#define CMD_help1 3 21224139Sjoerg#define CMD_help2 4 21324139Sjoerg#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ 21424139Sjoerg#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ 21524139Sjoerg#define CMD_number1 6 21624139Sjoerg#define CMD_number2 7 21724139Sjoerg#define CMD_delay 8 21824139Sjoerg#define CMD_displays 9 21924139Sjoerg#define CMD_kill 10 22024139Sjoerg#define CMD_renice 11 22124139Sjoerg#define CMD_idletog 12 22224139Sjoerg#define CMD_idletog2 13 22324139Sjoerg#define CMD_user 14 22438090Sdes#define CMD_selftog 15 225117709Sjulian#define CMD_thrtog 16 226131402Salfred#define CMD_viewtog 17 227132005Salfred#define CMD_viewsys 18 228146342Skeramida#define CMD_wcputog 19 229168710Sstas#define CMD_showargs 20 230168799Srafan#define CMD_jidtog 21 231222530Sjhb#define CMD_kidletog 22 232223936Sjhb#define CMD_pcputog 23 233265249Sbdrewery#define CMD_jail 24 23424139Sjoerg#ifdef ORDER 235265249Sbdrewery#define CMD_order 25 23624139Sjoerg#endif 23724139Sjoerg 23824139Sjoerg /* set the buffer for stdout */ 23924139Sjoerg#ifdef DEBUG 24089757Sdwmalone extern FILE *debug; 24189757Sdwmalone debug = fopen("debug.run", "w"); 24224139Sjoerg setbuffer(stdout, NULL, 0); 24324139Sjoerg#else 24424139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 24524139Sjoerg#endif 24624139Sjoerg 24724139Sjoerg /* get our name */ 24824139Sjoerg if (argc > 0) 24924139Sjoerg { 25024139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 25124139Sjoerg { 25224139Sjoerg myname = argv[0]; 25324139Sjoerg } 25424139Sjoerg else 25524139Sjoerg { 25624139Sjoerg myname++; 25724139Sjoerg } 25824139Sjoerg } 25924139Sjoerg 26024139Sjoerg /* initialize some selection options */ 26124139Sjoerg ps.idle = Yes; 26238090Sdes ps.self = -1; 26324139Sjoerg ps.system = No; 26424139Sjoerg ps.uid = -1; 265117709Sjulian ps.thread = No; 266146342Skeramida ps.wcpu = 1; 267265249Sbdrewery ps.jid = -1; 268168799Srafan ps.jail = No; 269222530Sjhb ps.kidle = Yes; 27024139Sjoerg ps.command = NULL; 27124139Sjoerg 27224139Sjoerg /* get preset options from the environment */ 27324139Sjoerg if ((env_top = getenv("TOP")) != NULL) 27424139Sjoerg { 27524139Sjoerg av = preset_argv = argparse(env_top, &preset_argc); 27624139Sjoerg ac = preset_argc; 27724139Sjoerg 27824139Sjoerg /* set the dummy argument to an explanatory message, in case 27924139Sjoerg getopt encounters a bad argument */ 28024139Sjoerg preset_argv[0] = "while processing environment"; 28124139Sjoerg } 28224139Sjoerg 28324139Sjoerg /* process options */ 28424139Sjoerg do { 28524139Sjoerg /* if we're done doing the presets, then process the real arguments */ 28624139Sjoerg if (preset_argc == 0) 28724139Sjoerg { 28824139Sjoerg ac = argc; 28924139Sjoerg av = argv; 29024139Sjoerg 29124139Sjoerg /* this should keep getopt happy... */ 29224139Sjoerg optind = 1; 29324139Sjoerg } 29424139Sjoerg 295265249Sbdrewery while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:t")) != EOF) 29624139Sjoerg { 29724139Sjoerg switch(i) 29824139Sjoerg { 29989757Sdwmalone case 'v': /* show version number */ 30089757Sdwmalone fprintf(stderr, "%s: version %s\n", 30189757Sdwmalone myname, version_string()); 30289757Sdwmalone exit(1); 30389757Sdwmalone break; 30489757Sdwmalone 30524139Sjoerg case 'u': /* toggle uid/username display */ 30624139Sjoerg do_unames = !do_unames; 30724139Sjoerg break; 30824139Sjoerg 30924139Sjoerg case 'U': /* display only username's processes */ 31024139Sjoerg if ((ps.uid = userid(optarg)) == -1) 31124139Sjoerg { 31224139Sjoerg fprintf(stderr, "%s: unknown user\n", optarg); 31324139Sjoerg exit(1); 31424139Sjoerg } 31524139Sjoerg break; 31624139Sjoerg 31724139Sjoerg case 'S': /* show system processes */ 31824139Sjoerg ps.system = !ps.system; 31924139Sjoerg break; 32024139Sjoerg 32124139Sjoerg case 'I': /* show idle processes */ 32224139Sjoerg ps.idle = !ps.idle; 32324139Sjoerg break; 32424139Sjoerg 32524139Sjoerg case 'i': /* go interactive regardless */ 32624139Sjoerg interactive = Yes; 32724139Sjoerg break; 32824139Sjoerg 32924139Sjoerg case 'n': /* batch, or non-interactive */ 33024139Sjoerg case 'b': 33124139Sjoerg interactive = No; 33224139Sjoerg break; 33324139Sjoerg 334168710Sstas case 'a': 335168710Sstas fmt_flags ^= FMT_SHOWARGS; 336168710Sstas break; 337168710Sstas 33824139Sjoerg case 'd': /* number of displays to show */ 33924139Sjoerg if ((i = atoiwi(optarg)) == Invalid || i == 0) 34024139Sjoerg { 34124139Sjoerg fprintf(stderr, 34224139Sjoerg "%s: warning: display count should be positive -- option ignored\n", 34324139Sjoerg myname); 34424139Sjoerg warnings++; 34524139Sjoerg } 34624139Sjoerg else 34724139Sjoerg { 34824139Sjoerg displays = i; 34924139Sjoerg } 35024139Sjoerg break; 35124139Sjoerg 35224139Sjoerg case 's': 35389757Sdwmalone if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) 35424139Sjoerg { 35524139Sjoerg fprintf(stderr, 35689757Sdwmalone "%s: warning: seconds delay should be positive -- using default\n", 35724139Sjoerg myname); 35824139Sjoerg delay = Default_DELAY; 35924139Sjoerg warnings++; 36024139Sjoerg } 36124139Sjoerg break; 36224139Sjoerg 36324139Sjoerg case 'q': /* be quick about it */ 36424139Sjoerg /* only allow this if user is really root */ 36524139Sjoerg if (getuid() == 0) 36624139Sjoerg { 36724139Sjoerg /* be very un-nice! */ 36824139Sjoerg (void) nice(-20); 36924139Sjoerg } 37024139Sjoerg else 37124139Sjoerg { 37224139Sjoerg fprintf(stderr, 37324139Sjoerg "%s: warning: `-q' option can only be used by root\n", 37424139Sjoerg myname); 37524139Sjoerg warnings++; 37624139Sjoerg } 37724139Sjoerg break; 37824139Sjoerg 379131616Sdes case 'm': /* select display mode */ 380131402Salfred if (strcmp(optarg, "io") == 0) { 381131402Salfred displaymode = DISP_IO; 382131402Salfred } else if (strcmp(optarg, "cpu") == 0) { 383131402Salfred displaymode = DISP_CPU; 384131402Salfred } else { 385131402Salfred fprintf(stderr, 386131402Salfred "%s: warning: `-m' option can only take args " 387131402Salfred "'io' or 'cpu'\n", 388131402Salfred myname); 389131402Salfred exit(1); 390131402Salfred } 391131402Salfred break; 392131402Salfred 39324139Sjoerg case 'o': /* select sort order */ 39424139Sjoerg#ifdef ORDER 39524139Sjoerg order_name = optarg; 39624139Sjoerg#else 39724139Sjoerg fprintf(stderr, 39824139Sjoerg "%s: this platform does not support arbitrary ordering. Sorry.\n", 39924139Sjoerg myname); 40024139Sjoerg warnings++; 40124139Sjoerg#endif 40224139Sjoerg break; 40324139Sjoerg 40438090Sdes case 't': 40538090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 40638090Sdes break; 407146342Skeramida 408146342Skeramida case 'C': 409146342Skeramida ps.wcpu = !ps.wcpu; 410146342Skeramida break; 411146342Skeramida 412117709Sjulian case 'H': 413117709Sjulian ps.thread = !ps.thread; 414117709Sjulian break; 415146342Skeramida 416168799Srafan case 'j': 417168799Srafan ps.jail = !ps.jail; 418168799Srafan break; 419168799Srafan 420265249Sbdrewery case 'J': /* display only jail's processes */ 421265249Sbdrewery if ((ps.jid = jail_getid(optarg)) == -1) 422265249Sbdrewery { 423265249Sbdrewery fprintf(stderr, "%s: unknown jail\n", optarg); 424265249Sbdrewery exit(1); 425265249Sbdrewery } 426265249Sbdrewery ps.jail = 1; 427265249Sbdrewery break; 428265249Sbdrewery 429175420Speter case 'P': 430223936Sjhb pcpu_stats = !pcpu_stats; 431175420Speter break; 432175420Speter 433222530Sjhb case 'z': 434222530Sjhb ps.kidle = !ps.kidle; 435222530Sjhb break; 436222530Sjhb 43724139Sjoerg default: 438157842Sru fprintf(stderr, 439157842Sru"Top version %s\n" 440222530Sjhb"Usage: %s [-abCHIijnPqStuvz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 441265249Sbdrewery" [-J jail] [-U username] [number]\n", 44224139Sjoerg version_string(), myname); 44324139Sjoerg exit(1); 44424139Sjoerg } 44524139Sjoerg } 44624139Sjoerg 44724139Sjoerg /* get count of top processes to display (if any) */ 44824139Sjoerg if (optind < ac) 44924139Sjoerg { 45024139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 45124139Sjoerg { 45224139Sjoerg fprintf(stderr, 45324139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 45424139Sjoerg myname); 45524139Sjoerg warnings++; 45624139Sjoerg } 45724139Sjoerg#if Default_TOPN == Infinity 45824139Sjoerg else 45924139Sjoerg { 46024139Sjoerg topn_specified = Yes; 46124139Sjoerg } 46224139Sjoerg#endif 46324139Sjoerg } 46424139Sjoerg 46524139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 46624139Sjoerg i = preset_argc; 46724139Sjoerg preset_argc = 0; 46824139Sjoerg 46924139Sjoerg /* repeat only if we really did the preset arguments */ 47024139Sjoerg } while (i != 0); 47124139Sjoerg 47224139Sjoerg /* set constants for username/uid display correctly */ 47324139Sjoerg if (!do_unames) 47424139Sjoerg { 47524139Sjoerg uname_field = " UID "; 47624139Sjoerg get_userid = itoa7; 47724139Sjoerg } 47824139Sjoerg 47924139Sjoerg /* initialize the kernel memory interface */ 480175195Sobrien if (machine_init(&statics, do_unames) == -1) 48124139Sjoerg { 48224139Sjoerg exit(1); 48324139Sjoerg } 48424139Sjoerg 48524139Sjoerg#ifdef ORDER 48624139Sjoerg /* determine sorting order index, if necessary */ 48724139Sjoerg if (order_name != NULL) 48824139Sjoerg { 48924139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 49024139Sjoerg { 49124139Sjoerg char **pp; 49224139Sjoerg 49324139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 49424139Sjoerg myname, order_name); 49524139Sjoerg fprintf(stderr, "\tTry one of these:"); 49624139Sjoerg pp = statics.order_names; 49724139Sjoerg while (*pp != NULL) 49824139Sjoerg { 49924139Sjoerg fprintf(stderr, " %s", *pp++); 50024139Sjoerg } 50124139Sjoerg fputc('\n', stderr); 50224139Sjoerg exit(1); 50324139Sjoerg } 50424139Sjoerg } 50524139Sjoerg#endif 50624139Sjoerg 50724139Sjoerg#ifdef no_initialization_needed 50824139Sjoerg /* initialize the hashing stuff */ 50924139Sjoerg if (do_unames) 51024139Sjoerg { 51124139Sjoerg init_hash(); 51224139Sjoerg } 51324139Sjoerg#endif 51424139Sjoerg 51524139Sjoerg /* initialize termcap */ 51624139Sjoerg init_termcap(interactive); 51724139Sjoerg 51824139Sjoerg /* get the string to use for the process area header */ 51924139Sjoerg header_text = format_header(uname_field); 52024139Sjoerg 52124139Sjoerg /* initialize display interface */ 52224139Sjoerg if ((max_topn = display_init(&statics)) == -1) 52324139Sjoerg { 52424139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 52524139Sjoerg exit(4); 52624139Sjoerg } 52724139Sjoerg 52824139Sjoerg /* print warning if user requested more processes than we can display */ 52924139Sjoerg if (topn > max_topn) 53024139Sjoerg { 53124139Sjoerg fprintf(stderr, 53224139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 53324139Sjoerg myname, max_topn); 53424139Sjoerg warnings++; 53524139Sjoerg } 53624139Sjoerg 53724139Sjoerg /* adjust for topn == Infinity */ 53824139Sjoerg if (topn == Infinity) 53924139Sjoerg { 54024139Sjoerg /* 54124139Sjoerg * For smart terminals, infinity really means everything that can 54224139Sjoerg * be displayed, or Largest. 54324139Sjoerg * On dumb terminals, infinity means every process in the system! 54424139Sjoerg * We only really want to do that if it was explicitly specified. 54524139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 54624139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 54724139Sjoerg * and the default is Infinity, then (and only then) we use 54824139Sjoerg * "Nominal_TOPN" instead. 54924139Sjoerg */ 55024139Sjoerg#if Default_TOPN == Infinity 55124139Sjoerg topn = smart_terminal ? Largest : 55224139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 55324139Sjoerg#else 55424139Sjoerg topn = Largest; 55524139Sjoerg#endif 55624139Sjoerg } 55724139Sjoerg 55824139Sjoerg /* set header display accordingly */ 55924139Sjoerg display_header(topn > 0); 56024139Sjoerg 56124139Sjoerg /* determine interactive state */ 56224139Sjoerg if (interactive == Maybe) 56324139Sjoerg { 56424139Sjoerg interactive = smart_terminal; 56524139Sjoerg } 56624139Sjoerg 56724139Sjoerg /* if # of displays not specified, fill it in */ 56824139Sjoerg if (displays == 0) 56924139Sjoerg { 57024139Sjoerg displays = smart_terminal ? Infinity : 1; 57124139Sjoerg } 57224139Sjoerg 57324139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 57424139Sjoerg#ifdef SIGHOLD 57524139Sjoerg sighold(SIGINT); 57624139Sjoerg sighold(SIGQUIT); 57724139Sjoerg sighold(SIGTSTP); 57824139Sjoerg#else 57924139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 58024139Sjoerg#endif 58124139Sjoerg init_screen(); 58224139Sjoerg (void) signal(SIGINT, leave); 58324139Sjoerg (void) signal(SIGQUIT, leave); 58424139Sjoerg (void) signal(SIGTSTP, tstop); 58524139Sjoerg#ifdef SIGWINCH 58624139Sjoerg (void) signal(SIGWINCH, winch); 58724139Sjoerg#endif 58824139Sjoerg#ifdef SIGRELSE 58924139Sjoerg sigrelse(SIGINT); 59024139Sjoerg sigrelse(SIGQUIT); 59124139Sjoerg sigrelse(SIGTSTP); 59224139Sjoerg#else 59324139Sjoerg (void) sigsetmask(old_sigmask); 59424139Sjoerg#endif 59524139Sjoerg if (warnings) 59624139Sjoerg { 59724139Sjoerg fputs("....", stderr); 59824139Sjoerg fflush(stderr); /* why must I do this? */ 59924139Sjoerg sleep((unsigned)(3 * warnings)); 60024139Sjoerg fputc('\n', stderr); 60124139Sjoerg } 60224139Sjoerg 60381187Skrisrestart: 60424139Sjoerg 60524139Sjoerg /* 60624139Sjoerg * main loop -- repeat while display count is positive or while it 60724139Sjoerg * indicates infinity (by being -1) 60824139Sjoerg */ 60924139Sjoerg 61024139Sjoerg while ((displays == -1) || (displays-- > 0)) 61124139Sjoerg { 612131402Salfred int (*compare)(); 613131402Salfred 614131402Salfred 61524139Sjoerg /* get the current stats */ 61624139Sjoerg get_system_info(&system_info); 61724139Sjoerg 61824139Sjoerg#ifdef ORDER 619133817Salfred compare = compares[order_index]; 62024139Sjoerg#else 621131829Skeramida if (displaymode == DISP_CPU) 622131402Salfred compare = proc_compare; 623131829Skeramida else 624131829Skeramida compare = io_compare; 62524139Sjoerg#endif 62624139Sjoerg 627131402Salfred /* get the current set of processes */ 628131402Salfred processes = 629131402Salfred get_process_info(&system_info, &ps, compare); 630131402Salfred 63124139Sjoerg /* display the load averages */ 63224139Sjoerg (*d_loadave)(system_info.last_pid, 63324139Sjoerg system_info.load_avg); 63424139Sjoerg 63524139Sjoerg /* display the current time */ 63624139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 63724139Sjoerg time(&curr_time); 63842447Sobrien i_uptime(&system_info.boottime, &curr_time); 63924139Sjoerg i_timeofday(&curr_time); 64024139Sjoerg 64124139Sjoerg /* display process state breakdown */ 64224139Sjoerg (*d_procstates)(system_info.p_total, 64324139Sjoerg system_info.procstates); 64424139Sjoerg 64524139Sjoerg /* display the cpu state percentage breakdown */ 64624139Sjoerg if (dostates) /* but not the first time */ 64724139Sjoerg { 64824139Sjoerg (*d_cpustates)(system_info.cpustates); 64924139Sjoerg } 65024139Sjoerg else 65124139Sjoerg { 65224139Sjoerg /* we'll do it next time */ 65324139Sjoerg if (smart_terminal) 65424139Sjoerg { 65524139Sjoerg z_cpustates(); 65624139Sjoerg } 65724139Sjoerg else 65824139Sjoerg { 65924139Sjoerg putchar('\n'); 66024139Sjoerg } 66124139Sjoerg dostates = Yes; 66224139Sjoerg } 66324139Sjoerg 66424139Sjoerg /* display memory stats */ 66524139Sjoerg (*d_memory)(system_info.memory); 666237656Sjhb (*d_arc)(system_info.arc); 66724139Sjoerg 66824142Sjoerg /* display swap stats */ 66924142Sjoerg (*d_swap)(system_info.swap); 67024142Sjoerg 67124139Sjoerg /* handle message area */ 67224139Sjoerg (*d_message)(); 67324139Sjoerg 67424139Sjoerg /* update the header area */ 67524139Sjoerg (*d_header)(header_text); 67624139Sjoerg 67724139Sjoerg if (topn > 0) 67824139Sjoerg { 67924139Sjoerg /* determine number of processes to actually display */ 68024139Sjoerg /* this number will be the smallest of: active processes, 68124139Sjoerg number user requested, number current screen accomodates */ 68289757Sdwmalone active_procs = system_info.P_ACTIVE; 68324139Sjoerg if (active_procs > topn) 68424139Sjoerg { 68524139Sjoerg active_procs = topn; 68624139Sjoerg } 68724139Sjoerg if (active_procs > max_topn) 68824139Sjoerg { 68924139Sjoerg active_procs = max_topn; 69024139Sjoerg } 69124139Sjoerg 69224139Sjoerg /* now show the top "n" processes. */ 69324139Sjoerg for (i = 0; i < active_procs; i++) 69424139Sjoerg { 695168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 696168710Sstas fmt_flags)); 69724139Sjoerg } 69824139Sjoerg } 69924139Sjoerg else 70024139Sjoerg { 70124139Sjoerg i = 0; 70224139Sjoerg } 70324139Sjoerg 70424139Sjoerg /* do end-screen processing */ 70524139Sjoerg u_endscreen(i); 70624139Sjoerg 70724139Sjoerg /* now, flush the output buffer */ 70889757Sdwmalone if (fflush(stdout) != 0) 70989757Sdwmalone { 71089757Sdwmalone new_message(MT_standout, " Write error on stdout"); 71189757Sdwmalone putchar('\r'); 71289757Sdwmalone quit(1); 71389757Sdwmalone /*NOTREACHED*/ 71489757Sdwmalone } 71524139Sjoerg 71624139Sjoerg /* only do the rest if we have more displays to show */ 71724139Sjoerg if (displays) 71824139Sjoerg { 71924139Sjoerg /* switch out for new display on smart terminals */ 72024139Sjoerg if (smart_terminal) 72124139Sjoerg { 72224139Sjoerg if (overstrike) 72324139Sjoerg { 72424139Sjoerg reset_display(); 72524139Sjoerg } 72624139Sjoerg else 72724139Sjoerg { 72824139Sjoerg d_loadave = u_loadave; 72924139Sjoerg d_procstates = u_procstates; 73024139Sjoerg d_cpustates = u_cpustates; 73124139Sjoerg d_memory = u_memory; 732237656Sjhb d_arc = u_arc; 73324142Sjoerg d_swap = u_swap; 73424139Sjoerg d_message = u_message; 73524139Sjoerg d_header = u_header; 73624139Sjoerg d_process = u_process; 73724139Sjoerg } 73824139Sjoerg } 73924139Sjoerg 74024139Sjoerg no_command = Yes; 74124139Sjoerg if (!interactive) 74224139Sjoerg { 743232239Skib sleep(delay); 744232660Skib if (leaveflag) { 745232660Skib end_screen(); 746232660Skib exit(0); 747232660Skib } 74824139Sjoerg } 74924139Sjoerg else while (no_command) 75024139Sjoerg { 75124139Sjoerg /* assume valid command unless told otherwise */ 75224139Sjoerg no_command = No; 75324139Sjoerg 75424139Sjoerg /* set up arguments for select with timeout */ 75524139Sjoerg FD_ZERO(&readfds); 75689757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 75724139Sjoerg timeout.tv_sec = delay; 75824139Sjoerg timeout.tv_usec = 0; 75924139Sjoerg 76081187Skris if (leaveflag) { 76181187Skris end_screen(); 76281187Skris exit(0); 76381187Skris } 76481187Skris 76581187Skris if (tstopflag) { 76681187Skris /* move to the lower left */ 76781187Skris end_screen(); 76881187Skris fflush(stdout); 76981187Skris 77081187Skris /* default the signal handler action */ 77181187Skris (void) signal(SIGTSTP, SIG_DFL); 77281187Skris 77381187Skris /* unblock the signal and send ourselves one */ 77481187Skris#ifdef SIGRELSE 77581187Skris sigrelse(SIGTSTP); 77681187Skris#else 77781187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 77881187Skris#endif 77981187Skris (void) kill(0, SIGTSTP); 78081187Skris 78181187Skris /* reset the signal handler */ 78281187Skris (void) signal(SIGTSTP, tstop); 78381187Skris 78481187Skris /* reinit screen */ 78581187Skris reinit_screen(); 78681187Skris reset_display(); 78781187Skris tstopflag = 0; 78881187Skris goto restart; 78981187Skris } 79081187Skris 79181187Skris if (winchflag) { 79281187Skris /* reascertain the screen dimensions */ 79381187Skris get_screensize(); 79481187Skris 79581187Skris /* tell display to resize */ 79681187Skris max_topn = display_resize(); 79781187Skris 79881187Skris /* reset the signal handler */ 79981187Skris (void) signal(SIGWINCH, winch); 80081187Skris 80181187Skris reset_display(); 80281187Skris winchflag = 0; 80381187Skris goto restart; 80481187Skris } 80581187Skris 80624139Sjoerg /* wait for either input or the end of the delay period */ 80786042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 80886042Sdwmalone if (sel_ret < 0 && errno != EINTR) 80986042Sdwmalone quit(0); 81086042Sdwmalone if (sel_ret > 0) 81124139Sjoerg { 81224139Sjoerg int newval; 81324139Sjoerg char *errmsg; 81424139Sjoerg 81524139Sjoerg /* something to read -- clear the message area first */ 81624139Sjoerg clear_message(); 81724139Sjoerg 81824139Sjoerg /* now read it and convert to command strchr */ 81924139Sjoerg /* (use "change" as a temporary to hold strchr) */ 82086042Sdwmalone if (read(0, &ch, 1) != 1) 82189757Sdwmalone { 82289757Sdwmalone /* read error: either 0 or -1 */ 82389757Sdwmalone new_message(MT_standout, " Read error on stdin"); 82489757Sdwmalone putchar('\r'); 82589757Sdwmalone quit(1); 82689757Sdwmalone /*NOTREACHED*/ 82789757Sdwmalone } 82824139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 82924139Sjoerg { 83024142Sjoerg if (ch != '\r' && ch != '\n') 83124142Sjoerg { 83224142Sjoerg /* illegal command */ 83324142Sjoerg new_message(MT_standout, " Command not understood"); 83424142Sjoerg } 83524139Sjoerg putchar('\r'); 83624139Sjoerg no_command = Yes; 83724139Sjoerg } 83824139Sjoerg else 83924139Sjoerg { 84024139Sjoerg change = iptr - command_chars; 84124139Sjoerg if (overstrike && change > CMD_OSLIMIT) 84224139Sjoerg { 84324139Sjoerg /* error */ 84424139Sjoerg new_message(MT_standout, 84524139Sjoerg " Command cannot be handled by this terminal"); 84624139Sjoerg putchar('\r'); 84724139Sjoerg no_command = Yes; 84824139Sjoerg } 84924139Sjoerg else switch(change) 85024139Sjoerg { 85124139Sjoerg case CMD_redraw: /* redraw screen */ 85224139Sjoerg reset_display(); 85324139Sjoerg break; 85424139Sjoerg 85524139Sjoerg case CMD_update: /* merely update display */ 85624139Sjoerg /* is the load average high? */ 85724139Sjoerg if (system_info.load_avg[0] > LoadMax) 85824139Sjoerg { 85924139Sjoerg /* yes, go home for visual feedback */ 86024139Sjoerg go_home(); 86124139Sjoerg fflush(stdout); 86224139Sjoerg } 86324139Sjoerg break; 86424139Sjoerg 86524139Sjoerg case CMD_quit: /* quit */ 86624139Sjoerg quit(0); 86724139Sjoerg /*NOTREACHED*/ 86824139Sjoerg break; 86924139Sjoerg 87024139Sjoerg case CMD_help1: /* help */ 87124139Sjoerg case CMD_help2: 87224139Sjoerg reset_display(); 87324139Sjoerg clear(); 87424139Sjoerg show_help(); 87524139Sjoerg standout("Hit any key to continue: "); 87624139Sjoerg fflush(stdout); 87724139Sjoerg (void) read(0, &ch, 1); 87824139Sjoerg break; 87924139Sjoerg 88024139Sjoerg case CMD_errors: /* show errors */ 88124139Sjoerg if (error_count() == 0) 88224139Sjoerg { 88324139Sjoerg new_message(MT_standout, 88424139Sjoerg " Currently no errors to report."); 88524139Sjoerg putchar('\r'); 88624139Sjoerg no_command = Yes; 88724139Sjoerg } 88824139Sjoerg else 88924139Sjoerg { 89024139Sjoerg reset_display(); 89124139Sjoerg clear(); 89224139Sjoerg show_errors(); 89324139Sjoerg standout("Hit any key to continue: "); 89424139Sjoerg fflush(stdout); 89524139Sjoerg (void) read(0, &ch, 1); 89624139Sjoerg } 89724139Sjoerg break; 89824139Sjoerg 89924139Sjoerg case CMD_number1: /* new number */ 90024139Sjoerg case CMD_number2: 90124139Sjoerg new_message(MT_standout, 90224139Sjoerg "Number of processes to show: "); 90324139Sjoerg newval = readline(tempbuf1, 8, Yes); 90424139Sjoerg if (newval > -1) 90524139Sjoerg { 90624139Sjoerg if (newval > max_topn) 90724139Sjoerg { 90824139Sjoerg new_message(MT_standout | MT_delayed, 90924139Sjoerg " This terminal can only display %d processes.", 91024139Sjoerg max_topn); 91124139Sjoerg putchar('\r'); 91224139Sjoerg } 91324139Sjoerg 91424139Sjoerg if (newval == 0) 91524139Sjoerg { 91624139Sjoerg /* inhibit the header */ 91724139Sjoerg display_header(No); 91824139Sjoerg } 91924139Sjoerg else if (newval > topn && topn == 0) 92024139Sjoerg { 92124139Sjoerg /* redraw the header */ 92224139Sjoerg display_header(Yes); 92324139Sjoerg d_header = i_header; 92424139Sjoerg } 92524139Sjoerg topn = newval; 92624139Sjoerg } 92724139Sjoerg break; 92824139Sjoerg 92924139Sjoerg case CMD_delay: /* new seconds delay */ 93024139Sjoerg new_message(MT_standout, "Seconds to delay: "); 93124139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 93224139Sjoerg { 93389757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 93489757Sdwmalone { 93589757Sdwmalone delay = 1; 93689757Sdwmalone } 93724139Sjoerg } 93824139Sjoerg clear_message(); 93924139Sjoerg break; 94024139Sjoerg 94124139Sjoerg case CMD_displays: /* change display count */ 94224139Sjoerg new_message(MT_standout, 94324139Sjoerg "Displays to show (currently %s): ", 94424139Sjoerg displays == -1 ? "infinite" : 94524139Sjoerg itoa(displays)); 94624139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 94724139Sjoerg { 94824139Sjoerg displays = i; 94924139Sjoerg } 95024139Sjoerg else if (i == 0) 95124139Sjoerg { 95224139Sjoerg quit(0); 95324139Sjoerg } 95424139Sjoerg clear_message(); 95524139Sjoerg break; 95624139Sjoerg 95724139Sjoerg case CMD_kill: /* kill program */ 95824139Sjoerg new_message(0, "kill "); 95924139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 96024139Sjoerg { 96124139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 96224139Sjoerg { 96366641Simp new_message(MT_standout, "%s", errmsg); 96424139Sjoerg putchar('\r'); 96524139Sjoerg no_command = Yes; 96624139Sjoerg } 96724139Sjoerg } 96824139Sjoerg else 96924139Sjoerg { 97024139Sjoerg clear_message(); 97124139Sjoerg } 97224139Sjoerg break; 97324139Sjoerg 97424139Sjoerg case CMD_renice: /* renice program */ 97524139Sjoerg new_message(0, "renice "); 97624139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 97724139Sjoerg { 97824139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 97924139Sjoerg { 98068293Simp new_message(MT_standout, "%s", errmsg); 98124139Sjoerg putchar('\r'); 98224139Sjoerg no_command = Yes; 98324139Sjoerg } 98424139Sjoerg } 98524139Sjoerg else 98624139Sjoerg { 98724139Sjoerg clear_message(); 98824139Sjoerg } 98924139Sjoerg break; 99024139Sjoerg 99124139Sjoerg case CMD_idletog: 99224139Sjoerg case CMD_idletog2: 99324139Sjoerg ps.idle = !ps.idle; 99424139Sjoerg new_message(MT_standout | MT_delayed, 99524139Sjoerg " %sisplaying idle processes.", 99624139Sjoerg ps.idle ? "D" : "Not d"); 99724139Sjoerg putchar('\r'); 99824139Sjoerg break; 99924139Sjoerg 100038090Sdes case CMD_selftog: 100138090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 100238090Sdes new_message(MT_standout | MT_delayed, 100338090Sdes " %sisplaying self.", 100438090Sdes (ps.self == -1) ? "D" : "Not d"); 100538090Sdes putchar('\r'); 100638090Sdes break; 100738090Sdes 100824139Sjoerg case CMD_user: 100924139Sjoerg new_message(MT_standout, 101024139Sjoerg "Username to show: "); 101124139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 101224139Sjoerg { 101324139Sjoerg if (tempbuf2[0] == '+' && 101424139Sjoerg tempbuf2[1] == '\0') 101524139Sjoerg { 101624139Sjoerg ps.uid = -1; 101724139Sjoerg } 101824139Sjoerg else if ((i = userid(tempbuf2)) == -1) 101924139Sjoerg { 102024139Sjoerg new_message(MT_standout, 102124139Sjoerg " %s: unknown user", tempbuf2); 102224139Sjoerg no_command = Yes; 102324139Sjoerg } 102424139Sjoerg else 102524139Sjoerg { 102624139Sjoerg ps.uid = i; 102724139Sjoerg } 102824139Sjoerg putchar('\r'); 102924139Sjoerg } 103024139Sjoerg else 103124139Sjoerg { 103224139Sjoerg clear_message(); 103324139Sjoerg } 103424139Sjoerg break; 103524139Sjoerg 1036117709Sjulian case CMD_thrtog: 1037117709Sjulian ps.thread = !ps.thread; 1038117709Sjulian new_message(MT_standout | MT_delayed, 1039223937Sjhb " Displaying threads %s", 1040145073Skeramida ps.thread ? "separately" : "as a count"); 1041145073Skeramida header_text = format_header(uname_field); 1042145073Skeramida reset_display(); 1043117709Sjulian putchar('\r'); 1044117709Sjulian break; 1045146342Skeramida case CMD_wcputog: 1046146342Skeramida ps.wcpu = !ps.wcpu; 1047146342Skeramida new_message(MT_standout | MT_delayed, 1048224204Sjhb " Displaying %s CPU", 1049224204Sjhb ps.wcpu ? "weighted" : "raw"); 1050146342Skeramida header_text = format_header(uname_field); 1051146342Skeramida reset_display(); 1052146342Skeramida putchar('\r'); 1053146342Skeramida break; 1054131402Salfred case CMD_viewtog: 1055131402Salfred if (++displaymode == DISP_MAX) 1056131402Salfred displaymode = 0; 1057131402Salfred header_text = format_header(uname_field); 1058131402Salfred display_header(Yes); 1059131402Salfred d_header = i_header; 1060131402Salfred reset_display(); 1061131402Salfred break; 1062132005Salfred case CMD_viewsys: 1063132005Salfred ps.system = !ps.system; 1064132005Salfred break; 1065168710Sstas case CMD_showargs: 1066168710Sstas fmt_flags ^= FMT_SHOWARGS; 1067168710Sstas break; 106824139Sjoerg#ifdef ORDER 106924139Sjoerg case CMD_order: 107024139Sjoerg new_message(MT_standout, 107124139Sjoerg "Order to sort: "); 107224139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 107324139Sjoerg { 107424139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 107524139Sjoerg { 107624139Sjoerg new_message(MT_standout, 107724139Sjoerg " %s: unrecognized sorting order", tempbuf2); 107824139Sjoerg no_command = Yes; 107924139Sjoerg } 108024139Sjoerg else 108124139Sjoerg { 108224139Sjoerg order_index = i; 108324139Sjoerg } 108424139Sjoerg putchar('\r'); 108524139Sjoerg } 108624139Sjoerg else 108724139Sjoerg { 108824139Sjoerg clear_message(); 108924139Sjoerg } 109024139Sjoerg break; 109124139Sjoerg#endif 1092168799Srafan case CMD_jidtog: 1093168799Srafan ps.jail = !ps.jail; 1094168799Srafan new_message(MT_standout | MT_delayed, 1095169257Srafan " %sisplaying jail ID.", 1096168799Srafan ps.jail ? "D" : "Not d"); 1097168799Srafan header_text = format_header(uname_field); 1098168799Srafan reset_display(); 1099168799Srafan putchar('\r'); 1100168799Srafan break; 1101265249Sbdrewery 1102265249Sbdrewery case CMD_jail: 1103265249Sbdrewery new_message(MT_standout, 1104265249Sbdrewery "Jail to show: "); 1105265249Sbdrewery if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 1106265249Sbdrewery { 1107265249Sbdrewery if (tempbuf2[0] == '+' && 1108265249Sbdrewery tempbuf2[1] == '\0') 1109265249Sbdrewery { 1110265249Sbdrewery ps.jid = -1; 1111265249Sbdrewery } 1112265249Sbdrewery else if ((i = jail_getid(tempbuf2)) == -1) 1113265249Sbdrewery { 1114265249Sbdrewery new_message(MT_standout, 1115265249Sbdrewery " %s: unknown jail", tempbuf2); 1116265249Sbdrewery no_command = Yes; 1117265249Sbdrewery } 1118265249Sbdrewery else 1119265249Sbdrewery { 1120265249Sbdrewery ps.jid = i; 1121265249Sbdrewery } 1122265249Sbdrewery if (ps.jail == 0) { 1123265249Sbdrewery ps.jail = 1; 1124265249Sbdrewery new_message(MT_standout | 1125265249Sbdrewery MT_delayed, " Displaying jail " 1126265249Sbdrewery "ID."); 1127265249Sbdrewery header_text = 1128265249Sbdrewery format_header(uname_field); 1129265249Sbdrewery reset_display(); 1130265249Sbdrewery } 1131265249Sbdrewery putchar('\r'); 1132265249Sbdrewery } 1133265249Sbdrewery else 1134265249Sbdrewery { 1135265249Sbdrewery clear_message(); 1136265249Sbdrewery } 1137265249Sbdrewery break; 1138265249Sbdrewery 1139222530Sjhb case CMD_kidletog: 1140222530Sjhb ps.kidle = !ps.kidle; 1141222530Sjhb new_message(MT_standout | MT_delayed, 1142222530Sjhb " %sisplaying system idle process.", 1143222530Sjhb ps.kidle ? "D" : "Not d"); 1144222530Sjhb putchar('\r'); 1145222530Sjhb break; 1146223936Sjhb case CMD_pcputog: 1147223936Sjhb pcpu_stats = !pcpu_stats; 1148223936Sjhb new_message(MT_standout | MT_delayed, 1149223936Sjhb " Displaying %sCPU statistics.", 1150223936Sjhb pcpu_stats ? "per-" : "global "); 1151224205Sjhb toggle_pcpustats(); 1152223936Sjhb max_topn = display_updatecpus(&statics); 1153223936Sjhb reset_display(); 1154223936Sjhb putchar('\r'); 1155223936Sjhb break; 115624139Sjoerg default: 115724139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 115824139Sjoerg putchar('\r'); 115924139Sjoerg } 116024139Sjoerg } 116124139Sjoerg 116224139Sjoerg /* flush out stuff that may have been written */ 116324139Sjoerg fflush(stdout); 116424139Sjoerg } 116524139Sjoerg } 116624139Sjoerg } 116724139Sjoerg } 116824139Sjoerg 116989757Sdwmalone#ifdef DEBUG 117089757Sdwmalone fclose(debug); 117189757Sdwmalone#endif 117224139Sjoerg quit(0); 117324139Sjoerg /*NOTREACHED*/ 117424139Sjoerg} 117524139Sjoerg 117624139Sjoerg/* 117724139Sjoerg * reset_display() - reset all the display routine pointers so that entire 117824139Sjoerg * screen will get redrawn. 117924139Sjoerg */ 118024139Sjoerg 118124139Sjoergreset_display() 118224139Sjoerg 118324139Sjoerg{ 118424139Sjoerg d_loadave = i_loadave; 118524139Sjoerg d_procstates = i_procstates; 118624139Sjoerg d_cpustates = i_cpustates; 118724139Sjoerg d_memory = i_memory; 1188237656Sjhb d_arc = i_arc; 118924142Sjoerg d_swap = i_swap; 119024139Sjoerg d_message = i_message; 119124139Sjoerg d_header = i_header; 119224139Sjoerg d_process = i_process; 119324139Sjoerg} 119424139Sjoerg 119524139Sjoerg/* 119624139Sjoerg * signal handlers 119724139Sjoerg */ 119824139Sjoerg 119924139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 120024139Sjoerg 120124139Sjoerg{ 120281187Skris leaveflag = 1; 120324139Sjoerg} 120424139Sjoerg 120524139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 120624139Sjoerg 120724139Sjoergint i; 120824139Sjoerg 120924139Sjoerg{ 121081187Skris tstopflag = 1; 121124139Sjoerg} 121224139Sjoerg 121324139Sjoerg#ifdef SIGWINCH 121424139Sjoergsigret_t winch(i) /* SIGWINCH handler */ 121524139Sjoerg 121624139Sjoergint i; 121724139Sjoerg 121824139Sjoerg{ 121981187Skris winchflag = 1; 122024139Sjoerg} 122124139Sjoerg#endif 122224139Sjoerg 122324139Sjoergvoid quit(status) /* exit under duress */ 122424139Sjoerg 122524139Sjoergint status; 122624139Sjoerg 122724139Sjoerg{ 122824139Sjoerg end_screen(); 122924139Sjoerg exit(status); 123024139Sjoerg /*NOTREACHED*/ 123124139Sjoerg} 1232