aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/exit.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 85917c2bf065..46cf6b681460 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -597,14 +597,6 @@ choose_new_parent(struct task_struct *p, struct task_struct *reaper)
597static void 597static void
598reparent_thread(struct task_struct *p, struct task_struct *father, int traced) 598reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
599{ 599{
600 /* We don't want people slaying init. */
601 if (p->exit_signal != -1)
602 p->exit_signal = SIGCHLD;
603
604 if (p->pdeath_signal)
605 /* We already hold the tasklist_lock here. */
606 group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
607
608 /* Move the child from its dying parent to the new one. */ 600 /* Move the child from its dying parent to the new one. */
609 if (unlikely(traced)) { 601 if (unlikely(traced)) {
610 /* Preserve ptrace links if someone else is tracing this child. */ 602 /* Preserve ptrace links if someone else is tracing this child. */
@@ -620,13 +612,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
620 p->parent = p->real_parent; 612 p->parent = p->real_parent;
621 add_parent(p); 613 add_parent(p);
622 614
623 /* If we'd notified the old parent about this child's death, 615 if (p->state == TASK_TRACED) {
624 * also notify the new parent.
625 */
626 if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
627 thread_group_empty(p))
628 do_notify_parent(p, p->exit_signal);
629 else if (p->state == TASK_TRACED) {
630 /* 616 /*
631 * If it was at a trace stop, turn it into 617 * If it was at a trace stop, turn it into
632 * a normal stop since it's no longer being 618 * a normal stop since it's no longer being
@@ -636,6 +622,27 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
636 } 622 }
637 } 623 }
638 624
625 /* If this is a threaded reparent there is no need to
626 * notify anyone anything has happened.
627 */
628 if (p->real_parent->group_leader == father->group_leader)
629 return;
630
631 /* We don't want people slaying init. */
632 if (p->exit_signal != -1)
633 p->exit_signal = SIGCHLD;
634
635 if (p->pdeath_signal)
636 /* We already hold the tasklist_lock here. */
637 group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p);
638
639 /* If we'd notified the old parent about this child's death,
640 * also notify the new parent.
641 */
642 if (!traced && p->exit_state == EXIT_ZOMBIE &&
643 p->exit_signal != -1 && thread_group_empty(p))
644 do_notify_parent(p, p->exit_signal);
645
639 /* 646 /*
640 * process group orphan check 647 * process group orphan check
641 * Case ii: Our child is in a different pgrp 648 * Case ii: Our child is in a different pgrp