From owner-svn-src-head@FreeBSD.ORG Mon Sep 17 13:36:48 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E71FC106564A; Mon, 17 Sep 2012 13:36:47 +0000 (UTC) (envelope-from melifaro@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D14758FC0C; Mon, 17 Sep 2012 13:36:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8HDalGM026656; Mon, 17 Sep 2012 13:36:47 GMT (envelope-from melifaro@svn.freebsd.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8HDalx3026645; Mon, 17 Sep 2012 13:36:47 GMT (envelope-from melifaro@svn.freebsd.org) Message-Id: <201209171336.q8HDalx3026645@svn.freebsd.org> From: "Alexander V. Chernikov" Date: Mon, 17 Sep 2012 13:36:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240605 - head/usr.bin/systat X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Sep 2012 13:36:48 -0000 Author: melifaro Date: Mon Sep 17 13:36:47 2012 New Revision: 240605 URL: http://svn.freebsd.org/changeset/base/240605 Log: Make systat(1) accept fractional number of seconds. Make old alarm(3)-based code use select(2). MFC after: 2 weeks Modified: head/usr.bin/systat/cmds.c head/usr.bin/systat/extern.h head/usr.bin/systat/icmp.c head/usr.bin/systat/icmp6.c head/usr.bin/systat/ip.c head/usr.bin/systat/ip6.c head/usr.bin/systat/keyboard.c head/usr.bin/systat/main.c head/usr.bin/systat/systat.1 head/usr.bin/systat/tcp.c Modified: head/usr.bin/systat/cmds.c ============================================================================== --- head/usr.bin/systat/cmds.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/cmds.c Mon Sep 17 13:36:47 2012 (r240605) @@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$"); static const char sccsid[] = "@(#)cmds.c 8.2 (Berkeley) 4/29/95"; #endif +#include + #include #include #include @@ -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 Modified: head/usr.bin/systat/extern.h ============================================================================== --- head/usr.bin/systat/extern.h Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/extern.h Mon Sep 17 13:36:47 2012 (r240605) @@ -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); Modified: head/usr.bin/systat/icmp.c ============================================================================== --- head/usr.bin/systat/icmp.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/icmp.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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; Modified: head/usr.bin/systat/icmp6.c ============================================================================== --- head/usr.bin/systat/icmp6.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/icmp6.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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; Modified: head/usr.bin/systat/ip.c ============================================================================== --- head/usr.bin/systat/ip.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/ip.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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; Modified: head/usr.bin/systat/ip6.c ============================================================================== --- head/usr.bin/systat/ip6.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/ip6.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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; Modified: head/usr.bin/systat/keyboard.c ============================================================================== --- head/usr.bin/systat/keyboard.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/keyboard.c Mon Sep 17 13:36:47 2012 (r240605) @@ -35,88 +35,146 @@ __FBSDID("$FreeBSD$"); static const char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93"; #endif +#include +#include + #include #include -#include #include #include +#include #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--; + } + while (tm.tv_usec >= 1000000) { + tm.tv_usec -= 1000000; + tm.tv_sec++; + } + if (tm.tv_sec < 0) { + /* We have to update screen immediately */ + display(); + gettimeofday(&last, NULL); + continue; } - 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); + + /* 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; } - if (ch != ':') - continue; - move(CMDLINE, 0); - clrtoeol(); - } - 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(); - continue; - } - if (isprint(ch) || ch == ' ') { - line[col] = ch; - mvaddch(CMDLINE, col, ch); - col++; + + 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; } Modified: head/usr.bin/systat/main.c ============================================================================== --- head/usr.bin/systat/main.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/main.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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 Modified: head/usr.bin/systat/systat.1 ============================================================================== --- head/usr.bin/systat/systat.1 Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/systat.1 Mon Sep 17 13:36:47 2012 (r240605) @@ -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 Modified: head/usr.bin/systat/tcp.c ============================================================================== --- head/usr.bin/systat/tcp.c Mon Sep 17 13:06:47 2012 (r240604) +++ head/usr.bin/systat/tcp.c Mon Sep 17 13:36:47 2012 (r240605) @@ -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;