mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-02-14 03:12:10 +02:00
timeout: ensure we terminate command upon abnormal exit
* src/timeout.c (main): Use PR_SET_PDEATHSIG to ensure the child is terminated even if the parent terminates abnormally. * tests/timeout/timeout-group.sh: Add a case to ensure sending SIGKILL results in the termination of the monitored command. * NEWS: Mention the improvement.
This commit is contained in:
3
NEWS
3
NEWS
@@ -46,6 +46,9 @@ GNU coreutils NEWS -*- outline -*-
|
||||
|
||||
csplit, ls, and sort, now handle a more complete set of terminating signals.
|
||||
|
||||
'timeout' on Linux will always terminate the child in the case where the
|
||||
timeout process itself dies, like when it receives a KILL signal for example.
|
||||
|
||||
** Build-related
|
||||
|
||||
'kill' and 'uptime' are no longer built by default. These programs can be
|
||||
|
||||
@@ -592,6 +592,14 @@ main (int argc, char **argv)
|
||||
}
|
||||
else if (monitored_pid == 0) /* child */
|
||||
{
|
||||
#if HAVE_PRCTL
|
||||
/* Add protection if the parent dies without signalling child. */
|
||||
prctl (PR_SET_PDEATHSIG, term_signal);
|
||||
#endif
|
||||
/* If we're already reparented to init, don't proceed. */
|
||||
if (getppid () == 1)
|
||||
return EXIT_CANCELED;
|
||||
|
||||
/* Restore signal mask for child. */
|
||||
if (sigprocmask (SIG_SETMASK, &orig_set, nullptr) != 0)
|
||||
{
|
||||
|
||||
@@ -76,6 +76,13 @@ check_timeout_cmd_running()
|
||||
{ sleep $delay; return 1; }
|
||||
}
|
||||
|
||||
check_timeout_cmd_exiting()
|
||||
{
|
||||
local delay="$1"
|
||||
test -e sig.received ||
|
||||
{ sleep $delay; return 1; }
|
||||
}
|
||||
|
||||
# Terminate any background processes
|
||||
cleanup_() { kill $pid 2>/dev/null && wait $pid; }
|
||||
|
||||
@@ -88,9 +95,20 @@ retry_delay_ check_timeout_cmd_running .1 6 || fail=1
|
||||
kill -USR1 -- -$pid
|
||||
wait
|
||||
test -e sig.received || fail=1
|
||||
|
||||
rm -f sig.received timeout.running
|
||||
|
||||
# On Linux ensure we kill the monitored command
|
||||
# even if we're terminated abnormally (e.g., get SIGKILL).
|
||||
if grep '^#define HAVE_PRCTL 1' "$CONFIG_HEADER" >/dev/null; then
|
||||
timeout -sUSR1 25 ./timeout.cmd 20 & pid=$!
|
||||
# Wait 6.3s for timeout.cmd to start
|
||||
retry_delay_ check_timeout_cmd_running .1 6 || fail=1
|
||||
kill -KILL -- $pid
|
||||
wait
|
||||
# Wait 6.3s for timeout.cmd to exit
|
||||
retry_delay_ check_timeout_cmd_exiting .1 6 || fail=1
|
||||
rm -f sig.received timeout.running
|
||||
fi
|
||||
|
||||
# Ensure cascaded timeouts work
|
||||
# or more generally, ensure we timeout
|
||||
|
||||
Reference in New Issue
Block a user