summaryrefslogtreecommitdiff
path: root/src/timeout.c
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2013-11-26 14:27:25 +0000
committerPádraig Brady <P@draigBrady.com>2013-11-27 01:30:46 +0000
commitc3523181bd487539f308113620564756c29279cc (patch)
tree09b2a1039b67a664dc0660fdc0cc51e723597e39 /src/timeout.c
parent6b91f64ed9e15c9df0767f4658de9ba4532456cf (diff)
downloadcoreutils-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/timeout.c')
-rw-r--r--src/timeout.c13
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)