Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Sep 2012 13:36:47 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r240605 - head/usr.bin/systat
Message-ID:  <201209171336.q8HDalx3026645@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209171336.q8HDalx3026645>