diff options
author | 1995-10-28 00:54:54 +0000 | |
---|---|---|
committer | 1995-10-28 00:54:54 +0000 | |
commit | bc62ad8e8d210bb5ef11912491c84c29ea0fc8ef (patch) | |
tree | 3f06036f0e0eeaee05fbfa81ccccf1cb8bc33de8 /lib/libc/gen/sleep.c | |
parent | update from NetBSD (diff) | |
download | wireguard-openbsd-bc62ad8e8d210bb5ef11912491c84c29ea0fc8ef.tar.xz wireguard-openbsd-bc62ad8e8d210bb5ef11912491c84c29ea0fc8ef.zip |
Eliminate race by stopping timer before restarting it with remaining time
(one more system call).
Diffstat (limited to 'lib/libc/gen/sleep.c')
-rw-r--r-- | lib/libc/gen/sleep.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c index b090c5959d7..cba9c97b2e1 100644 --- a/lib/libc/gen/sleep.c +++ b/lib/libc/gen/sleep.c @@ -1,4 +1,4 @@ -/* $NetBSD: sleep.c,v 1.10 1995/05/03 12:52:43 mycroft Exp $ */ +/* $NetBSD: sleep.c,v 1.10.2.2 1995/10/26 22:05:50 pk Exp $ */ /* * Copyright (c) 1989, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: sleep.c,v 1.10 1995/05/03 12:52:43 mycroft Exp $"; +static char rcsid[] = "$NetBSD: sleep.c,v 1.10.2.2 1995/10/26 22:05:50 pk Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -45,6 +45,8 @@ static char rcsid[] = "$NetBSD: sleep.c,v 1.10 1995/05/03 12:52:43 mycroft Exp $ #include <signal.h> #include <unistd.h> +static volatile int ringring; + unsigned int sleep(seconds) unsigned int seconds; @@ -99,12 +101,28 @@ sleep(seconds) set = oset; sigdelset(&set, SIGALRM); + ringring = 0; (void) sigsuspend(&set); - sigaction(SIGALRM, &oact, NULL); - sigprocmask(SIG_SETMASK, &oset, NULL); - - (void) setitimer(ITIMER_REAL, &oitv, &itv); + if (ringring) { + /* Our alarm went off; timer is not currently running */ + sigaction(SIGALRM, &oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); + (void) setitimer(ITIMER_REAL, &oitv, &itv); + } else { + struct itimerval nulltv; + /* + * Interrupted by other signal; allow for pending + * SIGALRM to be processed before resetting handler, + * after first turning off the timer. + */ + timerclear(&nulltv.it_interval); + timerclear(&nulltv.it_value); + (void) setitimer(ITIMER_REAL, &nulltv, &itv); + sigprocmask(SIG_SETMASK, &oset, NULL); + sigaction(SIGALRM, &oact, NULL); + (void) setitimer(ITIMER_REAL, &oitv, NULL); + } if (timerisset(&diff)) timeradd(&itv.it_value, &diff, &itv.it_value); @@ -115,5 +133,5 @@ sleep(seconds) static void sleephandler() { - + ringring = 1; } |