Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/netstat Fix "sidewaysintpr", the thing that prints i...



details:   https://anonhg.NetBSD.org/src/rev/e7d98a330e9f
branches:  trunk
changeset: 819236:e7d98a330e9f
user:      dholland <dholland%NetBSD.org@localhost>
date:      Thu Nov 24 00:05:13 2016 +0000

description:
Fix "sidewaysintpr", the thing that prints interface statistics in a
loop, to use signals properly. There are two copies of this code; one
uses kvm and the other uses sysctls. One copy had been updated to use
sigset_t and sigsuspend; the other was using vintage sigpause(). Sync
up the code so both use sigpause. Also, use sig_atomic_t, and block
SIGALRM when not waiting for it to avoid a small and unlikely but real
race.

Since the non-modernized copy of the code *had* for some been
modernized to use setitimer instead of just alarm(), propagate that
change to the other copy.

These copies could share more logic than they do.

diffstat:

 usr.bin/netstat/if.c |  44 +++++++++++++++++++++++++++++---------------
 1 files changed, 29 insertions(+), 15 deletions(-)

diffs (119 lines):

diff -r e1f0876caaef -r e7d98a330e9f usr.bin/netstat/if.c
--- a/usr.bin/netstat/if.c      Wed Nov 23 23:30:50 2016 +0000
+++ b/usr.bin/netstat/if.c      Thu Nov 24 00:05:13 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.89 2016/07/14 20:38:20 christos Exp $ */
+/*     $NetBSD: if.c,v 1.90 2016/11/24 00:05:13 dholland Exp $ */
 
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";
 #else
-__RCSID("$NetBSD: if.c,v 1.89 2016/07/14 20:38:20 christos Exp $");
+__RCSID("$NetBSD: if.c,v 1.90 2016/11/24 00:05:13 dholland Exp $");
 #endif
 #endif /* not lint */
 
@@ -100,7 +100,7 @@
 static void intpr_kvm(u_long, void (*)(const char *));
 
 struct iftot iftot[MAXIF], ip_cur, ip_old, sum_cur, sum_old;
-bool   signalled;                      /* set if alarm goes off "early" */
+static sig_atomic_t signalled;         /* set when alarm goes off */
 
 static unsigned redraw_lines = 21;
 
@@ -712,7 +712,9 @@
 __dead static void
 sidewaysintpr_sysctl(unsigned interval)
 {
+       struct itimerval it;
        sigset_t emptyset;
+       sigset_t noalrm;
        unsigned line;
 
        set_lines();
@@ -724,9 +726,18 @@
                exit(1);
        }
 
-       (void)signal(SIGALRM, catchalarm);
+       sigemptyset(&emptyset);
+       sigemptyset(&noalrm);
+       sigaddset(&noalrm, SIGALRM);
+       sigprocmask(SIG_SETMASK, &noalrm, NULL);
+
        signalled = 0;
-       (void)alarm(interval);
+       (void)signal(SIGALRM, catchalarm);
+
+       it.it_interval.tv_sec = it.it_value.tv_sec = interval;
+       it.it_interval.tv_usec = it.it_value.tv_usec = 0;
+       setitimer(ITIMER_REAL, &it, NULL);
+
 banner:
        iftot_banner(&ip_cur);
 
@@ -749,11 +760,10 @@
        putchar('\n');
        fflush(stdout);
        line++;
-       sigemptyset(&emptyset);
-       if (!signalled)
+       if (signalled == 0) {
                sigsuspend(&emptyset);
+       }
        signalled = 0;
-       (void)alarm(interval);
        if (line == redraw_lines)
                goto banner;
        goto loop;
@@ -764,13 +774,14 @@
 sidewaysintpr_kvm(unsigned interval, u_long off)
 {
        struct itimerval it;
+       sigset_t emptyset;
+       sigset_t noalrm;
        struct ifnet ifnet;
        u_long firstifnet;
        struct iftot *ip, *total;
        unsigned line;
        struct iftot *lastif, *sum, *interesting;
        struct ifnet_head ifhead;       /* TAILQ_HEAD */
-       int oldmask;
 
        set_lines();
 
@@ -806,8 +817,13 @@
        }
        lastif = ip;
 
+       sigemptyset(&emptyset);
+       sigemptyset(&noalrm);
+       sigaddset(&noalrm, SIGALRM);
+       sigprocmask(SIG_SETMASK, &noalrm, NULL);
+
+       signalled = 0;
        (void)signal(SIGALRM, catchalarm);
-       signalled = false;
 
        it.it_interval.tv_sec = it.it_value.tv_sec = interval;
        it.it_interval.tv_usec = it.it_value.tv_usec = 0;
@@ -980,12 +996,10 @@
        putchar('\n');
        fflush(stdout);
        line++;
-       oldmask = sigblock(sigmask(SIGALRM));
-       if (! signalled) {
-               sigpause(0);
+       if (signalled == 0) {
+               sigsuspend(&emptyset);
        }
-       sigsetmask(oldmask);
-       signalled = false;
+       signalled = 0;
        if (line == redraw_lines)
                goto banner;
        goto loop;



Home | Main Index | Thread Index | Old Index