summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2012-09-17 13:36:47 +0000
committermelifaro <melifaro@FreeBSD.org>2012-09-17 13:36:47 +0000
commit5d4e58ed8e46965b1c3efc1c7bb56298074b68dd (patch)
tree214963815700597764924eb2844d27ae9e182f57 /usr.bin
parent6c6afc2093a4a82b3599c9c5860b5ab439a2d19d (diff)
downloadFreeBSD-src-5d4e58ed8e46965b1c3efc1c7bb56298074b68dd.zip
FreeBSD-src-5d4e58ed8e46965b1c3efc1c7bb56298074b68dd.tar.gz
Make systat(1) accept fractional number of seconds.
Make old alarm(3)-based code use select(2). MFC after: 2 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/systat/cmds.c39
-rw-r--r--usr.bin/systat/extern.h5
-rw-r--r--usr.bin/systat/icmp.c2
-rw-r--r--usr.bin/systat/icmp6.c2
-rw-r--r--usr.bin/systat/ip.c2
-rw-r--r--usr.bin/systat/ip6.c2
-rw-r--r--usr.bin/systat/keyboard.c184
-rw-r--r--usr.bin/systat/main.c15
-rw-r--r--usr.bin/systat/systat.13
-rw-r--r--usr.bin/systat/tcp.c2
10 files changed, 159 insertions, 97 deletions
diff --git a/usr.bin/systat/cmds.c b/usr.bin/systat/cmds.c
index 6ad7443..46b3931 100644
--- a/usr.bin/systat/cmds.c
+++ b/usr.bin/systat/cmds.c
@@ -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
diff --git a/usr.bin/systat/extern.h b/usr.bin/systat/extern.h
index 9ab8a3a..393fa1c 100644
--- a/usr.bin/systat/extern.h
+++ b/usr.bin/systat/extern.h
@@ -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);
diff --git a/usr.bin/systat/icmp.c b/usr.bin/systat/icmp.c
index e3a5280..6085a90 100644
--- a/usr.bin/systat/icmp.c
+++ b/usr.bin/systat/icmp.c
@@ -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;
diff --git a/usr.bin/systat/icmp6.c b/usr.bin/systat/icmp6.c
index 366d026..2a3bbb7 100644
--- a/usr.bin/systat/icmp6.c
+++ b/usr.bin/systat/icmp6.c
@@ -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;
diff --git a/usr.bin/systat/ip.c b/usr.bin/systat/ip.c
index cad79b7..8e12a6a 100644
--- a/usr.bin/systat/ip.c
+++ b/usr.bin/systat/ip.c
@@ -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;
diff --git a/usr.bin/systat/ip6.c b/usr.bin/systat/ip6.c
index 4702885..5d2c210 100644
--- a/usr.bin/systat/ip6.c
+++ b/usr.bin/systat/ip6.c
@@ -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;
diff --git a/usr.bin/systat/keyboard.c b/usr.bin/systat/keyboard.c
index e7e0014..d6d793a 100644
--- a/usr.bin/systat/keyboard.c
+++ b/usr.bin/systat/keyboard.c
@@ -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;
}
diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c
index 3c6b49f..a429f57 100644
--- a/usr.bin/systat/main.c
+++ b/usr.bin/systat/main.c
@@ -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
diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1
index 9ae6bcf..1b14209 100644
--- a/usr.bin/systat/systat.1
+++ b/usr.bin/systat/systat.1
@@ -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
diff --git a/usr.bin/systat/tcp.c b/usr.bin/systat/tcp.c
index 134aa9a..c9e8e9a 100644
--- a/usr.bin/systat/tcp.c
+++ b/usr.bin/systat/tcp.c
@@ -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;
OpenPOWER on IntegriCloud