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 <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

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 <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--;
+                       }
+                       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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to