Annotation of src/usr.bin/top/top.c, Revision 1.7
1.7 ! deraadt 1: /* $OpenBSD: top.c,v 1.6 2000/12/22 22:46:57 deraadt Exp $ */
1.1 downsj 2:
1.2 downsj 3: const char copyright[] = "Copyright (c) 1984 through 1996, William LeFebvre";
1.1 downsj 4:
5: /*
6: * Top users/processes display for Unix
7: * Version 3
8: *
9: * This program may be freely redistributed,
10: * but this entire comment MUST remain intact.
11: *
12: * Copyright (c) 1984, 1989, William LeFebvre, Rice University
13: * Copyright (c) 1989, 1990, 1992, William LeFebvre, Northwestern University
14: */
15:
16: /*
17: * See the file "Changes" for information on version-to-version changes.
18: */
19:
20: /*
21: * This file contains "main" and other high-level routines.
22: */
23:
24: /*
25: * The following preprocessor variables, when defined, are used to
26: * distinguish between different Unix implementations:
27: *
28: * SIGHOLD - use SVR4 sighold function when defined
29: * SIGRELSE - use SVR4 sigrelse function when defined
30: * FD_SET - macros FD_SET and FD_ZERO are used when defined
31: */
32:
1.2 downsj 33: #include <sys/types.h>
34: #include <stdio.h>
35: #include <ctype.h>
1.1 downsj 36: #include <signal.h>
37: #include <setjmp.h>
1.2 downsj 38: #include <string.h>
39: #include <stdlib.h>
40: #include <unistd.h>
1.5 deraadt 41: #include <errno.h>
1.1 downsj 42: #include <sys/time.h>
43:
44: /* includes specific to top */
45: #include "display.h" /* interface to display package */
46: #include "screen.h" /* interface to screen package */
47: #include "top.h"
48: #include "top.local.h"
49: #include "boolean.h"
50: #include "machine.h"
51: #include "utils.h"
52:
53: /* Size of the stdio buffer given to stdout */
54: #define Buffersize 2048
55:
56: /* The buffer that stdio will use */
57: char stdoutbuf[Buffersize];
58:
59: /* build Signal masks */
60: #define Smask(s) (1 << ((s) - 1))
61:
62: /* imported from screen.c */
63: extern int overstrike;
64:
65: /* signal handling routines */
1.2 downsj 66: static void leave __P((int));
67: static void onalrm __P((int));
68: static void tstop __P((int));
1.1 downsj 69: #ifdef SIGWINCH
1.2 downsj 70: static void winch __P((int));
1.1 downsj 71: #endif
72:
1.7 ! deraadt 73: sig_atomic_t leaveflag;
! 74: sig_atomic_t tstopflag;
! 75: sig_atomic_t winchflag;
! 76:
1.2 downsj 77: static void reset_display __P((void));
1.1 downsj 78:
79: /* values which need to be accessed by signal handlers */
80: static int max_topn; /* maximum displayable processes */
81:
82: /* miscellaneous things */
83: char *myname = "top";
84: jmp_buf jmp_int;
85:
86: /* routines that don't return int */
87:
88: #ifdef ORDER
89: extern int (*proc_compares[])();
90: #else
91: extern int proc_compare();
92: #endif
93: time_t time();
94:
95: caddr_t get_process_info();
96:
97: /* pointers to display routines */
1.2 downsj 98: void (*d_loadave)() = i_loadave;
99: void (*d_procstates)() = i_procstates;
100: void (*d_cpustates)() = i_cpustates;
101: void (*d_memory)() = i_memory;
102: void (*d_message)() = i_message;
103: void (*d_header)() = i_header;
104: void (*d_process)() = i_process;
1.1 downsj 105:
106:
1.2 downsj 107: int main(argc, argv)
1.1 downsj 108:
109: int argc;
110: char *argv[];
111:
112: {
113: register int i;
114: register int active_procs;
115: register int change;
116:
117: struct system_info system_info;
118: struct statics statics;
119: caddr_t processes;
120:
121: static char tempbuf1[50];
122: static char tempbuf2[50];
123: int old_sigmask; /* only used for BSD-style signals */
124: int topn = Default_TOPN;
125: int delay = Default_DELAY;
126: int displays = 0; /* indicates unspecified */
127: time_t curr_time;
128: char *(*get_userid)() = username;
129: char *uname_field = "USERNAME";
130: char *header_text;
131: char *env_top;
132: char **preset_argv;
133: int preset_argc = 0;
134: char **av;
135: int ac;
136: char dostates = No;
137: char do_unames = Yes;
138: char interactive = Maybe;
139: char warnings = 0;
140: #if Default_TOPN == Infinity
141: char topn_specified = No;
142: #endif
143: char ch;
144: char *iptr;
145: char no_command = 1;
146: struct timeval timeout;
147: struct process_select ps;
148: #ifdef ORDER
149: char *order_name = NULL;
150: int order_index = 0;
151: #endif
152: #ifndef FD_SET
153: /* FD_SET and friends are not present: fake it */
154: typedef int fd_set;
155: #define FD_ZERO(x) (*(x) = 0)
156: #define FD_SET(f, x) (*(x) = f)
157: #endif
158: fd_set readfds;
159:
160: #ifdef ORDER
161: static char command_chars[] = "\f qh?en#sdkriIuo";
162: #else
163: static char command_chars[] = "\f qh?en#sdkriIu";
164: #endif
165: /* these defines enumerate the "strchr"s of the commands in command_chars */
166: #define CMD_redraw 0
167: #define CMD_update 1
168: #define CMD_quit 2
169: #define CMD_help1 3
170: #define CMD_help2 4
171: #define CMD_OSLIMIT 4 /* terminals with OS can only handle commands */
172: #define CMD_errors 5 /* less than or equal to CMD_OSLIMIT */
173: #define CMD_number1 6
174: #define CMD_number2 7
175: #define CMD_delay 8
176: #define CMD_displays 9
177: #define CMD_kill 10
178: #define CMD_renice 11
179: #define CMD_idletog 12
180: #define CMD_idletog2 13
181: #define CMD_user 14
182: #ifdef ORDER
183: #define CMD_order 15
184: #endif
185:
186: /* set the buffer for stdout */
187: #ifdef DEBUG
188: setbuffer(stdout, NULL, 0);
189: #else
190: setbuffer(stdout, stdoutbuf, Buffersize);
191: #endif
192:
193: /* get our name */
194: if (argc > 0)
195: {
196: if ((myname = strrchr(argv[0], '/')) == 0)
197: {
198: myname = argv[0];
199: }
200: else
201: {
202: myname++;
203: }
204: }
205:
206: /* initialize some selection options */
207: ps.idle = Yes;
208: ps.system = No;
209: ps.uid = -1;
210: ps.command = NULL;
211:
212: /* get preset options from the environment */
213: if ((env_top = getenv("TOP")) != NULL)
214: {
215: av = preset_argv = argparse(env_top, &preset_argc);
216: ac = preset_argc;
217:
218: /* set the dummy argument to an explanatory message, in case
219: getopt encounters a bad argument */
220: preset_argv[0] = "while processing environment";
221: }
222:
223: /* process options */
224: do {
225: /* if we're done doing the presets, then process the real arguments */
226: if (preset_argc == 0)
227: {
228: ac = argc;
229: av = argv;
230:
231: /* this should keep getopt happy... */
232: optind = 1;
233: }
234:
1.3 aaron 235: while ((i = getopt(ac, av, "SIbinqus:d:U:o:")) != -1)
1.1 downsj 236: {
237: switch(i)
238: {
239: case 'u': /* toggle uid/username display */
240: do_unames = !do_unames;
241: break;
242:
243: case 'U': /* display only username's processes */
244: if ((ps.uid = userid(optarg)) == -1)
245: {
246: fprintf(stderr, "%s: unknown user\n", optarg);
247: exit(1);
248: }
249: break;
250:
251: case 'S': /* show system processes */
252: ps.system = !ps.system;
253: break;
254:
255: case 'I': /* show idle processes */
256: ps.idle = !ps.idle;
257: break;
258:
259: case 'i': /* go interactive regardless */
260: interactive = Yes;
261: break;
262:
263: case 'n': /* batch, or non-interactive */
264: case 'b':
265: interactive = No;
266: break;
267:
268: case 'd': /* number of displays to show */
269: if ((i = atoiwi(optarg)) == Invalid || i == 0)
270: {
271: fprintf(stderr,
272: "%s: warning: display count should be positive -- option ignored\n",
273: myname);
274: warnings++;
275: }
276: else
277: {
278: displays = i;
279: }
280: break;
281:
282: case 's':
283: {
1.6 deraadt 284: char *endp;
285:
286: delay = strtoul(optarg, &endp, 10);
287: if (delay < 0 || *endp != '\0')
288: {
1.1 downsj 289: fprintf(stderr,
290: "%s: warning: seconds delay should be non-negative -- using default\n",
291: myname);
292: delay = Default_DELAY;
293: warnings++;
1.6 deraadt 294: }
1.1 downsj 295: }
296: break;
297:
298: case 'q': /* be quick about it */
299: /* only allow this if user is really root */
300: if (getuid() == 0)
301: {
302: /* be very un-nice! */
303: (void) nice(-20);
304: }
305: else
306: {
307: fprintf(stderr,
308: "%s: warning: `-q' option can only be used by root\n",
309: myname);
310: warnings++;
311: }
312: break;
313:
314: case 'o': /* select sort order */
315: #ifdef ORDER
316: order_name = optarg;
317: #else
318: fprintf(stderr,
319: "%s: this platform does not support arbitrary ordering. Sorry.\n",
320: myname);
321: warnings++;
322: #endif
323: break;
324:
325: default:
326: fprintf(stderr, "\
327: Top version %s\n\
328: Usage: %s [-ISbinqu] [-d x] [-s x] [-o field] [-U username] [number]\n",
329: version_string(), myname);
330: exit(1);
331: }
332: }
333:
334: /* get count of top processes to display (if any) */
335: if (optind < ac)
336: {
337: if ((topn = atoiwi(av[optind])) == Invalid)
338: {
339: fprintf(stderr,
340: "%s: warning: process display count should be non-negative -- using default\n",
341: myname);
342: warnings++;
343: }
344: #if Default_TOPN == Infinity
345: else
346: {
347: topn_specified = Yes;
348: }
349: #endif
350: }
351:
352: /* tricky: remember old value of preset_argc & set preset_argc = 0 */
353: i = preset_argc;
354: preset_argc = 0;
355:
356: /* repeat only if we really did the preset arguments */
357: } while (i != 0);
358:
359: /* set constants for username/uid display correctly */
360: if (!do_unames)
361: {
362: uname_field = " UID ";
363: get_userid = itoa7;
364: }
365:
366: /* initialize the kernel memory interface */
367: if (machine_init(&statics) == -1)
368: {
369: exit(1);
370: }
371:
372: #ifdef ORDER
373: /* determine sorting order index, if necessary */
374: if (order_name != NULL)
375: {
376: if ((order_index = string_index(order_name, statics.order_names)) == -1)
377: {
378: char **pp;
379:
380: fprintf(stderr, "%s: '%s' is not a recognized sorting order.\n",
381: myname, order_name);
382: fprintf(stderr, "\tTry one of these:");
383: pp = statics.order_names;
384: while (*pp != NULL)
385: {
386: fprintf(stderr, " %s", *pp++);
387: }
388: fputc('\n', stderr);
389: exit(1);
390: }
391: }
392: #endif
393:
394: #ifdef no_initialization_needed
395: /* initialize the hashing stuff */
396: if (do_unames)
397: {
398: init_hash();
399: }
400: #endif
401:
402: /* initialize termcap */
403: init_termcap(interactive);
404:
405: /* get the string to use for the process area header */
406: header_text = format_header(uname_field);
407:
408: /* initialize display interface */
409: if ((max_topn = display_init(&statics)) == -1)
410: {
411: fprintf(stderr, "%s: can't allocate sufficient memory\n", myname);
412: exit(4);
413: }
414:
415: /* print warning if user requested more processes than we can display */
416: if (topn > max_topn)
417: {
418: fprintf(stderr,
419: "%s: warning: this terminal can only display %d processes.\n",
420: myname, max_topn);
421: warnings++;
422: }
423:
424: /* adjust for topn == Infinity */
425: if (topn == Infinity)
426: {
427: /*
428: * For smart terminals, infinity really means everything that can
429: * be displayed, or Largest.
430: * On dumb terminals, infinity means every process in the system!
431: * We only really want to do that if it was explicitly specified.
432: * This is always the case when "Default_TOPN != Infinity". But if
433: * topn wasn't explicitly specified and we are on a dumb terminal
434: * and the default is Infinity, then (and only then) we use
435: * "Nominal_TOPN" instead.
436: */
437: #if Default_TOPN == Infinity
438: topn = smart_terminal ? Largest :
439: (topn_specified ? Largest : Nominal_TOPN);
440: #else
441: topn = Largest;
442: #endif
443: }
444:
445: /* set header display accordingly */
446: display_header(topn > 0);
447:
448: /* determine interactive state */
449: if (interactive == Maybe)
450: {
451: interactive = smart_terminal;
452: }
453:
454: /* if # of displays not specified, fill it in */
455: if (displays == 0)
456: {
457: displays = smart_terminal ? Infinity : 1;
458: }
459:
460: /* hold interrupt signals while setting up the screen and the handlers */
461: #ifdef SIGHOLD
462: sighold(SIGINT);
463: sighold(SIGQUIT);
464: sighold(SIGTSTP);
465: #else
466: old_sigmask = sigblock(Smask(SIGINT) | Smask(SIGQUIT) | Smask(SIGTSTP));
467: #endif
468: init_screen();
469: (void) signal(SIGINT, leave);
470: (void) signal(SIGQUIT, leave);
471: (void) signal(SIGTSTP, tstop);
472: #ifdef SIGWINCH
473: (void) signal(SIGWINCH, winch);
474: #endif
475: #ifdef SIGRELSE
476: sigrelse(SIGINT);
477: sigrelse(SIGQUIT);
478: sigrelse(SIGTSTP);
479: #else
480: (void) sigsetmask(old_sigmask);
481: #endif
482: if (warnings)
483: {
484: fputs("....", stderr);
485: fflush(stderr); /* why must I do this? */
486: sleep((unsigned)(3 * warnings));
487: fputc('\n', stderr);
488: }
489:
1.7 ! deraadt 490: restart:
1.1 downsj 491:
492: /*
493: * main loop -- repeat while display count is positive or while it
494: * indicates infinity (by being -1)
495: */
496:
497: while ((displays == -1) || (displays-- > 0))
498: {
499: /* get the current stats */
500: get_system_info(&system_info);
501:
502: /* get the current set of processes */
503: processes =
504: get_process_info(&system_info,
505: &ps,
506: #ifdef ORDER
507: proc_compares[order_index]);
508: #else
509: proc_compare);
510: #endif
511:
512: /* display the load averages */
513: (*d_loadave)(system_info.last_pid,
514: system_info.load_avg);
515:
516: /* display the current time */
517: /* this method of getting the time SHOULD be fairly portable */
518: time(&curr_time);
519: i_timeofday(&curr_time);
520:
521: /* display process state breakdown */
522: (*d_procstates)(system_info.p_total,
523: system_info.procstates);
524:
525: /* display the cpu state percentage breakdown */
526: if (dostates) /* but not the first time */
527: {
528: (*d_cpustates)(system_info.cpustates);
529: }
530: else
531: {
532: /* we'll do it next time */
533: if (smart_terminal)
534: {
535: z_cpustates();
536: }
537: else
538: {
539: putchar('\n');
540: }
541: dostates = Yes;
542: }
543:
544: /* display memory stats */
545: (*d_memory)(system_info.memory);
546:
547: /* handle message area */
548: (*d_message)();
549:
550: /* update the header area */
551: (*d_header)(header_text);
552:
553: if (topn > 0)
554: {
555: /* determine number of processes to actually display */
556: /* this number will be the smallest of: active processes,
557: number user requested, number current screen accomodates */
558: active_procs = system_info.p_active;
559: if (active_procs > topn)
560: {
561: active_procs = topn;
562: }
563: if (active_procs > max_topn)
564: {
565: active_procs = max_topn;
566: }
567:
568: /* now show the top "n" processes. */
569: for (i = 0; i < active_procs; i++)
570: {
571: (*d_process)(i, format_next_process(processes, get_userid));
572: }
573: }
574: else
575: {
576: i = 0;
577: }
578:
579: /* do end-screen processing */
580: u_endscreen(i);
581:
582: /* now, flush the output buffer */
583: fflush(stdout);
584:
585: /* only do the rest if we have more displays to show */
586: if (displays)
587: {
588: /* switch out for new display on smart terminals */
589: if (smart_terminal)
590: {
591: if (overstrike)
592: {
593: reset_display();
594: }
595: else
596: {
597: d_loadave = u_loadave;
598: d_procstates = u_procstates;
599: d_cpustates = u_cpustates;
600: d_memory = u_memory;
601: d_message = u_message;
602: d_header = u_header;
603: d_process = u_process;
604: }
605: }
606:
607: no_command = Yes;
608: if (!interactive)
609: {
610: /* set up alarm */
611: (void) signal(SIGALRM, onalrm);
612: (void) alarm((unsigned)delay);
613:
614: /* wait for the rest of it .... */
615: pause();
616: }
617: else while (no_command)
618: {
619: /* assume valid command unless told otherwise */
620: no_command = No;
621:
622: /* set up arguments for select with timeout */
623: FD_ZERO(&readfds);
624: FD_SET(1, &readfds); /* for standard input */
625: timeout.tv_sec = delay;
626: timeout.tv_usec = 0;
627:
1.7 ! deraadt 628: if (leaveflag) {
! 629: end_screen();
! 630: exit(0);
! 631: }
! 632:
! 633: if (tstopflag) {
! 634: /* move to the lower left */
! 635: end_screen();
! 636: fflush(stdout);
! 637:
! 638: /* default the signal handler action */
! 639: (void) signal(SIGTSTP, SIG_DFL);
! 640:
! 641: /* unblock the signal and send ourselves one */
! 642: #ifdef SIGRELSE
! 643: sigrelse(SIGTSTP);
! 644: #else
! 645: (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
! 646: #endif
! 647: (void) kill(0, SIGTSTP);
! 648:
! 649: /* reset the signal handler */
! 650: (void) signal(SIGTSTP, tstop);
! 651:
! 652: /* reinit screen */
! 653: reinit_screen();
! 654: reset_display();
! 655: tstopflag = 0;
! 656: goto restart;
! 657: }
! 658:
! 659: if (winchflag) {
! 660: /* reascertain the screen dimensions */
! 661: get_screensize();
! 662:
! 663: /* tell display to resize */
! 664: max_topn = display_resize();
! 665:
! 666: /* reset the signal handler */
! 667: (void) signal(SIGWINCH, winch);
! 668:
! 669: reset_display();
! 670: winchflag = 0;
! 671: goto restart;
! 672: }
! 673:
1.1 downsj 674: /* wait for either input or the end of the delay period */
675: if (select(32, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout) > 0)
676: {
677: int newval;
678: char *errmsg;
679:
680: /* something to read -- clear the message area first */
681: clear_message();
682:
683: /* now read it and convert to command strchr */
684: /* (use "change" as a temporary to hold strchr) */
685: (void) read(0, &ch, 1);
686: if ((iptr = strchr(command_chars, ch)) == NULL)
687: {
688: /* illegal command */
689: new_message(MT_standout, " Command not understood");
690: putchar('\r');
691: no_command = Yes;
692: }
693: else
694: {
695: change = iptr - command_chars;
696: if (overstrike && change > CMD_OSLIMIT)
697: {
698: /* error */
699: new_message(MT_standout,
700: " Command cannot be handled by this terminal");
701: putchar('\r');
702: no_command = Yes;
703: }
704: else switch(change)
705: {
706: case CMD_redraw: /* redraw screen */
707: reset_display();
708: break;
709:
710: case CMD_update: /* merely update display */
711: /* is the load average high? */
712: if (system_info.load_avg[0] > LoadMax)
713: {
714: /* yes, go home for visual feedback */
715: go_home();
716: fflush(stdout);
717: }
718: break;
719:
720: case CMD_quit: /* quit */
721: quit(0);
722: /*NOTREACHED*/
723: break;
724:
725: case CMD_help1: /* help */
726: case CMD_help2:
727: reset_display();
728: clear();
729: show_help();
730: standout("Hit any key to continue: ");
731: fflush(stdout);
732: (void) read(0, &ch, 1);
733: break;
734:
735: case CMD_errors: /* show errors */
736: if (error_count() == 0)
737: {
738: new_message(MT_standout,
739: " Currently no errors to report.");
740: putchar('\r');
741: no_command = Yes;
742: }
743: else
744: {
745: reset_display();
746: clear();
747: show_errors();
748: standout("Hit any key to continue: ");
749: fflush(stdout);
750: (void) read(0, &ch, 1);
751: }
752: break;
753:
754: case CMD_number1: /* new number */
755: case CMD_number2:
756: new_message(MT_standout,
757: "Number of processes to show: ");
758: newval = readline(tempbuf1, 8, Yes);
759: if (newval > -1)
760: {
761: if (newval > max_topn)
762: {
763: new_message(MT_standout | MT_delayed,
764: " This terminal can only display %d processes.",
765: max_topn);
766: putchar('\r');
767: }
768:
769: if (newval == 0)
770: {
771: /* inhibit the header */
772: display_header(No);
773: }
774: else if (newval > topn && topn == 0)
775: {
776: /* redraw the header */
777: display_header(Yes);
778: d_header = i_header;
779: }
780: topn = newval;
781: }
782: break;
783:
784: case CMD_delay: /* new seconds delay */
785: new_message(MT_standout, "Seconds to delay: ");
786: if ((i = readline(tempbuf1, 8, Yes)) > -1)
787: {
788: delay = i;
789: }
790: clear_message();
791: break;
792:
793: case CMD_displays: /* change display count */
794: new_message(MT_standout,
795: "Displays to show (currently %s): ",
796: displays == -1 ? "infinite" :
797: itoa(displays));
798: if ((i = readline(tempbuf1, 10, Yes)) > 0)
799: {
800: displays = i;
801: }
802: else if (i == 0)
803: {
804: quit(0);
805: }
806: clear_message();
807: break;
808:
809: case CMD_kill: /* kill program */
810: new_message(0, "kill ");
811: if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
812: {
813: if ((errmsg = kill_procs(tempbuf2)) != NULL)
814: {
1.4 millert 815: new_message(MT_standout, "%s", errmsg);
1.1 downsj 816: putchar('\r');
817: no_command = Yes;
818: }
819: }
820: else
821: {
822: clear_message();
823: }
824: break;
825:
826: case CMD_renice: /* renice program */
827: new_message(0, "renice ");
828: if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
829: {
830: if ((errmsg = renice_procs(tempbuf2)) != NULL)
831: {
1.4 millert 832: new_message(MT_standout, "%s", errmsg);
1.1 downsj 833: putchar('\r');
834: no_command = Yes;
835: }
836: }
837: else
838: {
839: clear_message();
840: }
841: break;
842:
843: case CMD_idletog:
844: case CMD_idletog2:
845: ps.idle = !ps.idle;
846: new_message(MT_standout | MT_delayed,
847: " %sisplaying idle processes.",
848: ps.idle ? "D" : "Not d");
849: putchar('\r');
850: break;
851:
852: case CMD_user:
853: new_message(MT_standout,
854: "Username to show: ");
855: if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
856: {
857: if (tempbuf2[0] == '+' &&
858: tempbuf2[1] == '\0')
859: {
860: ps.uid = -1;
861: }
862: else if ((i = userid(tempbuf2)) == -1)
863: {
864: new_message(MT_standout,
865: " %s: unknown user", tempbuf2);
866: no_command = Yes;
867: }
868: else
869: {
870: ps.uid = i;
871: }
872: putchar('\r');
873: }
874: else
875: {
876: clear_message();
877: }
878: break;
879:
880: #ifdef ORDER
881: case CMD_order:
882: new_message(MT_standout,
883: "Order to sort: ");
884: if (readline(tempbuf2, sizeof(tempbuf2), No) > 0)
885: {
886: if ((i = string_index(tempbuf2, statics.order_names)) == -1)
887: {
888: new_message(MT_standout,
889: " %s: unrecognized sorting order", tempbuf2);
890: no_command = Yes;
891: }
892: else
893: {
894: order_index = i;
895: }
896: putchar('\r');
897: }
898: else
899: {
900: clear_message();
901: }
902: break;
903: #endif
904:
905: default:
906: new_message(MT_standout, " BAD CASE IN SWITCH!");
907: putchar('\r');
908: }
909: }
910:
911: /* flush out stuff that may have been written */
912: fflush(stdout);
913: }
914: }
915: }
916: }
917:
918: quit(0);
919: /*NOTREACHED*/
920: }
921:
922: /*
923: * reset_display() - reset all the display routine pointers so that entire
924: * screen will get redrawn.
925: */
926:
1.2 downsj 927: static void reset_display()
1.1 downsj 928:
929: {
930: d_loadave = i_loadave;
931: d_procstates = i_procstates;
932: d_cpustates = i_cpustates;
933: d_memory = i_memory;
934: d_message = i_message;
935: d_header = i_header;
936: d_process = i_process;
937: }
938:
939: /*
940: * signal handlers
941: */
942:
1.2 downsj 943: void leave(unused) /* exit under normal conditions -- INT handler */
944:
945: int unused;
1.1 downsj 946:
947: {
1.7 ! deraadt 948: leaveflag = 1;
1.1 downsj 949: }
950:
1.2 downsj 951: void tstop(i) /* SIGTSTP handler */
1.1 downsj 952:
953: int i;
954:
955: {
1.7 ! deraadt 956: tstopflag = 1;
1.1 downsj 957: }
958:
959: #ifdef SIGWINCH
1.2 downsj 960: void winch(i) /* SIGWINCH handler */
1.1 downsj 961:
962: int i;
963:
964: {
1.7 ! deraadt 965: winchflag = 1;
1.1 downsj 966: }
967: #endif
968:
969: void quit(status) /* exit under duress */
970:
971: int status;
972:
973: {
974: end_screen();
975: exit(status);
976: /*NOTREACHED*/
977: }
978:
1.2 downsj 979: void onalrm(unused) /* SIGALRM handler */
980:
981: int unused;
1.1 downsj 982:
983: {
984: /* this is only used in batch mode to break out of the pause() */
985: /* return; */
986: }
987: