summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-09-21 15:22:52 +0100
committerPádraig Brady <P@draigBrady.com>2011-09-22 12:01:05 +0100
commit80a1aca0d2fad9d151a66ae5e612b96172bd5cbe (patch)
tree410568c66715f29e426002ac162d08118e74ac44 /src
parenta4fa14849a7e310d135732142df2439f8f820483 (diff)
downloadcoreutils-80a1aca0d2fad9d151a66ae5e612b96172bd5cbe.tar.xz
timeout: handle implicitly created threads
On some systems like glibc on GNU/kFreeBSD, a thread is implicitly created when timer_settime() is used. This breaks our scheme to ignore signals we've sent ourselves. * src/timeout.c (send_sig): Change the scheme used to ignore signals we've sent ourselves, to a more robust but perhaps limited scheme of ignoring all signals of a certain type after we've sent that signal to the job. * NEWS: Mention the change in behavior.
Diffstat (limited to 'src')
-rw-r--r--src/timeout.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/timeout.c b/src/timeout.c
index d734e4e81..59b937e7c 100644
--- a/src/timeout.c
+++ b/src/timeout.c
@@ -77,7 +77,6 @@
static int timed_out;
static int term_signal = SIGTERM; /* same default as kill command. */
static int monitored_pid;
-static int sigs_to_ignore[NSIG]; /* so monitor can ignore sigs it resends. */
static double kill_after;
static bool foreground; /* whether to use another program group. */
@@ -141,12 +140,20 @@ settimeout (double duration)
alarm (timeint);
}
-/* send sig to group but not ourselves.
- * FIXME: Is there a better way to achieve this? */
+/* send SIG avoiding the current process. */
+
static int
send_sig (int where, int sig)
{
- sigs_to_ignore[sig] = 1;
+ /* If sending to the group, then ignore the signal,
+ so we don't go into a signal loop. Note that this will ignore any of the
+ signals registered in install_signal_handlers(), that are sent after we
+ propagate the first one, which hopefully won't be an issue. Note this
+ process can be implicitly multithreaded due to some timer_settime()
+ implementations, therefore a signal sent to the group, can be sent
+ multiple times to this process. */
+ if (where == 0)
+ signal (sig, SIG_IGN);
return kill (where, sig);
}
@@ -160,11 +167,6 @@ cleanup (int sig)
}
if (monitored_pid)
{
- if (sigs_to_ignore[sig])
- {
- sigs_to_ignore[sig] = 0;
- return;
- }
if (kill_after)
{
/* Start a new timeout after which we'll send SIGKILL. */