diff options
author | Pádraig Brady <P@draigBrady.com> | 2013-11-26 14:27:25 +0000 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2013-11-27 01:30:46 +0000 |
commit | c3523181bd487539f308113620564756c29279cc (patch) | |
tree | 09b2a1039b67a664dc0660fdc0cc51e723597e39 /src | |
parent | 6b91f64ed9e15c9df0767f4658de9ba4532456cf (diff) | |
download | coreutils-c3523181bd487539f308113620564756c29279cc.tar.xz |
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().
Diffstat (limited to 'src')
-rw-r--r-- | src/timeout.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/timeout.c b/src/timeout.c index acb5a34aa..c8749d041 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) |