diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | src/timeout.c | 17 | ||||
-rwxr-xr-x | tests/misc/timeout-group | 21 |
3 files changed, 35 insertions, 6 deletions
@@ -14,6 +14,9 @@ GNU coreutils NEWS -*- outline -*- split --number l/... no longer creates extraneous files in certain cases. [bug introduced in coreutils-8.8] + timeout now sends signals to commands that create their own process group. + [bug introduced in coreutils-7.0] + ** Changes in behavior chmod, chown and chgrp now output the original attributes in messages, diff --git a/src/timeout.c b/src/timeout.c index 8f0980b96..ab54ed675 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -104,8 +104,6 @@ cleanup (int sig) } if (monitored_pid) { - int where = foreground ? monitored_pid : 0; - if (sigs_to_ignore[sig]) { sigs_to_ignore[sig] = 0; @@ -119,9 +117,20 @@ cleanup (int sig) kill_after = 0; /* Don't let later signals reset kill alarm. */ } - send_sig (where, sig); + /* Send the signal directly to the monitored child, + in case it has itself become group leader, + or is not running in a separate group. */ + send_sig (monitored_pid, sig); + /* The normal case is the job has remained in our + newly created process group, so send to all processes in that. */ + if (!foreground) + send_sig (0, sig); if (sig != SIGKILL && sig != SIGCONT) - send_sig (where, SIGCONT); + { + send_sig (monitored_pid, SIGCONT); + if (!foreground) + send_sig (0, SIGCONT); + } } else /* we're the child or the child is not exec'd yet. */ _exit (128 + sig); diff --git a/tests/misc/timeout-group b/tests/misc/timeout-group index 0c3caa0f0..fedd53a60 100755 --- a/tests/misc/timeout-group +++ b/tests/misc/timeout-group @@ -34,13 +34,13 @@ cat > timeout.cmd <<\EOF #!/bin/sh trap 'touch int.received; exit' INT touch timeout.running -sleep 10 +sleep $1 EOF chmod a+x timeout.cmd cat > group.sh <<\EOF #!/bin/sh -timeout --foreground 5 ./timeout.cmd& +timeout --foreground 5 ./timeout.cmd 10& wait EOF chmod a+x group.sh @@ -55,4 +55,21 @@ env kill -INT -- -$! wait test -e int.received || fail=1 +rm -f int.received timeout.running + + +# Ensure cascaded timeouts work +# or more generally, ensure we timeout +# commands that create their own group +# This didn't work before 8.13. + +# Note the first timeout must send a signal that +# the second is handling for it to be propagated to the command. +# SIGINT, SIGTERM, SIGALRM etc. are implicit. +timeout -sALRM 2 timeout -sINT 10 ./timeout.cmd 5& +until test -e timeout.running; do sleep .1; done +kill -ALRM $! +wait +test -e int.received || fail=1 + Exit $fail |