From c3523181bd487539f308113620564756c29279cc Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Tue, 26 Nov 2013 14:27:25 +0000 Subject: [PATCH] timeout: avoid unlikely issues with --kill-after * src/timeout.c (cleanup): When calling settimeout() from this signal handler, ensure we don't call out to error() or gettext(), which are not async-signal-safe. Also reset the errno which may be cleared by settimeout(). --- src/timeout.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/timeout.c b/src/timeout.c index acb5a34aa0..c8749d041b 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -118,7 +118,7 @@ unblock_signal (int sig) as that's more useful in practice than reporting an error. '0' means don't timeout. */ static void -settimeout (double duration) +settimeout (double duration, bool warn) { /* We configure timers below so that SIGALRM is sent on expiry. @@ -142,11 +142,12 @@ settimeout (double duration) return; else { - error (0, errno, _("warning: timer_settime")); + if (warn) + error (0, errno, _("warning: timer_settime")); timer_delete (timerid); } } - else if (errno != ENOSYS) + else if (warn && errno != ENOSYS) error (0, errno, _("warning: timer_create")); #endif @@ -190,10 +191,12 @@ cleanup (int sig) { if (kill_after) { + int saved_errno = errno; /* settimeout may reset. */ /* Start a new timeout after which we'll send SIGKILL. */ term_signal = SIGKILL; - settimeout (kill_after); + settimeout (kill_after, false); kill_after = 0; /* Don't let later signals reset kill alarm. */ + errno = saved_errno; } /* Send the signal directly to the monitored child, @@ -459,7 +462,7 @@ main (int argc, char **argv) pid_t wait_result; int status; - settimeout (timeout); + settimeout (timeout, true); while ((wait_result = waitpid (monitored_pid, &status, 0)) < 0 && errno == EINTR) -- 2.47.2