version 1.19, 2001/11/28 20:28:08 |
version 1.20, 2001/12/07 07:57:35 |
|
|
#endif /* not lint */ |
#endif /* not lint */ |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/sysctl.h> |
|
|
|
#include <err.h> |
#include <err.h> |
#include <nlist.h> |
#include <nlist.h> |
|
|
#include "systat.h" |
#include "systat.h" |
#include "extern.h" |
#include "extern.h" |
|
|
double dellave; |
static struct nlist namelist[] = { |
|
#define X_FIRST 0 |
|
#define X_HZ 0 |
|
{ "_hz" }, |
|
#define X_STATHZ 1 |
|
{ "_stathz" }, |
|
{ "" } |
|
}; |
|
static double dellave; |
|
|
kvm_t *kd; |
kvm_t *kd; |
char *nlistf = NULL; |
|
char *memf = NULL; |
char *memf = NULL; |
|
char *nlistf = NULL; |
sig_t sigtstpdfl; |
sig_t sigtstpdfl; |
double avenrun[3]; |
double avenrun[3]; |
int col; |
int col; |
int naptime = 5; |
int naptime = 5; |
int verbose = 1; /* to report kvm read errs */ |
int verbose = 1; /* to report kvm read errs */ |
int hz, stathz; |
int hz, stathz; |
char c; |
char c; |
char *namp; |
char *namp; |
char hostname[MAXHOSTNAMELEN]; |
char hostname[MAXHOSTNAMELEN]; |
WINDOW *wnd; |
WINDOW *wnd; |
long CMDLINE; |
long CMDLINE; |
|
|
WINDOW *wload; /* one line window for load average */ |
static WINDOW *wload; /* one line window for load average */ |
|
|
static void usage __P((void)); |
static void usage __P((void)); |
|
|
|
|
int argc; |
int argc; |
char **argv; |
char **argv; |
{ |
{ |
int ch; |
int ch, ret; |
char errbuf[_POSIX2_LINE_MAX]; |
char errbuf[_POSIX2_LINE_MAX]; |
|
|
while ((ch = getopt(argc, argv, "w:")) != -1) |
while ((ch = getopt(argc, argv, "M:N:w:")) != -1) |
switch(ch) { |
switch(ch) { |
case 'w': |
case 'M': |
if ((naptime = atoi(optarg)) <= 0) |
memf = optarg; |
errx(1, "interval <= 0."); |
break; |
break; |
case 'N': |
default: |
nlistf = optarg; |
usage(); |
break; |
} |
case 'w': |
argc -= optind; |
if ((naptime = atoi(optarg)) <= 0) |
argv += optind; |
errx(1, "interval <= 0."); |
|
break; |
|
case '?': |
|
default: |
|
usage(); |
|
} |
|
argc -= optind; |
|
argv += optind; |
|
/* |
|
* Discard setgid privileges if not the running kernel so that bad |
|
* guys can't print interesting stuff from kernel memory. |
|
*/ |
|
if (nlistf != NULL || memf != NULL) { |
|
setegid(getgid()); |
|
setgid(getgid()); |
|
} |
|
|
while (argc > 0) { |
while (argc > 0) { |
if (isdigit(argv[0][0])) { |
if (isdigit(argv[0][0])) { |
|
|
errx(1, "unknown request: %s", &argv[0][0]); |
errx(1, "unknown request: %s", &argv[0][0]); |
curcmd = p; |
curcmd = p; |
} |
} |
argc--; |
argc--, argv++; |
argv++; |
|
} |
} |
kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); |
kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf); |
if (kd == NULL) { |
if (kd == NULL) { |
error("%s", errbuf); |
error("%s", errbuf); |
exit(1); |
exit(1); |
} |
} |
|
|
signal(SIGINT, sigdie); |
if ((ret = kvm_nlist(kd, namelist)) == -1) |
siginterrupt(SIGINT, 1); |
errx(1, "%s", kvm_geterr(kd)); |
signal(SIGQUIT, sigdie); |
else if (ret) |
siginterrupt(SIGQUIT, 1); |
nlisterr(namelist); |
signal(SIGTERM, sigdie); |
|
siginterrupt(SIGTERM, 1); |
|
|
|
|
if (namelist[X_FIRST].n_type == 0) |
|
errx(1, "couldn't read namelist"); |
|
signal(SIGINT, die); |
|
signal(SIGQUIT, die); |
|
signal(SIGTERM, die); |
|
|
/* |
/* |
* Initialize display. Load average appears in a one line |
* Initialize display. Load average appears in a one line |
* window of its own. Current command's display appears in |
* window of its own. Current command's display appears in |
|
|
wnd = (*curcmd->c_open)(); |
wnd = (*curcmd->c_open)(); |
if (wnd == NULL) { |
if (wnd == NULL) { |
warnx("couldn't initialize display"); |
warnx("couldn't initialize display"); |
die(); |
die(0); |
} |
} |
wload = newwin(1, 0, 3, 20); |
wload = newwin(1, 0, 3, 20); |
if (wload == NULL) { |
if (wload == NULL) { |
warnx("couldn't set up load average window"); |
warnx("couldn't set up load average window"); |
die(); |
die(0); |
} |
} |
gethostname(hostname, sizeof (hostname)); |
gethostname(hostname, sizeof (hostname)); |
gethz(); |
NREAD(X_HZ, &hz, LONG); |
|
NREAD(X_STATHZ, &stathz, LONG); |
(*curcmd->c_init)(); |
(*curcmd->c_init)(); |
curcmd->c_flags |= CF_INIT; |
curcmd->c_flags |= CF_INIT; |
labels(); |
labels(); |
|
|
dellave = 0.0; |
dellave = 0.0; |
|
|
signal(SIGALRM, sigdisplay); |
signal(SIGALRM, display); |
siginterrupt(SIGALRM, 1); |
signal(SIGWINCH, resize); |
signal(SIGWINCH, sigwinch); |
display(0); |
siginterrupt(SIGWINCH, 1); |
|
gotdisplay = 1; |
|
noecho(); |
noecho(); |
crmode(); |
crmode(); |
keyboard(); |
keyboard(); |
/*NOTREACHED*/ |
/*NOTREACHED*/ |
} |
} |
|
|
void |
|
gethz() |
|
{ |
|
struct clockinfo cinf; |
|
size_t size = sizeof(cinf); |
|
int mib[2]; |
|
|
|
mib[0] = CTL_KERN; |
|
mib[1] = KERN_CLOCKRATE; |
|
if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1) |
|
return; |
|
stathz = cinf.stathz; |
|
hz = cinf.hz; |
|
} |
|
|
|
static void |
static void |
usage() |
usage() |
{ |
{ |
|
|
} |
} |
|
|
void |
void |
sigdisplay(signo) |
display(signo) |
int signo; |
int signo; |
{ |
{ |
gotdisplay = 1; |
|
} |
|
|
|
void |
|
display(void) |
|
{ |
|
int i, j; |
int i, j; |
|
|
/* Get the load average over the last minute. */ |
/* Get the load average over the last minute. */ |
|
|
if (dellave < 0.05) |
if (dellave < 0.05) |
c = '|'; |
c = '|'; |
dellave = avenrun[0]; |
dellave = avenrun[0]; |
wmove(wload, 0, 0); |
wmove(wload, 0, 0); wclrtoeol(wload); |
wclrtoeol(wload); |
|
for (i = (j > 50) ? 50 : j; i > 0; i--) |
for (i = (j > 50) ? 50 : j; i > 0; i--) |
waddch(wload, c); |
waddch(wload, c); |
if (j > 50) |
if (j > 50) |
|
|
clrtoeol(); |
clrtoeol(); |
} |
} |
|
|
volatile sig_atomic_t gotdie; |
|
volatile sig_atomic_t gotdisplay; |
|
volatile sig_atomic_t gotwinch; |
|
|
|
void |
void |
sigdie(signo) |
die(signo) |
int signo; |
int signo; |
{ |
{ |
gotdie = 1; |
|
} |
|
|
|
void |
|
die() |
|
{ |
|
if (wnd) { |
if (wnd) { |
move(CMDLINE, 0); |
move(CMDLINE, 0); |
clrtoeol(); |
clrtoeol(); |
|
|
} |
} |
|
|
void |
void |
sigwinch(signo) |
resize(signo) |
int signo; |
int signo; |
{ |
{ |
gotwinch = 1; |
sigset_t mask, oldmask; |
|
|
|
sigemptyset(&mask); |
|
sigaddset(&mask, SIGALRM); |
|
sigprocmask(SIG_BLOCK, &mask, &oldmask); |
|
clearok(curscr, TRUE); |
|
wrefresh(curscr); |
|
sigprocmask(SIG_SETMASK, &oldmask, NULL); |
} |
} |
|
|
|
|