timeout: support cascaded timeouts

* src/timeout.c (cleanup): Send signals directly to the child
in case it has started its own process group (like a cascaded
timeout command would for example).
* test/misc/timeout-group: Add a test case.
* NEWS: Mention the fix.
This commit is contained in:
Pádraig Brady 2011-07-08 13:31:05 +01:00
parent 4496c94091
commit 4d90d29899
3 changed files with 35 additions and 6 deletions

3
NEWS
View File

@ -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,

View File

@ -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);

View File

@ -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