1 /*- 2 * Copyright (c) 1980, 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980, 1992 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)main.c 5.13 (Berkeley) 09/02/92"; 16 #endif /* not lint */ 17 18 #include <sys/param.h> 19 20 #include <nlist.h> 21 #include <signal.h> 22 #include <stdio.h> 23 #include "systat.h" 24 #include "extern.h" 25 26 static struct nlist namelist[] = { 27 #define X_FIRST 0 28 #define X_HZ 0 29 { "_hz" }, 30 #define X_STATHZ 1 31 { "_stathz" }, 32 { "" } 33 }; 34 35 static int dellave; 36 37 kvm_t *kd; 38 sig_t sigtstpdfl; 39 double avenrun[3]; 40 int col; 41 int naptime = 5; 42 int verbose = 1; /* to report kvm read errs */ 43 int hz, stathz; 44 char c; 45 char *namp; 46 char hostname[MAXHOSTNAMELEN]; 47 WINDOW *wnd; 48 int CMDLINE; 49 50 static WINDOW *wload; /* one line window for load average */ 51 52 void 53 main(argc, argv) 54 int argc; 55 char **argv; 56 { 57 char errbuf[80]; 58 59 argc--, argv++; 60 while (argc > 0) { 61 if (argv[0][0] == '-') { 62 struct cmdtab *p; 63 64 p = lookup(&argv[0][1]); 65 if (p == (struct cmdtab *)-1) { 66 fprintf(stderr, "%s: unknown request\n", 67 &argv[0][1]); 68 exit(1); 69 } 70 curcmd = p; 71 } else { 72 naptime = atoi(argv[0]); 73 if (naptime <= 0) 74 naptime = 5; 75 } 76 argc--, argv++; 77 } 78 kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); 79 if (kd == NULL) { 80 error("%s", errbuf); 81 exit(1); 82 } 83 if (kvm_nlist(kd, namelist)) { 84 nlisterr(namelist); 85 exit(1); 86 } 87 if (namelist[X_FIRST].n_type == 0) { 88 fprintf(stderr, "couldn't read namelist.\n"); 89 exit(1); 90 } 91 signal(SIGINT, die); 92 signal(SIGQUIT, die); 93 signal(SIGTERM, die); 94 95 /* 96 * Initialize display. Load average appears in a one line 97 * window of its own. Current command's display appears in 98 * an overlapping sub-window of stdscr configured by the display 99 * routines to minimize update work by curses. 100 */ 101 initscr(); 102 CMDLINE = LINES - 1; 103 wnd = (*curcmd->c_open)(); 104 if (wnd == NULL) { 105 fprintf(stderr, "Couldn't initialize display.\n"); 106 die(0); 107 } 108 wload = newwin(1, 0, 3, 20); 109 if (wload == NULL) { 110 fprintf(stderr, "Couldn't set up load average window.\n"); 111 die(0); 112 } 113 gethostname(hostname, sizeof (hostname)); 114 NREAD(X_HZ, &hz, LONG); 115 NREAD(X_STATHZ, &stathz, LONG); 116 (*curcmd->c_init)(); 117 curcmd->c_flags |= CF_INIT; 118 labels(); 119 120 dellave = 0.0; 121 122 signal(SIGALRM, display); 123 sigtstpdfl = signal(SIGTSTP, suspend); 124 display(0); 125 noecho(); 126 crmode(); 127 keyboard(); 128 /*NOTREACHED*/ 129 } 130 131 void 132 labels() 133 { 134 if (curcmd->c_flags & CF_LOADAV) { 135 mvaddstr(2, 20, 136 "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); 137 mvaddstr(3, 5, "Load Average"); 138 } 139 (*curcmd->c_label)(); 140 #ifdef notdef 141 mvprintw(21, 25, "CPU usage on %s", hostname); 142 #endif 143 refresh(); 144 } 145 146 void 147 display(signo) 148 int signo; 149 { 150 register int i, j; 151 152 /* Get the load average over the last minute. */ 153 (void) getloadavg(avenrun, sizeof(avenrun) / sizeof(avenrun[0])); 154 (*curcmd->c_fetch)(); 155 if (curcmd->c_flags & CF_LOADAV) { 156 j = 5.0*avenrun[0] + 0.5; 157 dellave -= avenrun[0]; 158 if (dellave >= 0.0) 159 c = '<'; 160 else { 161 c = '>'; 162 dellave = -dellave; 163 } 164 if (dellave < 0.1) 165 c = '|'; 166 dellave = avenrun[0]; 167 wmove(wload, 0, 0); wclrtoeol(wload); 168 for (i = (j > 50) ? 50 : j; i > 0; i--) 169 waddch(wload, c); 170 if (j > 50) 171 wprintw(wload, " %4.1f", avenrun[0]); 172 } 173 (*curcmd->c_refresh)(); 174 if (curcmd->c_flags & CF_LOADAV) 175 wrefresh(wload); 176 wrefresh(wnd); 177 move(CMDLINE, col); 178 refresh(); 179 alarm(naptime); 180 } 181 182 void 183 load() 184 { 185 186 (void) getloadavg(avenrun, sizeof(avenrun)/sizeof(avenrun[0])); 187 mvprintw(CMDLINE, 0, "%4.1f %4.1f %4.1f", 188 avenrun[0], avenrun[1], avenrun[2]); 189 clrtoeol(); 190 } 191 192 void 193 die(signo) 194 int signo; 195 { 196 move(CMDLINE, 0); 197 clrtoeol(); 198 refresh(); 199 endwin(); 200 exit(0); 201 } 202 203 #if __STDC__ 204 #include <stdarg.h> 205 #else 206 #include <varargs.h> 207 #endif 208 209 #if __STDC__ 210 void 211 error(const char *fmt, ...) 212 #else 213 void 214 error(fmt, va_alist) 215 char *fmt; 216 va_dcl 217 #endif 218 { 219 va_list ap; 220 #if __STDC__ 221 va_start(ap, fmt); 222 #else 223 va_start(ap); 224 #endif 225 (void) vfprintf(stderr, fmt, ap); 226 va_end(ap); 227 if (wnd) { 228 clrtoeol(); 229 refresh(); 230 } else 231 fprintf(stderr, "\n"); 232 } 233 234 void 235 nlisterr(namelist) 236 struct nlist namelist[]; 237 { 238 int i, n; 239 240 n = 0; 241 clear(); 242 mvprintw(2, 10, "systat: nlist: can't find following symbols:"); 243 for (i = 0; 244 namelist[i].n_name != NULL && *namelist[i].n_name != '\0'; i++) 245 if (namelist[i].n_value == 0) 246 mvprintw(2 + ++n, 10, "%s", namelist[i].n_name); 247 move(CMDLINE, 0); 248 clrtoeol(); 249 refresh(); 250 endwin(); 251 exit(1); 252 } 253