Module Name: src Committed By: dholland Date: Thu Nov 24 00:05:13 UTC 2016
Modified Files: src/usr.bin/netstat: if.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/usr.bin/netstat/if.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/netstat/if.c diff -u src/usr.bin/netstat/if.c:1.89 src/usr.bin/netstat/if.c:1.90 --- src/usr.bin/netstat/if.c:1.89 Thu Jul 14 20:38:20 2016 +++ src/usr.bin/netstat/if.c Thu Nov 24 00:05:13 2016 @@ -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_sysctl(void); 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 @@ iftot_print_sum(struct iftot *cur, struc __dead static void sidewaysintpr_sysctl(unsigned interval) { + struct itimerval it; sigset_t emptyset; + sigset_t noalrm; unsigned line; set_lines(); @@ -724,9 +726,18 @@ sidewaysintpr_sysctl(unsigned interval) 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 @@ loop: 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 @@ static void 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 @@ sidewaysintpr_kvm(unsigned interval, u_l } 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 @@ loop: 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;