Make systat(1) accept fractional number of seconds.
Make old alarm(3)-based code use select(2). MFC after: 2 weeks
This commit is contained in:
parent
6c6afc2093
commit
5d4e58ed8e
@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
|
||||
static const char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/29/95";
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
@ -49,10 +51,9 @@ command(const char *cmd)
|
||||
{
|
||||
struct cmdtab *p;
|
||||
char *cp, *tmpstr, *tmpstr1;
|
||||
int interval, omask;
|
||||
double t;
|
||||
|
||||
tmpstr = tmpstr1 = strdup(cmd);
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
for (cp = tmpstr1; *cp && !isspace(*cp); cp++)
|
||||
;
|
||||
if (*cp)
|
||||
@ -68,7 +69,7 @@ command(const char *cmd)
|
||||
goto done;
|
||||
}
|
||||
if (strcmp(tmpstr1, "stop") == 0) {
|
||||
alarm(0);
|
||||
delay = 0;
|
||||
mvaddstr(CMDLINE, 0, "Refresh disabled.");
|
||||
clrtoeol();
|
||||
goto done;
|
||||
@ -88,19 +89,23 @@ command(const char *cmd)
|
||||
clrtoeol();
|
||||
goto done;
|
||||
}
|
||||
interval = atoi(tmpstr1);
|
||||
if (interval <= 0 &&
|
||||
(strcmp(tmpstr1, "start") == 0 || strcmp(tmpstr1, "interval") == 0)) {
|
||||
interval = *cp ? atoi(cp) : naptime;
|
||||
if (interval <= 0) {
|
||||
error("%d: bad interval.", interval);
|
||||
goto done;
|
||||
t = strtod(tmpstr1, NULL) * 1000000.0;
|
||||
if (t > 0 && t < (double)UINT_MAX)
|
||||
delay = (unsigned int)t;
|
||||
if ((t <= 0 || t > (double)UINT_MAX) &&
|
||||
(strcmp(tmpstr1, "start") == 0 ||
|
||||
strcmp(tmpstr1, "interval") == 0)) {
|
||||
if (*cp != '\0') {
|
||||
t = strtod(cp, NULL) * 1000000.0;
|
||||
if (t <= 0 || t >= (double)UINT_MAX) {
|
||||
error("%d: bad interval.", (int)t);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (interval > 0) {
|
||||
alarm(0);
|
||||
naptime = interval;
|
||||
display(0);
|
||||
if (t > 0) {
|
||||
delay = (unsigned int)t;
|
||||
display();
|
||||
status();
|
||||
goto done;
|
||||
}
|
||||
@ -112,7 +117,6 @@ command(const char *cmd)
|
||||
if (p) {
|
||||
if (curcmd == p)
|
||||
goto done;
|
||||
alarm(0);
|
||||
(*curcmd->c_close)(wnd);
|
||||
curcmd->c_flags &= ~CF_INIT;
|
||||
wnd = (*p->c_open)();
|
||||
@ -133,14 +137,13 @@ command(const char *cmd)
|
||||
}
|
||||
curcmd = p;
|
||||
labels();
|
||||
display(0);
|
||||
display();
|
||||
status();
|
||||
goto done;
|
||||
}
|
||||
if (curcmd->c_cmd == 0 || !(*curcmd->c_cmd)(tmpstr1, cp))
|
||||
error("%s: Unknown command.", tmpstr1);
|
||||
done:
|
||||
sigsetmask(omask);
|
||||
free(tmpstr);
|
||||
}
|
||||
|
||||
@ -177,7 +180,7 @@ status(void)
|
||||
{
|
||||
|
||||
error("Showing %s, refresh every %d seconds.",
|
||||
curcmd->c_name, naptime);
|
||||
curcmd->c_name, delay / 1000000);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -49,11 +49,12 @@ extern int CMDLINE;
|
||||
extern int dk_ndrive;
|
||||
extern int hz, stathz;
|
||||
extern double hertz; /* sampling frequency for cp_time and dk_time */
|
||||
extern int naptime, col;
|
||||
extern int col;
|
||||
extern int nhosts;
|
||||
extern int nports;
|
||||
extern int protos;
|
||||
extern int verbose;
|
||||
extern unsigned int delay;
|
||||
|
||||
struct inpcb;
|
||||
|
||||
@ -87,7 +88,7 @@ int cmdnetstat(const char *, const char *);
|
||||
struct cmdtab *lookup(const char *);
|
||||
void command(const char *);
|
||||
void die(int);
|
||||
void display(int);
|
||||
void display(void);
|
||||
int dkinit(void);
|
||||
int dkcmd(char *, char *);
|
||||
void error(const char *fmt, ...) __printflike(1, 2);
|
||||
|
@ -138,7 +138,7 @@ domode(struct icmpstat *ret)
|
||||
switch(currentmode) {
|
||||
case display_RATE:
|
||||
sub = &oldstat;
|
||||
divisor = naptime;
|
||||
divisor = (delay > 1000000) ? delay / 1000000 : 1;
|
||||
break;
|
||||
case display_DELTA:
|
||||
sub = &oldstat;
|
||||
|
@ -137,7 +137,7 @@ domode(struct icmp6stat *ret)
|
||||
switch(currentmode) {
|
||||
case display_RATE:
|
||||
sub = &oldstat;
|
||||
divisor = naptime;
|
||||
divisor = (delay > 1000000) ? delay / 1000000 : 1;
|
||||
break;
|
||||
case display_DELTA:
|
||||
sub = &oldstat;
|
||||
|
@ -146,7 +146,7 @@ domode(struct stat *ret)
|
||||
switch(currentmode) {
|
||||
case display_RATE:
|
||||
sub = &oldstat;
|
||||
divisor = naptime;
|
||||
divisor = (delay > 1000000) ? delay / 1000000 : 1;
|
||||
break;
|
||||
case display_DELTA:
|
||||
sub = &oldstat;
|
||||
|
@ -142,7 +142,7 @@ domode(struct ip6stat *ret)
|
||||
switch(currentmode) {
|
||||
case display_RATE:
|
||||
sub = &oldstat;
|
||||
divisor = naptime;
|
||||
divisor = (delay > 1000000) ? delay / 1000000 : 1;
|
||||
break;
|
||||
case display_DELTA:
|
||||
sub = &oldstat;
|
||||
|
@ -35,88 +35,146 @@ __FBSDID("$FreeBSD$");
|
||||
static const char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "systat.h"
|
||||
#include "extern.h"
|
||||
|
||||
static char line[80];
|
||||
static int keyboard_dispatch(int ch);
|
||||
|
||||
int
|
||||
keyboard(void)
|
||||
{
|
||||
char line[80];
|
||||
int ch, oldmask;
|
||||
int ch, n;
|
||||
struct timeval last, intvl, now, tm;
|
||||
fd_set rfds;
|
||||
|
||||
/* Set initial timings */
|
||||
gettimeofday(&last, NULL);
|
||||
intvl.tv_sec = delay / 1000000;
|
||||
intvl.tv_usec = delay % 1000000;
|
||||
for (;;) {
|
||||
col = 0;
|
||||
move(CMDLINE, 0);
|
||||
do {
|
||||
refresh();
|
||||
ch = getch();
|
||||
if (ch == ERR) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
exit(1);
|
||||
for (;;) {
|
||||
/* Determine interval to sleep */
|
||||
(void)gettimeofday(&now, NULL);
|
||||
tm.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
|
||||
tm.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
|
||||
while (tm.tv_usec < 0) {
|
||||
tm.tv_usec += 1000000;
|
||||
tm.tv_sec--;
|
||||
}
|
||||
if (ch >= 'A' && ch <= 'Z')
|
||||
ch += 'a' - 'A';
|
||||
if (col == 0) {
|
||||
#define mask(s) (1 << ((s) - 1))
|
||||
if (ch == CTRL('l')) {
|
||||
oldmask = sigblock(mask(SIGALRM));
|
||||
wrefresh(curscr);
|
||||
sigsetmask(oldmask);
|
||||
continue;
|
||||
}
|
||||
if (ch == CTRL('g')) {
|
||||
oldmask = sigblock(mask(SIGALRM));
|
||||
status();
|
||||
sigsetmask(oldmask);
|
||||
continue;
|
||||
}
|
||||
if (ch != ':')
|
||||
continue;
|
||||
move(CMDLINE, 0);
|
||||
clrtoeol();
|
||||
while (tm.tv_usec >= 1000000) {
|
||||
tm.tv_usec -= 1000000;
|
||||
tm.tv_sec++;
|
||||
}
|
||||
if (ch == erasechar() && col > 0) {
|
||||
if (col == 1 && line[0] == ':')
|
||||
continue;
|
||||
col--;
|
||||
goto doerase;
|
||||
}
|
||||
if (ch == CTRL('w') && col > 0) {
|
||||
while (--col >= 0 && isspace(line[col]))
|
||||
;
|
||||
col++;
|
||||
while (--col >= 0 && !isspace(line[col]))
|
||||
if (col == 0 && line[0] == ':')
|
||||
break;
|
||||
col++;
|
||||
goto doerase;
|
||||
}
|
||||
if (ch == killchar() && col > 0) {
|
||||
col = 0;
|
||||
if (line[0] == ':')
|
||||
col++;
|
||||
doerase:
|
||||
move(CMDLINE, col);
|
||||
clrtoeol();
|
||||
if (tm.tv_sec < 0) {
|
||||
/* We have to update screen immediately */
|
||||
display();
|
||||
gettimeofday(&last, NULL);
|
||||
continue;
|
||||
}
|
||||
if (isprint(ch) || ch == ' ') {
|
||||
line[col] = ch;
|
||||
mvaddch(CMDLINE, col, ch);
|
||||
col++;
|
||||
|
||||
/* Prepare select */
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(STDIN_FILENO, &rfds);
|
||||
n = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tm);
|
||||
|
||||
if (n > 0) {
|
||||
/* Read event on stdin */
|
||||
ch = getch();
|
||||
|
||||
if (keyboard_dispatch(ch) == 0) {
|
||||
refresh();
|
||||
continue;
|
||||
}
|
||||
|
||||
line[col] = '\0';
|
||||
command(line + 1);
|
||||
/* Refresh delay */
|
||||
intvl.tv_sec = delay / 1000000;
|
||||
intvl.tv_usec = delay % 1000000;
|
||||
refresh();
|
||||
break;
|
||||
}
|
||||
} while (col == 0 || (ch != '\r' && ch != '\n'));
|
||||
line[col] = '\0';
|
||||
oldmask = sigblock(mask(SIGALRM));
|
||||
command(line + 1);
|
||||
sigsetmask(oldmask);
|
||||
|
||||
if (n < 0 && errno != EINTR)
|
||||
exit(1);
|
||||
|
||||
/* Timeout or signal. Call display another time */
|
||||
display();
|
||||
gettimeofday(&last, NULL);
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
static int
|
||||
keyboard_dispatch(int ch)
|
||||
{
|
||||
|
||||
if (ch == ERR) {
|
||||
if (errno == EINTR)
|
||||
return 0;
|
||||
exit(1);
|
||||
}
|
||||
if (ch >= 'A' && ch <= 'Z')
|
||||
ch += 'a' - 'A';
|
||||
if (col == 0) {
|
||||
if (ch == CTRL('l')) {
|
||||
wrefresh(curscr);
|
||||
return 0;
|
||||
}
|
||||
if (ch == CTRL('g')) {
|
||||
status();
|
||||
return 0;
|
||||
}
|
||||
if (ch != ':')
|
||||
return 0;
|
||||
move(CMDLINE, 0);
|
||||
clrtoeol();
|
||||
}
|
||||
if (ch == erasechar() && col > 0) {
|
||||
if (col == 1 && line[0] == ':')
|
||||
return 0;
|
||||
col--;
|
||||
goto doerase;
|
||||
}
|
||||
if (ch == CTRL('w') && col > 0) {
|
||||
while (--col >= 0 && isspace(line[col]))
|
||||
;
|
||||
col++;
|
||||
while (--col >= 0 && !isspace(line[col]))
|
||||
if (col == 0 && line[0] == ':')
|
||||
return 1;
|
||||
col++;
|
||||
goto doerase;
|
||||
}
|
||||
if (ch == killchar() && col > 0) {
|
||||
col = 0;
|
||||
if (line[0] == ':')
|
||||
col++;
|
||||
doerase:
|
||||
move(CMDLINE, col);
|
||||
clrtoeol();
|
||||
return 0;
|
||||
}
|
||||
if (isprint(ch) || ch == ' ') {
|
||||
line[col] = ch;
|
||||
mvaddch(CMDLINE, col, ch);
|
||||
col++;
|
||||
}
|
||||
|
||||
if (col == 0 || (ch != '\r' && ch != '\n'))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ kvm_t *kd;
|
||||
sig_t sigtstpdfl;
|
||||
double avenrun[3];
|
||||
int col;
|
||||
int naptime = 5;
|
||||
unsigned int delay = 5000000; /* in microseconds */
|
||||
int verbose = 1; /* to report kvm read errs */
|
||||
struct clockinfo clkinfo;
|
||||
double hertz;
|
||||
@ -82,6 +82,7 @@ main(int argc, char **argv)
|
||||
{
|
||||
char errbuf[_POSIX2_LINE_MAX], dummy;
|
||||
size_t size;
|
||||
double t;
|
||||
|
||||
(void) setlocale(LC_ALL, "");
|
||||
|
||||
@ -97,9 +98,9 @@ main(int argc, char **argv)
|
||||
errx(1, "%s: unknown request", &argv[0][1]);
|
||||
curcmd = p;
|
||||
} else {
|
||||
naptime = atoi(argv[0]);
|
||||
if (naptime <= 0)
|
||||
naptime = 5;
|
||||
t = strtod(argv[0], NULL) * 1000000.0;
|
||||
if (t > 0 && t < (double)UINT_MAX)
|
||||
delay = (unsigned int)t;
|
||||
}
|
||||
argc--, argv++;
|
||||
}
|
||||
@ -166,8 +167,7 @@ main(int argc, char **argv)
|
||||
|
||||
dellave = 0.0;
|
||||
|
||||
signal(SIGALRM, display);
|
||||
display(0);
|
||||
display();
|
||||
noecho();
|
||||
crmode();
|
||||
keyboard();
|
||||
@ -192,7 +192,7 @@ labels(void)
|
||||
}
|
||||
|
||||
void
|
||||
display(int signo __unused)
|
||||
display()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@ -223,7 +223,6 @@ display(int signo __unused)
|
||||
wrefresh(wnd);
|
||||
move(CMDLINE, col);
|
||||
refresh();
|
||||
alarm(naptime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)systat.1 8.2 (Berkeley) 12/30/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 14, 2007
|
||||
.Dd September 17, 2012
|
||||
.Dt SYSTAT 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -109,6 +109,7 @@ full detail below.
|
||||
The
|
||||
.Ar refresh-value
|
||||
specifies the screen refresh time interval in seconds.
|
||||
Time interval can be fractional.
|
||||
.El
|
||||
.Pp
|
||||
Certain characters cause immediate action by
|
||||
|
@ -147,7 +147,7 @@ domode(struct tcpstat *ret)
|
||||
switch(currentmode) {
|
||||
case display_RATE:
|
||||
sub = &oldstat;
|
||||
divisor = naptime;
|
||||
divisor = (delay > 1000000) ? delay / 1000000 : 1;
|
||||
break;
|
||||
case display_DELTA:
|
||||
sub = &oldstat;
|
||||
|
Loading…
Reference in New Issue
Block a user