diff options
author | Pádraig Brady <P@draigBrady.com> | 2011-09-21 15:22:52 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2011-09-22 12:01:05 +0100 |
commit | 80a1aca0d2fad9d151a66ae5e612b96172bd5cbe (patch) | |
tree | 410568c66715f29e426002ac162d08118e74ac44 /src | |
parent | a4fa14849a7e310d135732142df2439f8f820483 (diff) | |
download | coreutils-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.c | 20 |
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. */ |