Skip to content

Commit

Permalink
signal: Fix SIGCONT notification code
Browse files Browse the repository at this point in the history
After a task receives SIGCONT, its parent is notified via SIGCHLD with
its siginfo describing what the notified event is.  If SIGCONT is
received while the child process is stopped, the code should be
CLD_CONTINUED.  If SIGCONT is recieved while the child process is in
the process of being stopped, it should be CLD_STOPPED.  Which code to
use is determined in prepare_signal() and recorded in signal->flags
using SIGNAL_CLD_CONTINUED|STOP flags.

get_signal_deliver() should test these flags and then notify
accoringly; however, it incorrectly tested SIGNAL_STOP_CONTINUED
instead of SIGNAL_CLD_CONTINUED, thus incorrectly notifying
CLD_CONTINUED if the signal is delivered before the task is wait(2)ed
and CLD_STOPPED if the state was fetched already.

Fix it by testing SIGNAL_CLD_CONTINUED.  While at it, uncompress the
?: test into if/else clause for better readability.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Roland McGrath <roland@redhat.com>
  • Loading branch information
Tejun Heo committed Mar 23, 2011
1 parent 6447f55 commit c672af3
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1853,8 +1853,13 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
* the CLD_ si_code into SIGNAL_CLD_MASK bits.
*/
if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
int why = (signal->flags & SIGNAL_STOP_CONTINUED)
? CLD_CONTINUED : CLD_STOPPED;
int why;

if (signal->flags & SIGNAL_CLD_CONTINUED)
why = CLD_CONTINUED;
else
why = CLD_STOPPED;

signal->flags &= ~SIGNAL_CLD_MASK;

why = tracehook_notify_jctl(why, CLD_CONTINUED);
Expand Down

0 comments on commit c672af3

Please sign in to comment.