summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephan Krempel <krempel@par-tec.com>2013-01-25 02:48:46 +0000
committerPádraig Brady <P@draigBrady.com>2013-01-26 02:38:52 +0000
commitf8c0258d4643dbabc461a84d0b940be44a680a9b (patch)
treea693b5ef23d5314a2aa835f8aea213a828b16530 /src
parent2238ab574191d30b89a007b760c616efaf9c219c (diff)
downloadcoreutils-f8c0258d4643dbabc461a84d0b940be44a680a9b.tar.xz
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
Diffstat (limited to 'src')
-rw-r--r--src/timeout.c15
1 files changed, 15 insertions, 0 deletions
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