aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sched.h4
-rw-r--r--kernel/exit.c9
-rw-r--r--kernel/signal.c17
3 files changed, 17 insertions, 13 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 87f7ca7ed6f6..0df7231d9ee0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -2145,7 +2145,7 @@ static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, s
2145 spin_unlock_irqrestore(&tsk->sighand->siglock, flags); 2145 spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
2146 2146
2147 return ret; 2147 return ret;
2148} 2148}
2149 2149
2150extern void block_all_signals(int (*notifier)(void *priv), void *priv, 2150extern void block_all_signals(int (*notifier)(void *priv), void *priv,
2151 sigset_t *mask); 2151 sigset_t *mask);
@@ -2160,7 +2160,7 @@ extern int kill_pid_info_as_uid(int, struct siginfo *, struct pid *, uid_t, uid_
2160extern int kill_pgrp(struct pid *pid, int sig, int priv); 2160extern int kill_pgrp(struct pid *pid, int sig, int priv);
2161extern int kill_pid(struct pid *pid, int sig, int priv); 2161extern int kill_pid(struct pid *pid, int sig, int priv);
2162extern int kill_proc_info(int, struct siginfo *, pid_t); 2162extern int kill_proc_info(int, struct siginfo *, pid_t);
2163extern int do_notify_parent(struct task_struct *, int); 2163extern bool do_notify_parent(struct task_struct *, int);
2164extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent); 2164extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent);
2165extern void force_sig(int, struct task_struct *); 2165extern void force_sig(int, struct task_struct *);
2166extern int send_sig(int, struct task_struct *, int); 2166extern int send_sig(int, struct task_struct *, int);
diff --git a/kernel/exit.c b/kernel/exit.c
index d49134a7f250..34d135f4fccc 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -820,6 +820,7 @@ static void forget_original_parent(struct task_struct *father)
820static void exit_notify(struct task_struct *tsk, int group_dead) 820static void exit_notify(struct task_struct *tsk, int group_dead)
821{ 821{
822 int signal; 822 int signal;
823 bool autoreap;
823 void *cookie; 824 void *cookie;
824 825
825 /* 826 /*
@@ -858,9 +859,11 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
858 859
859 signal = tracehook_notify_death(tsk, &cookie, group_dead); 860 signal = tracehook_notify_death(tsk, &cookie, group_dead);
860 if (signal >= 0) 861 if (signal >= 0)
861 signal = do_notify_parent(tsk, signal); 862 autoreap = do_notify_parent(tsk, signal);
863 else
864 autoreap = (signal == DEATH_REAP);
862 865
863 tsk->exit_state = signal == DEATH_REAP ? EXIT_DEAD : EXIT_ZOMBIE; 866 tsk->exit_state = autoreap ? EXIT_DEAD : EXIT_ZOMBIE;
864 867
865 /* mt-exec, de_thread() is waiting for group leader */ 868 /* mt-exec, de_thread() is waiting for group leader */
866 if (unlikely(tsk->signal->notify_count < 0)) 869 if (unlikely(tsk->signal->notify_count < 0))
@@ -868,7 +871,7 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
868 write_unlock_irq(&tasklist_lock); 871 write_unlock_irq(&tasklist_lock);
869 872
870 /* If the process is dead, release it - nobody will wait for it */ 873 /* If the process is dead, release it - nobody will wait for it */
871 if (signal == DEATH_REAP) 874 if (autoreap)
872 release_task(tsk); 875 release_task(tsk);
873} 876}
874 877
diff --git a/kernel/signal.c b/kernel/signal.c
index 1550aee34f42..d52e82cd62bb 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1577,15 +1577,15 @@ ret:
1577 * Let a parent know about the death of a child. 1577 * Let a parent know about the death of a child.
1578 * For a stopped/continued status change, use do_notify_parent_cldstop instead. 1578 * For a stopped/continued status change, use do_notify_parent_cldstop instead.
1579 * 1579 *
1580 * Returns -1 if our parent ignored us and so we've switched to 1580 * Returns true if our parent ignored us and so we've switched to
1581 * self-reaping, or else @sig. 1581 * self-reaping.
1582 */ 1582 */
1583int do_notify_parent(struct task_struct *tsk, int sig) 1583bool do_notify_parent(struct task_struct *tsk, int sig)
1584{ 1584{
1585 struct siginfo info; 1585 struct siginfo info;
1586 unsigned long flags; 1586 unsigned long flags;
1587 struct sighand_struct *psig; 1587 struct sighand_struct *psig;
1588 int ret = sig; 1588 bool autoreap = false;
1589 1589
1590 BUG_ON(sig == -1); 1590 BUG_ON(sig == -1);
1591 1591
@@ -1649,16 +1649,17 @@ int do_notify_parent(struct task_struct *tsk, int sig)
1649 * is implementation-defined: we do (if you don't want 1649 * is implementation-defined: we do (if you don't want
1650 * it, just use SIG_IGN instead). 1650 * it, just use SIG_IGN instead).
1651 */ 1651 */
1652 ret = tsk->exit_signal = -1; 1652 autoreap = true;
1653 tsk->exit_signal = -1;
1653 if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) 1654 if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
1654 sig = -1; 1655 sig = 0;
1655 } 1656 }
1656 if (valid_signal(sig) && sig > 0) 1657 if (valid_signal(sig) && sig)
1657 __group_send_sig_info(sig, &info, tsk->parent); 1658 __group_send_sig_info(sig, &info, tsk->parent);
1658 __wake_up_parent(tsk, tsk->parent); 1659 __wake_up_parent(tsk, tsk->parent);
1659 spin_unlock_irqrestore(&psig->siglock, flags); 1660 spin_unlock_irqrestore(&psig->siglock, flags);
1660 1661
1661 return ret; 1662 return autoreap;
1662} 1663}
1663 1664
1664/** 1665/**