>From 60f225e8806707bc899c53732d2796cdfd1d9b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Mon, 27 Jun 2011 19:33:16 +0100 Subject: [PATCH] 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: Add a test case. * NEWS: Mention the fix. Reported by Shay Shimony --- NEWS | 3 +++ src/timeout.c | 10 +++++++++- tests/misc/timeout | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletions(-) diff --git a/NEWS b/NEWS index 619fbdd..e18a6ec 100644 --- a/NEWS +++ b/NEWS @@ -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 a686225..3877fae 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -108,9 +108,17 @@ cleanup (int sig) alarm (kill_after); kill_after = 0; /* Don't let later signals reset kill alarm. */ } + /* Send the signal directly to the monitored child, + in case it has itself become group leader. */ + 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. */ send_sig (0, sig); if (sig != SIGKILL && sig != SIGCONT) - send_sig (0, SIGCONT); + { + send_sig (monitored_pid, SIGCONT); + 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 b/tests/misc/timeout index 7506e7c..080436c 100755 --- a/tests/misc/timeout +++ b/tests/misc/timeout @@ -51,4 +51,21 @@ test $? = 124 && fail=1 exec timeout 10 true ) || fail=1 +cat <<\EOF > sleep_usr1 +#!/bin/sh +trap 'echo USR1; exit' USR1 +sleep $1& +wait +EOF +chmod a+x sleep_usr1 + +# Ensure the first timeout kills the processes, +# which was not the case 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 1 timeout -sUSR1 10 ./sleep_usr1 5 > out +echo USR1 > exp +compare out exp || fail=1 + Exit $fail -- 1.7.5.2