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 332948 2018-04-24 17:37:29Z lidl $ 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> 42332948Slidl#include <curses.h> 43300395Sngie#include <errno.h> 44265249Sbdrewery#include <jail.h> 45300395Sngie#include <setjmp.h> 46300395Sngie#include <signal.h> 47300395Sngie#include <unistd.h> 4824139Sjoerg 4924139Sjoerg/* includes specific to top */ 50300395Sngie#include "commands.h" 5124139Sjoerg#include "display.h" /* interface to display package */ 5224139Sjoerg#include "screen.h" /* interface to screen package */ 5324139Sjoerg#include "top.h" 5424139Sjoerg#include "top.local.h" 5524139Sjoerg#include "boolean.h" 5624139Sjoerg#include "machine.h" 5724139Sjoerg#include "utils.h" 58300395Sngie#include "username.h" 5924139Sjoerg 6024139Sjoerg/* Size of the stdio buffer given to stdout */ 6124139Sjoerg#define Buffersize 2048 6224139Sjoerg 6324139Sjoerg/* The buffer that stdio will use */ 6424139Sjoergchar stdoutbuf[Buffersize]; 6524139Sjoerg 6624139Sjoerg/* build Signal masks */ 6724139Sjoerg#define Smask(s) (1 << ((s) - 1)) 6824139Sjoerg 6924139Sjoerg/* for getopt: */ 7024139Sjoergextern int optind; 7124139Sjoergextern char *optarg; 7224139Sjoerg 7324139Sjoerg/* imported from screen.c */ 7424139Sjoergextern int overstrike; 7524139Sjoerg 76168710Sstasstatic int fmt_flags = 0; 77175420Speterint pcpu_stats = No; 78168710Sstas 7924139Sjoerg/* signal handling routines */ 8024139Sjoergsigret_t leave(); 8124139Sjoergsigret_t tstop(); 8224139Sjoerg#ifdef SIGWINCH 83332948Slidlsigret_t top_winch(int); 8424139Sjoerg#endif 8524139Sjoerg 8681187Skrisvolatile sig_atomic_t leaveflag; 8781187Skrisvolatile sig_atomic_t tstopflag; 8881187Skrisvolatile sig_atomic_t winchflag; 8981187Skris 9024139Sjoerg/* internal routines */ 9124139Sjoergvoid quit(); 9224139Sjoerg 9324139Sjoerg/* values which need to be accessed by signal handlers */ 9424139Sjoergstatic int max_topn; /* maximum displayable processes */ 9524139Sjoerg 9624139Sjoerg/* miscellaneous things */ 97145073Skeramidastruct process_select ps; 9824139Sjoergchar *myname = "top"; 9924139Sjoergjmp_buf jmp_int; 10024139Sjoerg 10124139Sjoerg/* routines that don't return int */ 10224139Sjoerg 10324139Sjoergchar *username(); 10424139Sjoergchar *ctime(); 10524139Sjoergchar *kill_procs(); 10624139Sjoergchar *renice_procs(); 10724139Sjoerg 10824139Sjoerg#ifdef ORDER 109133817Salfredextern int (*compares[])(); 11024139Sjoerg#else 11124139Sjoergextern int proc_compare(); 112131829Skeramidaextern int io_compare(); 11324139Sjoerg#endif 11424139Sjoergtime_t time(); 11524139Sjoerg 11624139Sjoergcaddr_t get_process_info(); 11724139Sjoerg 11824139Sjoerg/* different routines for displaying the user's identification */ 11924139Sjoerg/* (values assigned to get_userid) */ 12024139Sjoergchar *username(); 12124139Sjoergchar *itoa7(); 12224139Sjoerg 12324139Sjoerg/* pointers to display routines */ 124300395Sngievoid (*d_loadave)() = i_loadave; 125300395Sngievoid (*d_procstates)() = i_procstates; 126300395Sngievoid (*d_cpustates)() = i_cpustates; 127300395Sngievoid (*d_memory)() = i_memory; 128300395Sngievoid (*d_arc)() = i_arc; 129318449Sallanjudevoid (*d_carc)() = i_carc; 130300395Sngievoid (*d_swap)() = i_swap; 131300395Sngievoid (*d_message)() = i_message; 132300395Sngievoid (*d_header)() = i_header; 133300395Sngievoid (*d_process)() = i_process; 13424139Sjoerg 135300395Sngievoid reset_display(void); 13624139Sjoerg 137322509Sgahrstatic void 138322509Sgahrreset_uids() 139322509Sgahr{ 140322509Sgahr for (size_t i = 0; i < TOP_MAX_UIDS; ++i) 141322509Sgahr ps.uid[i] = -1; 142322509Sgahr} 143300395Sngie 144322509Sgahrstatic int 145322509Sgahradd_uid(int uid) 146322509Sgahr{ 147322509Sgahr size_t i = 0; 148322509Sgahr 149322509Sgahr /* Add the uid if there's room */ 150322509Sgahr for (; i < TOP_MAX_UIDS; ++i) 151322509Sgahr { 152322509Sgahr if (ps.uid[i] == -1 || ps.uid[i] == uid) 153322509Sgahr { 154322509Sgahr ps.uid[i] = uid; 155322509Sgahr break; 156322509Sgahr } 157322509Sgahr } 158322509Sgahr 159322509Sgahr return (i == TOP_MAX_UIDS); 160322509Sgahr} 161322509Sgahr 162322509Sgahrstatic void 163322509Sgahrrem_uid(int uid) 164322509Sgahr{ 165322509Sgahr size_t i = 0; 166322509Sgahr size_t where = TOP_MAX_UIDS; 167322509Sgahr 168322509Sgahr /* Look for the user to remove - no problem if it's not there */ 169322509Sgahr for (; i < TOP_MAX_UIDS; ++i) 170322509Sgahr { 171322509Sgahr if (ps.uid[i] == -1) 172322509Sgahr break; 173322509Sgahr if (ps.uid[i] == uid) 174322509Sgahr where = i; 175322509Sgahr } 176322509Sgahr 177322509Sgahr /* Make sure we don't leave a hole in the middle */ 178322509Sgahr if (where != TOP_MAX_UIDS) 179322509Sgahr { 180322509Sgahr ps.uid[where] = ps.uid[i-1]; 181322509Sgahr ps.uid[i-1] = -1; 182322509Sgahr } 183322509Sgahr} 184322509Sgahr 185322509Sgahrstatic int 186322509Sgahrhandle_user(char *buf, size_t buflen) 187322509Sgahr{ 188322509Sgahr int rc = 0; 189322509Sgahr int uid = -1; 190322509Sgahr char *buf2 = buf; 191322509Sgahr 192322509Sgahr new_message(MT_standout, "Username to show (+ for all): "); 193322509Sgahr if (readline(buf, buflen, No) <= 0) 194322509Sgahr { 195322509Sgahr clear_message(); 196322509Sgahr return rc; 197322509Sgahr } 198322509Sgahr 199322509Sgahr if (buf[0] == '+' || buf[0] == '-') 200322509Sgahr { 201322509Sgahr if (buf[1] == '\0') 202322509Sgahr { 203322509Sgahr reset_uids(); 204322509Sgahr goto end; 205322509Sgahr } 206322509Sgahr else 207322509Sgahr ++buf2; 208322509Sgahr } 209322509Sgahr 210322509Sgahr if ((uid = userid(buf2)) == -1) 211322509Sgahr { 212322509Sgahr new_message(MT_standout, " %s: unknown user", buf2); 213322509Sgahr rc = 1; 214322509Sgahr goto end; 215322509Sgahr } 216322509Sgahr 217322509Sgahr if (buf2 == buf) 218322509Sgahr { 219322509Sgahr reset_uids(); 220322509Sgahr ps.uid[0] = uid; 221322509Sgahr goto end; 222322509Sgahr } 223322509Sgahr 224322509Sgahr if (buf[0] == '+') 225322509Sgahr { 226322509Sgahr if (add_uid(uid)) 227322509Sgahr { 228322509Sgahr new_message(MT_standout, " too many users, reset with '+'"); 229322509Sgahr rc = 1; 230322509Sgahr goto end; 231322509Sgahr } 232322509Sgahr } 233322509Sgahr else 234322509Sgahr rem_uid(uid); 235322509Sgahr 236322509Sgahrend: 237322509Sgahr putchar('\r'); 238322509Sgahr return rc; 239322509Sgahr} 240322509Sgahr 241300395Sngieint 24224139Sjoergmain(argc, argv) 24324139Sjoerg 24424139Sjoergint argc; 24524139Sjoergchar *argv[]; 24624139Sjoerg 24724139Sjoerg{ 24824139Sjoerg register int i; 24924139Sjoerg register int active_procs; 25024139Sjoerg register int change; 25124139Sjoerg 25224139Sjoerg struct system_info system_info; 25324139Sjoerg struct statics statics; 25424139Sjoerg caddr_t processes; 25524139Sjoerg 25624139Sjoerg static char tempbuf1[50]; 25724139Sjoerg static char tempbuf2[50]; 25824139Sjoerg int old_sigmask; /* only used for BSD-style signals */ 25924139Sjoerg int topn = Default_TOPN; 26024139Sjoerg int delay = Default_DELAY; 26124139Sjoerg int displays = 0; /* indicates unspecified */ 26286042Sdwmalone int sel_ret = 0; 26324139Sjoerg time_t curr_time; 26424139Sjoerg char *(*get_userid)() = username; 26524139Sjoerg char *uname_field = "USERNAME"; 26624139Sjoerg char *header_text; 26724139Sjoerg char *env_top; 26824139Sjoerg char **preset_argv; 26924139Sjoerg int preset_argc = 0; 27024139Sjoerg char **av; 27124139Sjoerg int ac; 27224139Sjoerg char dostates = No; 27324139Sjoerg char do_unames = Yes; 27424139Sjoerg char interactive = Maybe; 27524139Sjoerg char warnings = 0; 27624139Sjoerg#if Default_TOPN == Infinity 27724139Sjoerg char topn_specified = No; 27824139Sjoerg#endif 27924139Sjoerg char ch; 28024139Sjoerg char *iptr; 28124139Sjoerg char no_command = 1; 28224139Sjoerg struct timeval timeout; 28324139Sjoerg#ifdef ORDER 28424139Sjoerg char *order_name = NULL; 28524139Sjoerg int order_index = 0; 28624139Sjoerg#endif 28724139Sjoerg#ifndef FD_SET 28824139Sjoerg /* FD_SET and friends are not present: fake it */ 28924139Sjoerg typedef int fd_set; 29024139Sjoerg#define FD_ZERO(x) (*(x) = 0) 29189757Sdwmalone#define FD_SET(f, x) (*(x) = 1<<f) 29224139Sjoerg#endif 29324139Sjoerg fd_set readfds; 29424139Sjoerg 29524139Sjoerg#ifdef ORDER 296307757Sdes static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJwo"; 29724139Sjoerg#else 298307757Sdes static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPJw"; 29924139Sjoerg#endif 30024139Sjoerg/* these defines enumerate the "strchr"s of the commands in command_chars */ 30124139Sjoerg#define CMD_redraw 0 30224139Sjoerg#define CMD_update 1 30324139Sjoerg#define CMD_quit 2 30424139Sjoerg#define CMD_help1 3 30524139Sjoerg#define CMD_help2 4 30624139Sjoerg#define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */ 30724139Sjoerg#define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */ 30824139Sjoerg#define CMD_number1 6 30924139Sjoerg#define CMD_number2 7 31024139Sjoerg#define CMD_delay 8 31124139Sjoerg#define CMD_displays 9 31224139Sjoerg#define CMD_kill 10 31324139Sjoerg#define CMD_renice 11 31424139Sjoerg#define CMD_idletog 12 31524139Sjoerg#define CMD_idletog2 13 31624139Sjoerg#define CMD_user 14 31738090Sdes#define CMD_selftog 15 318117709Sjulian#define CMD_thrtog 16 319131402Salfred#define CMD_viewtog 17 320132005Salfred#define CMD_viewsys 18 321146342Skeramida#define CMD_wcputog 19 322168710Sstas#define CMD_showargs 20 323168799Srafan#define CMD_jidtog 21 324222530Sjhb#define CMD_kidletog 22 325223936Sjhb#define CMD_pcputog 23 326265249Sbdrewery#define CMD_jail 24 327307757Sdes#define CMD_swaptog 25 32824139Sjoerg#ifdef ORDER 329307757Sdes#define CMD_order 26 33024139Sjoerg#endif 33124139Sjoerg 33224139Sjoerg /* set the buffer for stdout */ 33324139Sjoerg#ifdef DEBUG 33489757Sdwmalone extern FILE *debug; 33589757Sdwmalone debug = fopen("debug.run", "w"); 33624139Sjoerg setbuffer(stdout, NULL, 0); 33724139Sjoerg#else 33824139Sjoerg setbuffer(stdout, stdoutbuf, Buffersize); 33924139Sjoerg#endif 34024139Sjoerg 34124139Sjoerg /* get our name */ 34224139Sjoerg if (argc > 0) 34324139Sjoerg { 34424139Sjoerg if ((myname = strrchr(argv[0], '/')) == 0) 34524139Sjoerg { 34624139Sjoerg myname = argv[0]; 34724139Sjoerg } 34824139Sjoerg else 34924139Sjoerg { 35024139Sjoerg myname++; 35124139Sjoerg } 35224139Sjoerg } 35324139Sjoerg 35424139Sjoerg /* initialize some selection options */ 35524139Sjoerg ps.idle = Yes; 35638090Sdes ps.self = -1; 35724139Sjoerg ps.system = No; 358322509Sgahr reset_uids(); 359117709Sjulian ps.thread = No; 360146342Skeramida ps.wcpu = 1; 361265249Sbdrewery ps.jid = -1; 362168799Srafan ps.jail = No; 363307757Sdes ps.swap = No; 364222530Sjhb ps.kidle = Yes; 36524139Sjoerg ps.command = NULL; 36624139Sjoerg 36724139Sjoerg /* get preset options from the environment */ 36824139Sjoerg if ((env_top = getenv("TOP")) != NULL) 36924139Sjoerg { 37024139Sjoerg av = preset_argv = argparse(env_top, &preset_argc); 37124139Sjoerg ac = preset_argc; 37224139Sjoerg 37324139Sjoerg /* set the dummy argument to an explanatory message, in case 37424139Sjoerg getopt encounters a bad argument */ 37524139Sjoerg preset_argv[0] = "while processing environment"; 37624139Sjoerg } 37724139Sjoerg 37824139Sjoerg /* process options */ 37924139Sjoerg do { 38024139Sjoerg /* if we're done doing the presets, then process the real arguments */ 38124139Sjoerg if (preset_argc == 0) 38224139Sjoerg { 38324139Sjoerg ac = argc; 38424139Sjoerg av = argv; 38524139Sjoerg 38624139Sjoerg /* this should keep getopt happy... */ 38724139Sjoerg optind = 1; 38824139Sjoerg } 38924139Sjoerg 390307757Sdes while ((i = getopt(ac, av, "CSIHPabijJ:nquvzs:d:U:m:o:tw")) != EOF) 39124139Sjoerg { 39224139Sjoerg switch(i) 39324139Sjoerg { 39489757Sdwmalone case 'v': /* show version number */ 39589757Sdwmalone fprintf(stderr, "%s: version %s\n", 39689757Sdwmalone myname, version_string()); 39789757Sdwmalone exit(1); 39889757Sdwmalone break; 39989757Sdwmalone 40024139Sjoerg case 'u': /* toggle uid/username display */ 40124139Sjoerg do_unames = !do_unames; 40224139Sjoerg break; 40324139Sjoerg 40424139Sjoerg case 'U': /* display only username's processes */ 405322509Sgahr if ((ps.uid[0] = userid(optarg)) == -1) 40624139Sjoerg { 40724139Sjoerg fprintf(stderr, "%s: unknown user\n", optarg); 40824139Sjoerg exit(1); 40924139Sjoerg } 41024139Sjoerg break; 41124139Sjoerg 41224139Sjoerg case 'S': /* show system processes */ 41324139Sjoerg ps.system = !ps.system; 41424139Sjoerg break; 41524139Sjoerg 41624139Sjoerg case 'I': /* show idle processes */ 41724139Sjoerg ps.idle = !ps.idle; 41824139Sjoerg break; 41924139Sjoerg 42024139Sjoerg case 'i': /* go interactive regardless */ 42124139Sjoerg interactive = Yes; 42224139Sjoerg break; 42324139Sjoerg 42424139Sjoerg case 'n': /* batch, or non-interactive */ 42524139Sjoerg case 'b': 42624139Sjoerg interactive = No; 42724139Sjoerg break; 42824139Sjoerg 429168710Sstas case 'a': 430168710Sstas fmt_flags ^= FMT_SHOWARGS; 431168710Sstas break; 432168710Sstas 43324139Sjoerg case 'd': /* number of displays to show */ 43424139Sjoerg if ((i = atoiwi(optarg)) == Invalid || i == 0) 43524139Sjoerg { 43624139Sjoerg fprintf(stderr, 43724139Sjoerg "%s: warning: display count should be positive -- option ignored\n", 43824139Sjoerg myname); 43924139Sjoerg warnings++; 44024139Sjoerg } 44124139Sjoerg else 44224139Sjoerg { 44324139Sjoerg displays = i; 44424139Sjoerg } 44524139Sjoerg break; 44624139Sjoerg 44724139Sjoerg case 's': 44889757Sdwmalone if ((delay = atoi(optarg)) < 0 || (delay == 0 && getuid() != 0)) 44924139Sjoerg { 45024139Sjoerg fprintf(stderr, 45189757Sdwmalone "%s: warning: seconds delay should be positive -- using default\n", 45224139Sjoerg myname); 45324139Sjoerg delay = Default_DELAY; 45424139Sjoerg warnings++; 45524139Sjoerg } 45624139Sjoerg break; 45724139Sjoerg 45824139Sjoerg case 'q': /* be quick about it */ 45924139Sjoerg /* only allow this if user is really root */ 46024139Sjoerg if (getuid() == 0) 46124139Sjoerg { 46224139Sjoerg /* be very un-nice! */ 46324139Sjoerg (void) nice(-20); 46424139Sjoerg } 46524139Sjoerg else 46624139Sjoerg { 46724139Sjoerg fprintf(stderr, 46824139Sjoerg "%s: warning: `-q' option can only be used by root\n", 46924139Sjoerg myname); 47024139Sjoerg warnings++; 47124139Sjoerg } 47224139Sjoerg break; 47324139Sjoerg 474131616Sdes case 'm': /* select display mode */ 475131402Salfred if (strcmp(optarg, "io") == 0) { 476131402Salfred displaymode = DISP_IO; 477131402Salfred } else if (strcmp(optarg, "cpu") == 0) { 478131402Salfred displaymode = DISP_CPU; 479131402Salfred } else { 480131402Salfred fprintf(stderr, 481131402Salfred "%s: warning: `-m' option can only take args " 482131402Salfred "'io' or 'cpu'\n", 483131402Salfred myname); 484131402Salfred exit(1); 485131402Salfred } 486131402Salfred break; 487131402Salfred 48824139Sjoerg case 'o': /* select sort order */ 48924139Sjoerg#ifdef ORDER 49024139Sjoerg order_name = optarg; 49124139Sjoerg#else 49224139Sjoerg fprintf(stderr, 49324139Sjoerg "%s: this platform does not support arbitrary ordering. Sorry.\n", 49424139Sjoerg myname); 49524139Sjoerg warnings++; 49624139Sjoerg#endif 49724139Sjoerg break; 49824139Sjoerg 49938090Sdes case 't': 50038090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 50138090Sdes break; 502146342Skeramida 503146342Skeramida case 'C': 504146342Skeramida ps.wcpu = !ps.wcpu; 505146342Skeramida break; 506146342Skeramida 507117709Sjulian case 'H': 508117709Sjulian ps.thread = !ps.thread; 509117709Sjulian break; 510146342Skeramida 511168799Srafan case 'j': 512168799Srafan ps.jail = !ps.jail; 513168799Srafan break; 514168799Srafan 515265249Sbdrewery case 'J': /* display only jail's processes */ 516265249Sbdrewery if ((ps.jid = jail_getid(optarg)) == -1) 517265249Sbdrewery { 518265249Sbdrewery fprintf(stderr, "%s: unknown jail\n", optarg); 519265249Sbdrewery exit(1); 520265249Sbdrewery } 521265249Sbdrewery ps.jail = 1; 522265249Sbdrewery break; 523265249Sbdrewery 524175420Speter case 'P': 525223936Sjhb pcpu_stats = !pcpu_stats; 526175420Speter break; 527175420Speter 528307757Sdes case 'w': 529307757Sdes ps.swap = 1; 530307757Sdes break; 531307757Sdes 532222530Sjhb case 'z': 533222530Sjhb ps.kidle = !ps.kidle; 534222530Sjhb break; 535222530Sjhb 53624139Sjoerg default: 537157842Sru fprintf(stderr, 538157842Sru"Top version %s\n" 539330630Seadler"Usage: %s [-abCHIijnPqStuvwz] [-d count] [-m io | cpu] [-o field] [-s time]\n" 540265249Sbdrewery" [-J jail] [-U username] [number]\n", 54124139Sjoerg version_string(), myname); 54224139Sjoerg exit(1); 54324139Sjoerg } 54424139Sjoerg } 54524139Sjoerg 54624139Sjoerg /* get count of top processes to display (if any) */ 54724139Sjoerg if (optind < ac) 54824139Sjoerg { 54924139Sjoerg if ((topn = atoiwi(av[optind])) == Invalid) 55024139Sjoerg { 55124139Sjoerg fprintf(stderr, 55224139Sjoerg "%s: warning: process display count should be non-negative -- using default\n", 55324139Sjoerg myname); 55424139Sjoerg warnings++; 55524139Sjoerg } 55624139Sjoerg#if Default_TOPN == Infinity 55724139Sjoerg else 55824139Sjoerg { 55924139Sjoerg topn_specified = Yes; 56024139Sjoerg } 56124139Sjoerg#endif 56224139Sjoerg } 56324139Sjoerg 56424139Sjoerg /* tricky: remember old value of preset_argc & set preset_argc = 0 */ 56524139Sjoerg i = preset_argc; 56624139Sjoerg preset_argc = 0; 56724139Sjoerg 56824139Sjoerg /* repeat only if we really did the preset arguments */ 56924139Sjoerg } while (i != 0); 57024139Sjoerg 57124139Sjoerg /* set constants for username/uid display correctly */ 57224139Sjoerg if (!do_unames) 57324139Sjoerg { 57424139Sjoerg uname_field = " UID "; 57524139Sjoerg get_userid = itoa7; 57624139Sjoerg } 57724139Sjoerg 57824139Sjoerg /* initialize the kernel memory interface */ 579175195Sobrien if (machine_init(&statics, do_unames) == -1) 58024139Sjoerg { 58124139Sjoerg exit(1); 58224139Sjoerg } 58324139Sjoerg 58424139Sjoerg#ifdef ORDER 58524139Sjoerg /* determine sorting order index, if necessary */ 58624139Sjoerg if (order_name != NULL) 58724139Sjoerg { 58824139Sjoerg if ((order_index = string_index(order_name, statics.order_names)) == -1) 58924139Sjoerg { 59024139Sjoerg char **pp; 59124139Sjoerg 59224139Sjoerg fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n", 59324139Sjoerg myname, order_name); 59424139Sjoerg fprintf(stderr, "\tTry one of these:"); 59524139Sjoerg pp = statics.order_names; 59624139Sjoerg while (*pp != NULL) 59724139Sjoerg { 59824139Sjoerg fprintf(stderr, " %s", *pp++); 59924139Sjoerg } 60024139Sjoerg fputc('\n', stderr); 60124139Sjoerg exit(1); 60224139Sjoerg } 60324139Sjoerg } 60424139Sjoerg#endif 60524139Sjoerg 60624139Sjoerg#ifdef no_initialization_needed 60724139Sjoerg /* initialize the hashing stuff */ 60824139Sjoerg if (do_unames) 60924139Sjoerg { 61024139Sjoerg init_hash(); 61124139Sjoerg } 61224139Sjoerg#endif 61324139Sjoerg 61424139Sjoerg /* initialize termcap */ 61524139Sjoerg init_termcap(interactive); 61624139Sjoerg 61724139Sjoerg /* get the string to use for the process area header */ 61824139Sjoerg header_text = format_header(uname_field); 61924139Sjoerg 62024139Sjoerg /* initialize display interface */ 62124139Sjoerg if ((max_topn = display_init(&statics)) == -1) 62224139Sjoerg { 62324139Sjoerg fprintf(stderr, "%s: can't allocate sufficient memory\n", myname); 62424139Sjoerg exit(4); 62524139Sjoerg } 62624139Sjoerg 62724139Sjoerg /* print warning if user requested more processes than we can display */ 62824139Sjoerg if (topn > max_topn) 62924139Sjoerg { 63024139Sjoerg fprintf(stderr, 63124139Sjoerg "%s: warning: this terminal can only display %d processes.\n", 63224139Sjoerg myname, max_topn); 63324139Sjoerg warnings++; 63424139Sjoerg } 63524139Sjoerg 63624139Sjoerg /* adjust for topn == Infinity */ 63724139Sjoerg if (topn == Infinity) 63824139Sjoerg { 63924139Sjoerg /* 64024139Sjoerg * For smart terminals, infinity really means everything that can 64124139Sjoerg * be displayed, or Largest. 64224139Sjoerg * On dumb terminals, infinity means every process in the system! 64324139Sjoerg * We only really want to do that if it was explicitly specified. 64424139Sjoerg * This is always the case when "Default_TOPN != Infinity". But if 64524139Sjoerg * topn wasn't explicitly specified and we are on a dumb terminal 64624139Sjoerg * and the default is Infinity, then (and only then) we use 64724139Sjoerg * "Nominal_TOPN" instead. 64824139Sjoerg */ 64924139Sjoerg#if Default_TOPN == Infinity 65024139Sjoerg topn = smart_terminal ? Largest : 65124139Sjoerg (topn_specified ? Largest : Nominal_TOPN); 65224139Sjoerg#else 65324139Sjoerg topn = Largest; 65424139Sjoerg#endif 65524139Sjoerg } 65624139Sjoerg 65724139Sjoerg /* set header display accordingly */ 65824139Sjoerg display_header(topn > 0); 65924139Sjoerg 66024139Sjoerg /* determine interactive state */ 66124139Sjoerg if (interactive == Maybe) 66224139Sjoerg { 66324139Sjoerg interactive = smart_terminal; 66424139Sjoerg } 66524139Sjoerg 66624139Sjoerg /* if # of displays not specified, fill it in */ 66724139Sjoerg if (displays == 0) 66824139Sjoerg { 66924139Sjoerg displays = smart_terminal ? Infinity : 1; 67024139Sjoerg } 67124139Sjoerg 67224139Sjoerg /* hold interrupt signals while setting up the screen and the handlers */ 67324139Sjoerg#ifdef SIGHOLD 67424139Sjoerg sighold(SIGINT); 67524139Sjoerg sighold(SIGQUIT); 67624139Sjoerg sighold(SIGTSTP); 67724139Sjoerg#else 67824139Sjoerg old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP)); 67924139Sjoerg#endif 68024139Sjoerg init_screen(); 68124139Sjoerg (void) signal(SIGINT, leave); 68224139Sjoerg (void) signal(SIGQUIT, leave); 68324139Sjoerg (void) signal(SIGTSTP, tstop); 68424139Sjoerg#ifdef SIGWINCH 685332948Slidl (void) signal(SIGWINCH, top_winch); 68624139Sjoerg#endif 68724139Sjoerg#ifdef SIGRELSE 68824139Sjoerg sigrelse(SIGINT); 68924139Sjoerg sigrelse(SIGQUIT); 69024139Sjoerg sigrelse(SIGTSTP); 69124139Sjoerg#else 69224139Sjoerg (void) sigsetmask(old_sigmask); 69324139Sjoerg#endif 69424139Sjoerg if (warnings) 69524139Sjoerg { 69624139Sjoerg fputs("....", stderr); 69724139Sjoerg fflush(stderr); /* why must I do this? */ 69824139Sjoerg sleep((unsigned)(3 * warnings)); 69924139Sjoerg fputc('\n', stderr); 70024139Sjoerg } 70124139Sjoerg 70281187Skrisrestart: 70324139Sjoerg 70424139Sjoerg /* 70524139Sjoerg * main loop -- repeat while display count is positive or while it 70624139Sjoerg * indicates infinity (by being -1) 70724139Sjoerg */ 70824139Sjoerg 70924139Sjoerg while ((displays == -1) || (displays-- > 0)) 71024139Sjoerg { 711131402Salfred int (*compare)(); 712131402Salfred 713131402Salfred 71424139Sjoerg /* get the current stats */ 71524139Sjoerg get_system_info(&system_info); 71624139Sjoerg 71724139Sjoerg#ifdef ORDER 718133817Salfred compare = compares[order_index]; 71924139Sjoerg#else 720131829Skeramida if (displaymode == DISP_CPU) 721131402Salfred compare = proc_compare; 722131829Skeramida else 723131829Skeramida compare = io_compare; 72424139Sjoerg#endif 72524139Sjoerg 726131402Salfred /* get the current set of processes */ 727131402Salfred processes = 728131402Salfred get_process_info(&system_info, &ps, compare); 729131402Salfred 73024139Sjoerg /* display the load averages */ 73124139Sjoerg (*d_loadave)(system_info.last_pid, 73224139Sjoerg system_info.load_avg); 73324139Sjoerg 73424139Sjoerg /* display the current time */ 73524139Sjoerg /* this method of getting the time SHOULD be fairly portable */ 73624139Sjoerg time(&curr_time); 73742447Sobrien i_uptime(&system_info.boottime, &curr_time); 73824139Sjoerg i_timeofday(&curr_time); 73924139Sjoerg 74024139Sjoerg /* display process state breakdown */ 74124139Sjoerg (*d_procstates)(system_info.p_total, 74224139Sjoerg system_info.procstates); 74324139Sjoerg 74424139Sjoerg /* display the cpu state percentage breakdown */ 74524139Sjoerg if (dostates) /* but not the first time */ 74624139Sjoerg { 74724139Sjoerg (*d_cpustates)(system_info.cpustates); 74824139Sjoerg } 74924139Sjoerg else 75024139Sjoerg { 75124139Sjoerg /* we'll do it next time */ 75224139Sjoerg if (smart_terminal) 75324139Sjoerg { 75424139Sjoerg z_cpustates(); 75524139Sjoerg } 75624139Sjoerg else 75724139Sjoerg { 75824139Sjoerg putchar('\n'); 75924139Sjoerg } 76024139Sjoerg dostates = Yes; 76124139Sjoerg } 76224139Sjoerg 76324139Sjoerg /* display memory stats */ 76424139Sjoerg (*d_memory)(system_info.memory); 765237656Sjhb (*d_arc)(system_info.arc); 766318449Sallanjude (*d_carc)(system_info.carc); 76724139Sjoerg 76824142Sjoerg /* display swap stats */ 76924142Sjoerg (*d_swap)(system_info.swap); 77024142Sjoerg 77124139Sjoerg /* handle message area */ 77224139Sjoerg (*d_message)(); 77324139Sjoerg 77424139Sjoerg /* update the header area */ 77524139Sjoerg (*d_header)(header_text); 77624139Sjoerg 77724139Sjoerg if (topn > 0) 77824139Sjoerg { 77924139Sjoerg /* determine number of processes to actually display */ 78024139Sjoerg /* this number will be the smallest of: active processes, 78124139Sjoerg number user requested, number current screen accomodates */ 78289757Sdwmalone active_procs = system_info.P_ACTIVE; 78324139Sjoerg if (active_procs > topn) 78424139Sjoerg { 78524139Sjoerg active_procs = topn; 78624139Sjoerg } 78724139Sjoerg if (active_procs > max_topn) 78824139Sjoerg { 78924139Sjoerg active_procs = max_topn; 79024139Sjoerg } 79124139Sjoerg 79224139Sjoerg /* now show the top "n" processes. */ 79324139Sjoerg for (i = 0; i < active_procs; i++) 79424139Sjoerg { 795168710Sstas (*d_process)(i, format_next_process(processes, get_userid, 796168710Sstas fmt_flags)); 79724139Sjoerg } 79824139Sjoerg } 79924139Sjoerg else 80024139Sjoerg { 80124139Sjoerg i = 0; 80224139Sjoerg } 80324139Sjoerg 80424139Sjoerg /* do end-screen processing */ 80524139Sjoerg u_endscreen(i); 80624139Sjoerg 80724139Sjoerg /* now, flush the output buffer */ 80889757Sdwmalone if (fflush(stdout) != 0) 80989757Sdwmalone { 81089757Sdwmalone new_message(MT_standout, " Write error on stdout"); 81189757Sdwmalone putchar('\r'); 81289757Sdwmalone quit(1); 81389757Sdwmalone /*NOTREACHED*/ 81489757Sdwmalone } 81524139Sjoerg 81624139Sjoerg /* only do the rest if we have more displays to show */ 81724139Sjoerg if (displays) 81824139Sjoerg { 81924139Sjoerg /* switch out for new display on smart terminals */ 82024139Sjoerg if (smart_terminal) 82124139Sjoerg { 82224139Sjoerg if (overstrike) 82324139Sjoerg { 82424139Sjoerg reset_display(); 82524139Sjoerg } 82624139Sjoerg else 82724139Sjoerg { 82824139Sjoerg d_loadave = u_loadave; 82924139Sjoerg d_procstates = u_procstates; 83024139Sjoerg d_cpustates = u_cpustates; 83124139Sjoerg d_memory = u_memory; 832237656Sjhb d_arc = u_arc; 833318449Sallanjude d_carc = u_carc; 83424142Sjoerg d_swap = u_swap; 83524139Sjoerg d_message = u_message; 83624139Sjoerg d_header = u_header; 83724139Sjoerg d_process = u_process; 83824139Sjoerg } 83924139Sjoerg } 84024139Sjoerg 84124139Sjoerg no_command = Yes; 84224139Sjoerg if (!interactive) 84324139Sjoerg { 844232239Skib sleep(delay); 845232660Skib if (leaveflag) { 846232660Skib end_screen(); 847232660Skib exit(0); 848232660Skib } 84924139Sjoerg } 85024139Sjoerg else while (no_command) 85124139Sjoerg { 85224139Sjoerg /* assume valid command unless told otherwise */ 85324139Sjoerg no_command = No; 85424139Sjoerg 85524139Sjoerg /* set up arguments for select with timeout */ 85624139Sjoerg FD_ZERO(&readfds); 85789757Sdwmalone FD_SET(0, &readfds); /* for standard input */ 85824139Sjoerg timeout.tv_sec = delay; 85924139Sjoerg timeout.tv_usec = 0; 86024139Sjoerg 86181187Skris if (leaveflag) { 86281187Skris end_screen(); 86381187Skris exit(0); 86481187Skris } 86581187Skris 86681187Skris if (tstopflag) { 86781187Skris /* move to the lower left */ 86881187Skris end_screen(); 86981187Skris fflush(stdout); 87081187Skris 87181187Skris /* default the signal handler action */ 87281187Skris (void) signal(SIGTSTP, SIG_DFL); 87381187Skris 87481187Skris /* unblock the signal and send ourselves one */ 87581187Skris#ifdef SIGRELSE 87681187Skris sigrelse(SIGTSTP); 87781187Skris#else 87881187Skris (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1))); 87981187Skris#endif 88081187Skris (void) kill(0, SIGTSTP); 88181187Skris 88281187Skris /* reset the signal handler */ 88381187Skris (void) signal(SIGTSTP, tstop); 88481187Skris 88581187Skris /* reinit screen */ 88681187Skris reinit_screen(); 88781187Skris reset_display(); 88881187Skris tstopflag = 0; 88981187Skris goto restart; 89081187Skris } 89181187Skris 89281187Skris if (winchflag) { 89381187Skris /* reascertain the screen dimensions */ 89481187Skris get_screensize(); 89581187Skris 89681187Skris /* tell display to resize */ 89781187Skris max_topn = display_resize(); 89881187Skris 89981187Skris /* reset the signal handler */ 900332948Slidl (void) signal(SIGWINCH, top_winch); 90181187Skris 90281187Skris reset_display(); 90381187Skris winchflag = 0; 90481187Skris goto restart; 90581187Skris } 90681187Skris 90724139Sjoerg /* wait for either input or the end of the delay period */ 90886042Sdwmalone sel_ret = select(2, &readfds, NULL, NULL, &timeout); 90986042Sdwmalone if (sel_ret < 0 && errno != EINTR) 91086042Sdwmalone quit(0); 91186042Sdwmalone if (sel_ret > 0) 91224139Sjoerg { 91324139Sjoerg int newval; 91424139Sjoerg char *errmsg; 91524139Sjoerg 91624139Sjoerg /* something to read -- clear the message area first */ 91724139Sjoerg clear_message(); 91824139Sjoerg 91924139Sjoerg /* now read it and convert to command strchr */ 92024139Sjoerg /* (use "change" as a temporary to hold strchr) */ 92186042Sdwmalone if (read(0, &ch, 1) != 1) 92289757Sdwmalone { 92389757Sdwmalone /* read error: either 0 or -1 */ 92489757Sdwmalone new_message(MT_standout, " Read error on stdin"); 92589757Sdwmalone putchar('\r'); 92689757Sdwmalone quit(1); 92789757Sdwmalone /*NOTREACHED*/ 92889757Sdwmalone } 92924139Sjoerg if ((iptr = strchr(command_chars, ch)) == NULL) 93024139Sjoerg { 93124142Sjoerg if (ch != '\r' && ch != '\n') 93224142Sjoerg { 93324142Sjoerg /* illegal command */ 93424142Sjoerg new_message(MT_standout, " Command not understood"); 93524142Sjoerg } 93624139Sjoerg putchar('\r'); 93724139Sjoerg no_command = Yes; 93824139Sjoerg } 93924139Sjoerg else 94024139Sjoerg { 94124139Sjoerg change = iptr - command_chars; 94224139Sjoerg if (overstrike && change > CMD_OSLIMIT) 94324139Sjoerg { 94424139Sjoerg /* error */ 94524139Sjoerg new_message(MT_standout, 94624139Sjoerg " Command cannot be handled by this terminal"); 94724139Sjoerg putchar('\r'); 94824139Sjoerg no_command = Yes; 94924139Sjoerg } 95024139Sjoerg else switch(change) 95124139Sjoerg { 95224139Sjoerg case CMD_redraw: /* redraw screen */ 95324139Sjoerg reset_display(); 95424139Sjoerg break; 95524139Sjoerg 95624139Sjoerg case CMD_update: /* merely update display */ 95724139Sjoerg /* is the load average high? */ 95824139Sjoerg if (system_info.load_avg[0] > LoadMax) 95924139Sjoerg { 96024139Sjoerg /* yes, go home for visual feedback */ 96124139Sjoerg go_home(); 96224139Sjoerg fflush(stdout); 96324139Sjoerg } 96424139Sjoerg break; 96524139Sjoerg 96624139Sjoerg case CMD_quit: /* quit */ 96724139Sjoerg quit(0); 96824139Sjoerg /*NOTREACHED*/ 96924139Sjoerg break; 97024139Sjoerg 97124139Sjoerg case CMD_help1: /* help */ 97224139Sjoerg case CMD_help2: 97324139Sjoerg reset_display(); 974332948Slidl top_clear(); 97524139Sjoerg show_help(); 976332948Slidl top_standout("Hit any key to continue: "); 97724139Sjoerg fflush(stdout); 97824139Sjoerg (void) read(0, &ch, 1); 97924139Sjoerg break; 98024139Sjoerg 98124139Sjoerg case CMD_errors: /* show errors */ 98224139Sjoerg if (error_count() == 0) 98324139Sjoerg { 98424139Sjoerg new_message(MT_standout, 98524139Sjoerg " Currently no errors to report."); 98624139Sjoerg putchar('\r'); 98724139Sjoerg no_command = Yes; 98824139Sjoerg } 98924139Sjoerg else 99024139Sjoerg { 99124139Sjoerg reset_display(); 992332948Slidl top_clear(); 99324139Sjoerg show_errors(); 994332948Slidl top_standout("Hit any key to continue: "); 99524139Sjoerg fflush(stdout); 99624139Sjoerg (void) read(0, &ch, 1); 99724139Sjoerg } 99824139Sjoerg break; 99924139Sjoerg 100024139Sjoerg case CMD_number1: /* new number */ 100124139Sjoerg case CMD_number2: 100224139Sjoerg new_message(MT_standout, 100324139Sjoerg "Number of processes to show: "); 100424139Sjoerg newval = readline(tempbuf1, 8, Yes); 100524139Sjoerg if (newval > -1) 100624139Sjoerg { 100724139Sjoerg if (newval > max_topn) 100824139Sjoerg { 100924139Sjoerg new_message(MT_standout | MT_delayed, 101024139Sjoerg " This terminal can only display %d processes.", 101124139Sjoerg max_topn); 101224139Sjoerg putchar('\r'); 101324139Sjoerg } 101424139Sjoerg 101524139Sjoerg if (newval == 0) 101624139Sjoerg { 101724139Sjoerg /* inhibit the header */ 101824139Sjoerg display_header(No); 101924139Sjoerg } 102024139Sjoerg else if (newval > topn && topn == 0) 102124139Sjoerg { 102224139Sjoerg /* redraw the header */ 102324139Sjoerg display_header(Yes); 102424139Sjoerg d_header = i_header; 102524139Sjoerg } 102624139Sjoerg topn = newval; 102724139Sjoerg } 102824139Sjoerg break; 102924139Sjoerg 103024139Sjoerg case CMD_delay: /* new seconds delay */ 103124139Sjoerg new_message(MT_standout, "Seconds to delay: "); 103224139Sjoerg if ((i = readline(tempbuf1, 8, Yes)) > -1) 103324139Sjoerg { 103489757Sdwmalone if ((delay = i) == 0 && getuid() != 0) 103589757Sdwmalone { 103689757Sdwmalone delay = 1; 103789757Sdwmalone } 103824139Sjoerg } 103924139Sjoerg clear_message(); 104024139Sjoerg break; 104124139Sjoerg 104224139Sjoerg case CMD_displays: /* change display count */ 104324139Sjoerg new_message(MT_standout, 104424139Sjoerg "Displays to show (currently %s): ", 104524139Sjoerg displays == -1 ? "infinite" : 104624139Sjoerg itoa(displays)); 104724139Sjoerg if ((i = readline(tempbuf1, 10, Yes)) > 0) 104824139Sjoerg { 104924139Sjoerg displays = i; 105024139Sjoerg } 105124139Sjoerg else if (i == 0) 105224139Sjoerg { 105324139Sjoerg quit(0); 105424139Sjoerg } 105524139Sjoerg clear_message(); 105624139Sjoerg break; 105724139Sjoerg 105824139Sjoerg case CMD_kill: /* kill program */ 105924139Sjoerg new_message(0, "kill "); 106024139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 106124139Sjoerg { 106224139Sjoerg if ((errmsg = kill_procs(tempbuf2)) != NULL) 106324139Sjoerg { 106466641Simp new_message(MT_standout, "%s", errmsg); 106524139Sjoerg putchar('\r'); 106624139Sjoerg no_command = Yes; 106724139Sjoerg } 106824139Sjoerg } 106924139Sjoerg else 107024139Sjoerg { 107124139Sjoerg clear_message(); 107224139Sjoerg } 107324139Sjoerg break; 107424139Sjoerg 107524139Sjoerg case CMD_renice: /* renice program */ 107624139Sjoerg new_message(0, "renice "); 107724139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 107824139Sjoerg { 107924139Sjoerg if ((errmsg = renice_procs(tempbuf2)) != NULL) 108024139Sjoerg { 108168293Simp new_message(MT_standout, "%s", errmsg); 108224139Sjoerg putchar('\r'); 108324139Sjoerg no_command = Yes; 108424139Sjoerg } 108524139Sjoerg } 108624139Sjoerg else 108724139Sjoerg { 108824139Sjoerg clear_message(); 108924139Sjoerg } 109024139Sjoerg break; 109124139Sjoerg 109224139Sjoerg case CMD_idletog: 109324139Sjoerg case CMD_idletog2: 109424139Sjoerg ps.idle = !ps.idle; 109524139Sjoerg new_message(MT_standout | MT_delayed, 109624139Sjoerg " %sisplaying idle processes.", 109724139Sjoerg ps.idle ? "D" : "Not d"); 109824139Sjoerg putchar('\r'); 109924139Sjoerg break; 110024139Sjoerg 110138090Sdes case CMD_selftog: 110238090Sdes ps.self = (ps.self == -1) ? getpid() : -1; 110338090Sdes new_message(MT_standout | MT_delayed, 110438090Sdes " %sisplaying self.", 110538090Sdes (ps.self == -1) ? "D" : "Not d"); 110638090Sdes putchar('\r'); 110738090Sdes break; 110838090Sdes 110924139Sjoerg case CMD_user: 1110322509Sgahr if (handle_user(tempbuf2, sizeof(tempbuf2))) 1111322509Sgahr no_command = Yes; 111224139Sjoerg break; 111324139Sjoerg 1114117709Sjulian case CMD_thrtog: 1115117709Sjulian ps.thread = !ps.thread; 1116117709Sjulian new_message(MT_standout | MT_delayed, 1117223937Sjhb " Displaying threads %s", 1118145073Skeramida ps.thread ? "separately" : "as a count"); 1119145073Skeramida header_text = format_header(uname_field); 1120145073Skeramida reset_display(); 1121117709Sjulian putchar('\r'); 1122117709Sjulian break; 1123146342Skeramida case CMD_wcputog: 1124146342Skeramida ps.wcpu = !ps.wcpu; 1125146342Skeramida new_message(MT_standout | MT_delayed, 1126224204Sjhb " Displaying %s CPU", 1127224204Sjhb ps.wcpu ? "weighted" : "raw"); 1128146342Skeramida header_text = format_header(uname_field); 1129146342Skeramida reset_display(); 1130146342Skeramida putchar('\r'); 1131146342Skeramida break; 1132131402Salfred case CMD_viewtog: 1133131402Salfred if (++displaymode == DISP_MAX) 1134131402Salfred displaymode = 0; 1135131402Salfred header_text = format_header(uname_field); 1136131402Salfred display_header(Yes); 1137131402Salfred d_header = i_header; 1138131402Salfred reset_display(); 1139131402Salfred break; 1140132005Salfred case CMD_viewsys: 1141132005Salfred ps.system = !ps.system; 1142132005Salfred break; 1143168710Sstas case CMD_showargs: 1144168710Sstas fmt_flags ^= FMT_SHOWARGS; 1145168710Sstas break; 114624139Sjoerg#ifdef ORDER 114724139Sjoerg case CMD_order: 114824139Sjoerg new_message(MT_standout, 114924139Sjoerg "Order to sort: "); 115024139Sjoerg if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 115124139Sjoerg { 115224139Sjoerg if ((i = string_index(tempbuf2, statics.order_names)) == -1) 115324139Sjoerg { 115424139Sjoerg new_message(MT_standout, 115524139Sjoerg " %s: unrecognized sorting order", tempbuf2); 115624139Sjoerg no_command = Yes; 115724139Sjoerg } 115824139Sjoerg else 115924139Sjoerg { 116024139Sjoerg order_index = i; 116124139Sjoerg } 116224139Sjoerg putchar('\r'); 116324139Sjoerg } 116424139Sjoerg else 116524139Sjoerg { 116624139Sjoerg clear_message(); 116724139Sjoerg } 116824139Sjoerg break; 116924139Sjoerg#endif 1170168799Srafan case CMD_jidtog: 1171168799Srafan ps.jail = !ps.jail; 1172168799Srafan new_message(MT_standout | MT_delayed, 1173169257Srafan " %sisplaying jail ID.", 1174168799Srafan ps.jail ? "D" : "Not d"); 1175168799Srafan header_text = format_header(uname_field); 1176168799Srafan reset_display(); 1177168799Srafan putchar('\r'); 1178168799Srafan break; 1179265249Sbdrewery 1180265249Sbdrewery case CMD_jail: 1181265249Sbdrewery new_message(MT_standout, 1182265250Sbdrewery "Jail to show (+ for all): "); 1183265249Sbdrewery if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) 1184265249Sbdrewery { 1185265249Sbdrewery if (tempbuf2[0] == '+' && 1186265249Sbdrewery tempbuf2[1] == '\0') 1187265249Sbdrewery { 1188265249Sbdrewery ps.jid = -1; 1189265249Sbdrewery } 1190265249Sbdrewery else if ((i = jail_getid(tempbuf2)) == -1) 1191265249Sbdrewery { 1192265249Sbdrewery new_message(MT_standout, 1193265249Sbdrewery " %s: unknown jail", tempbuf2); 1194265249Sbdrewery no_command = Yes; 1195265249Sbdrewery } 1196265249Sbdrewery else 1197265249Sbdrewery { 1198265249Sbdrewery ps.jid = i; 1199265249Sbdrewery } 1200265249Sbdrewery if (ps.jail == 0) { 1201265249Sbdrewery ps.jail = 1; 1202265249Sbdrewery new_message(MT_standout | 1203265249Sbdrewery MT_delayed, " Displaying jail " 1204265249Sbdrewery "ID."); 1205265249Sbdrewery header_text = 1206265249Sbdrewery format_header(uname_field); 1207265249Sbdrewery reset_display(); 1208265249Sbdrewery } 1209265249Sbdrewery putchar('\r'); 1210265249Sbdrewery } 1211265249Sbdrewery else 1212265249Sbdrewery { 1213265249Sbdrewery clear_message(); 1214265249Sbdrewery } 1215265249Sbdrewery break; 1216265249Sbdrewery 1217222530Sjhb case CMD_kidletog: 1218222530Sjhb ps.kidle = !ps.kidle; 1219222530Sjhb new_message(MT_standout | MT_delayed, 1220222530Sjhb " %sisplaying system idle process.", 1221222530Sjhb ps.kidle ? "D" : "Not d"); 1222222530Sjhb putchar('\r'); 1223222530Sjhb break; 1224223936Sjhb case CMD_pcputog: 1225223936Sjhb pcpu_stats = !pcpu_stats; 1226223936Sjhb new_message(MT_standout | MT_delayed, 1227223936Sjhb " Displaying %sCPU statistics.", 1228223936Sjhb pcpu_stats ? "per-" : "global "); 1229224205Sjhb toggle_pcpustats(); 1230223936Sjhb max_topn = display_updatecpus(&statics); 1231223936Sjhb reset_display(); 1232223936Sjhb putchar('\r'); 1233223936Sjhb break; 1234307757Sdes case CMD_swaptog: 1235307757Sdes ps.swap = !ps.swap; 1236307757Sdes new_message(MT_standout | MT_delayed, 1237307757Sdes " %sisplaying per-process swap usage.", 1238307757Sdes ps.swap ? "D" : "Not d"); 1239307757Sdes header_text = format_header(uname_field); 1240307757Sdes reset_display(); 1241307757Sdes putchar('\r'); 1242307757Sdes break; 124324139Sjoerg default: 124424139Sjoerg new_message(MT_standout, " BAD CASE IN SWITCH!"); 124524139Sjoerg putchar('\r'); 124624139Sjoerg } 124724139Sjoerg } 124824139Sjoerg 124924139Sjoerg /* flush out stuff that may have been written */ 125024139Sjoerg fflush(stdout); 125124139Sjoerg } 125224139Sjoerg } 125324139Sjoerg } 125424139Sjoerg } 125524139Sjoerg 125689757Sdwmalone#ifdef DEBUG 125789757Sdwmalone fclose(debug); 125889757Sdwmalone#endif 125924139Sjoerg quit(0); 126024139Sjoerg /*NOTREACHED*/ 126124139Sjoerg} 126224139Sjoerg 126324139Sjoerg/* 126424139Sjoerg * reset_display() - reset all the display routine pointers so that entire 126524139Sjoerg * screen will get redrawn. 126624139Sjoerg */ 126724139Sjoerg 1268300395Sngievoid 126924139Sjoergreset_display() 127024139Sjoerg 127124139Sjoerg{ 127224139Sjoerg d_loadave = i_loadave; 127324139Sjoerg d_procstates = i_procstates; 127424139Sjoerg d_cpustates = i_cpustates; 127524139Sjoerg d_memory = i_memory; 1276237656Sjhb d_arc = i_arc; 1277318449Sallanjude d_carc = i_carc; 127824142Sjoerg d_swap = i_swap; 127924139Sjoerg d_message = i_message; 128024139Sjoerg d_header = i_header; 128124139Sjoerg d_process = i_process; 128224139Sjoerg} 128324139Sjoerg 128424139Sjoerg/* 128524139Sjoerg * signal handlers 128624139Sjoerg */ 128724139Sjoerg 128824139Sjoergsigret_t leave() /* exit under normal conditions -- INT handler */ 128924139Sjoerg 129024139Sjoerg{ 129181187Skris leaveflag = 1; 129224139Sjoerg} 129324139Sjoerg 129424139Sjoergsigret_t tstop(i) /* SIGTSTP handler */ 129524139Sjoerg 129624139Sjoergint i; 129724139Sjoerg 129824139Sjoerg{ 129981187Skris tstopflag = 1; 130024139Sjoerg} 130124139Sjoerg 130224139Sjoerg#ifdef SIGWINCH 1303332948Slidlsigret_t top_winch(int i) /* SIGWINCH handler */ 130424139Sjoerg{ 130581187Skris winchflag = 1; 130624139Sjoerg} 130724139Sjoerg#endif 130824139Sjoerg 130924139Sjoergvoid quit(status) /* exit under duress */ 131024139Sjoerg 131124139Sjoergint status; 131224139Sjoerg 131324139Sjoerg{ 131424139Sjoerg end_screen(); 131524139Sjoerg exit(status); 131624139Sjoerg /*NOTREACHED*/ 131724139Sjoerg} 1318