aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-03-23 05:36:59 -0400
committerTejun Heo <tj@kernel.org>2011-03-23 05:36:59 -0400
commitc672af35d54992b88d3c48133bd62cc3386fb2f9 (patch)
tree32232508b7f736d066a4b4e2acfbb9812f9b383f /kernel/signal.c
parent6447f55da90b77faec1697d499ed7986bb4f6de6 (diff)
signal: Fix SIGCONT notification code
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>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 31751868de88..e26274abf3a9 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1853,8 +1853,13 @@ relock:
1853 * the CLD_ si_code into SIGNAL_CLD_MASK bits. 1853 * the CLD_ si_code into SIGNAL_CLD_MASK bits.
1854 */ 1854 */
1855 if (unlikely(signal->flags & SIGNAL_CLD_MASK)) { 1855 if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
1856 int why = (signal->flags & SIGNAL_STOP_CONTINUED) 1856 int why;
1857 ? CLD_CONTINUED : CLD_STOPPED; 1857
1858 if (signal->flags & SIGNAL_CLD_CONTINUED)
1859 why = CLD_CONTINUED;
1860 else
1861 why = CLD_STOPPED;
1862
1858 signal->flags &= ~SIGNAL_CLD_MASK; 1863 signal->flags &= ~SIGNAL_CLD_MASK;
1859 1864
1860 why = tracehook_notify_jctl(why, CLD_CONTINUED); 1865 why = tracehook_notify_jctl(why, CLD_CONTINUED);