From f8c0258d4643dbabc461a84d0b940be44a680a9b Mon Sep 17 00:00:00 2001 From: Stephan Krempel Date: Fri, 25 Jan 2013 02:48:46 +0000 Subject: timeout: ensure a blocked SIGALRM from the parent is unblocked * src/timeout.c (unblock_signal): A new function to unblock a specified signal, or warn if not possible. (set_timeout): Ensure SIGALRM is unblocked before we setup the timer. * tests/misc/timeout-blocked.pl: A new test for the issue. * tests/local.mk: Reference the new test. * NEWS: Mention the fix. Fixes: http://bugs.gnu.org/13535 --- src/timeout.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/timeout.c b/src/timeout.c index b163a0ee8..2ffd2b119 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -102,6 +102,16 @@ static struct option const long_options[] = {NULL, 0, NULL, 0} }; +static void +unblock_signal (int sig) +{ + sigset_t unblock_set; + sigemptyset (&unblock_set); + sigaddset (&unblock_set, sig); + if (sigprocmask (SIG_UNBLOCK, &unblock_set, NULL) != 0) + error (0, errno, _("warning: sigprocmask")); +} + /* Start the timeout after which we'll receive a SIGALRM. Round DURATION up to the next representable value. Treat out-of-range values as if they were maximal, @@ -110,6 +120,11 @@ static struct option const long_options[] = static void settimeout (double duration) { + + /* We configure timers below so that SIGALRM is sent on expiry. + Therefore ensure we don't inherit a mask blocking SIGALRM. */ + unblock_signal (SIGALRM); + /* timer_settime() provides potentially nanosecond resolution. setitimer() is more portable (to Darwin for example), but only provides microsecond resolution and thus is -- cgit v1.2.3-54-g00ecf