aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index ae0f2c4e452b..d3ad54677f9c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -52,6 +52,11 @@
52 52
53static void exit_mm(struct task_struct * tsk); 53static void exit_mm(struct task_struct * tsk);
54 54
55static inline int task_detached(struct task_struct *p)
56{
57 return p->exit_signal == -1;
58}
59
55static void __unhash_process(struct task_struct *p) 60static void __unhash_process(struct task_struct *p)
56{ 61{
57 nr_threads--; 62 nr_threads--;
@@ -160,7 +165,7 @@ repeat:
160 zap_leader = 0; 165 zap_leader = 0;
161 leader = p->group_leader; 166 leader = p->group_leader;
162 if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { 167 if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) {
163 BUG_ON(leader->exit_signal == -1); 168 BUG_ON(task_detached(leader));
164 do_notify_parent(leader, leader->exit_signal); 169 do_notify_parent(leader, leader->exit_signal);
165 /* 170 /*
166 * If we were the last child thread and the leader has 171 * If we were the last child thread and the leader has
@@ -170,7 +175,7 @@ repeat:
170 * do_notify_parent() will have marked it self-reaping in 175 * do_notify_parent() will have marked it self-reaping in
171 * that case. 176 * that case.
172 */ 177 */
173 zap_leader = (leader->exit_signal == -1); 178 zap_leader = task_detached(leader);
174 } 179 }
175 180
176 write_unlock_irq(&tasklist_lock); 181 write_unlock_irq(&tasklist_lock);
@@ -329,13 +334,11 @@ void __set_special_pids(struct pid *pid)
329 pid_t nr = pid_nr(pid); 334 pid_t nr = pid_nr(pid);
330 335
331 if (task_session(curr) != pid) { 336 if (task_session(curr) != pid) {
332 detach_pid(curr, PIDTYPE_SID); 337 change_pid(curr, PIDTYPE_SID, pid);
333 attach_pid(curr, PIDTYPE_SID, pid);
334 set_task_session(curr, nr); 338 set_task_session(curr, nr);
335 } 339 }
336 if (task_pgrp(curr) != pid) { 340 if (task_pgrp(curr) != pid) {
337 detach_pid(curr, PIDTYPE_PGID); 341 change_pid(curr, PIDTYPE_PGID, pid);
338 attach_pid(curr, PIDTYPE_PGID, pid);
339 set_task_pgrp(curr, nr); 342 set_task_pgrp(curr, nr);
340 } 343 }
341} 344}
@@ -693,7 +696,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
693 if (unlikely(traced)) { 696 if (unlikely(traced)) {
694 /* Preserve ptrace links if someone else is tracing this child. */ 697 /* Preserve ptrace links if someone else is tracing this child. */
695 list_del_init(&p->ptrace_list); 698 list_del_init(&p->ptrace_list);
696 if (p->parent != p->real_parent) 699 if (ptrace_reparented(p))
697 list_add(&p->ptrace_list, &p->real_parent->ptrace_children); 700 list_add(&p->ptrace_list, &p->real_parent->ptrace_children);
698 } else { 701 } else {
699 /* If this child is being traced, then we're the one tracing it 702 /* If this child is being traced, then we're the one tracing it
@@ -717,18 +720,18 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
717 /* If this is a threaded reparent there is no need to 720 /* If this is a threaded reparent there is no need to
718 * notify anyone anything has happened. 721 * notify anyone anything has happened.
719 */ 722 */
720 if (p->real_parent->group_leader == father->group_leader) 723 if (same_thread_group(p->real_parent, father))
721 return; 724 return;
722 725
723 /* We don't want people slaying init. */ 726 /* We don't want people slaying init. */
724 if (p->exit_signal != -1) 727 if (!task_detached(p))
725 p->exit_signal = SIGCHLD; 728 p->exit_signal = SIGCHLD;
726 729
727 /* If we'd notified the old parent about this child's death, 730 /* If we'd notified the old parent about this child's death,
728 * also notify the new parent. 731 * also notify the new parent.
729 */ 732 */
730 if (!traced && p->exit_state == EXIT_ZOMBIE && 733 if (!traced && p->exit_state == EXIT_ZOMBIE &&
731 p->exit_signal != -1 && thread_group_empty(p)) 734 !task_detached(p) && thread_group_empty(p))
732 do_notify_parent(p, p->exit_signal); 735 do_notify_parent(p, p->exit_signal);
733 736
734 kill_orphaned_pgrp(p, father); 737 kill_orphaned_pgrp(p, father);
@@ -781,18 +784,18 @@ static void forget_original_parent(struct task_struct *father)
781 } else { 784 } else {
782 /* reparent ptraced task to its real parent */ 785 /* reparent ptraced task to its real parent */
783 __ptrace_unlink (p); 786 __ptrace_unlink (p);
784 if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 && 787 if (p->exit_state == EXIT_ZOMBIE && !task_detached(p) &&
785 thread_group_empty(p)) 788 thread_group_empty(p))
786 do_notify_parent(p, p->exit_signal); 789 do_notify_parent(p, p->exit_signal);
787 } 790 }
788 791
789 /* 792 /*
790 * if the ptraced child is a zombie with exit_signal == -1 793 * if the ptraced child is a detached zombie we must collect
791 * we must collect it before we exit, or it will remain 794 * it before we exit, or it will remain zombie forever since
792 * zombie forever since we prevented it from self-reap itself 795 * we prevented it from self-reap itself while it was being
793 * while it was being traced by us, to be able to see it in wait4. 796 * traced by us, to be able to see it in wait4.
794 */ 797 */
795 if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) 798 if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && task_detached(p)))
796 list_add(&p->ptrace_list, &ptrace_dead); 799 list_add(&p->ptrace_list, &ptrace_dead);
797 } 800 }
798 801
@@ -849,29 +852,30 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
849 * we have changed execution domain as these two values started 852 * we have changed execution domain as these two values started
850 * the same after a fork. 853 * the same after a fork.
851 */ 854 */
852 if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 && 855 if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&
853 (tsk->parent_exec_id != tsk->real_parent->self_exec_id || 856 (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
854 tsk->self_exec_id != tsk->parent_exec_id) 857 tsk->self_exec_id != tsk->parent_exec_id) &&
855 && !capable(CAP_KILL)) 858 !capable(CAP_KILL))
856 tsk->exit_signal = SIGCHLD; 859 tsk->exit_signal = SIGCHLD;
857 860
858
859 /* If something other than our normal parent is ptracing us, then 861 /* If something other than our normal parent is ptracing us, then
860 * send it a SIGCHLD instead of honoring exit_signal. exit_signal 862 * send it a SIGCHLD instead of honoring exit_signal. exit_signal
861 * only has special meaning to our real parent. 863 * only has special meaning to our real parent.
862 */ 864 */
863 if (tsk->exit_signal != -1 && thread_group_empty(tsk)) { 865 if (!task_detached(tsk) && thread_group_empty(tsk)) {
864 int signal = tsk->parent == tsk->real_parent ? tsk->exit_signal : SIGCHLD; 866 int signal = ptrace_reparented(tsk) ?
867 SIGCHLD : tsk->exit_signal;
865 do_notify_parent(tsk, signal); 868 do_notify_parent(tsk, signal);
866 } else if (tsk->ptrace) { 869 } else if (tsk->ptrace) {
867 do_notify_parent(tsk, SIGCHLD); 870 do_notify_parent(tsk, SIGCHLD);
868 } 871 }
869 872
870 state = EXIT_ZOMBIE; 873 state = EXIT_ZOMBIE;
871 if (tsk->exit_signal == -1 && likely(!tsk->ptrace)) 874 if (task_detached(tsk) && likely(!tsk->ptrace))
872 state = EXIT_DEAD; 875 state = EXIT_DEAD;
873 tsk->exit_state = state; 876 tsk->exit_state = state;
874 877
878 /* mt-exec, de_thread() is waiting for us */
875 if (thread_group_leader(tsk) && 879 if (thread_group_leader(tsk) &&
876 tsk->signal->notify_count < 0 && 880 tsk->signal->notify_count < 0 &&
877 tsk->signal->group_exit_task) 881 tsk->signal->group_exit_task)
@@ -1115,12 +1119,13 @@ asmlinkage long sys_exit(int error_code)
1115NORET_TYPE void 1119NORET_TYPE void
1116do_group_exit(int exit_code) 1120do_group_exit(int exit_code)
1117{ 1121{
1122 struct signal_struct *sig = current->signal;
1123
1118 BUG_ON(exit_code & 0x80); /* core dumps don't get here */ 1124 BUG_ON(exit_code & 0x80); /* core dumps don't get here */
1119 1125
1120 if (current->signal->flags & SIGNAL_GROUP_EXIT) 1126 if (signal_group_exit(sig))
1121 exit_code = current->signal->group_exit_code; 1127 exit_code = sig->group_exit_code;
1122 else if (!thread_group_empty(current)) { 1128 else if (!thread_group_empty(current)) {
1123 struct signal_struct *const sig = current->signal;
1124 struct sighand_struct *const sighand = current->sighand; 1129 struct sighand_struct *const sighand = current->sighand;
1125 spin_lock_irq(&sighand->siglock); 1130 spin_lock_irq(&sighand->siglock);
1126 if (signal_group_exit(sig)) 1131 if (signal_group_exit(sig))
@@ -1172,7 +1177,7 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options,
1172 * Do not consider detached threads that are 1177 * Do not consider detached threads that are
1173 * not ptraced: 1178 * not ptraced:
1174 */ 1179 */
1175 if (p->exit_signal == -1 && !p->ptrace) 1180 if (task_detached(p) && !p->ptrace)
1176 return 0; 1181 return 0;
1177 1182
1178 /* Wait for all children (clone and not) if __WALL is set; 1183 /* Wait for all children (clone and not) if __WALL is set;
@@ -1262,8 +1267,7 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
1262 return 0; 1267 return 0;
1263 } 1268 }
1264 1269
1265 /* traced means p->ptrace, but not vice versa */ 1270 traced = ptrace_reparented(p);
1266 traced = (p->real_parent != p->parent);
1267 1271
1268 if (likely(!traced)) { 1272 if (likely(!traced)) {
1269 struct signal_struct *psig; 1273 struct signal_struct *psig;
@@ -1364,9 +1368,9 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
1364 * If it's still not detached after that, don't release 1368 * If it's still not detached after that, don't release
1365 * it now. 1369 * it now.
1366 */ 1370 */
1367 if (p->exit_signal != -1) { 1371 if (!task_detached(p)) {
1368 do_notify_parent(p, p->exit_signal); 1372 do_notify_parent(p, p->exit_signal);
1369 if (p->exit_signal != -1) { 1373 if (!task_detached(p)) {
1370 p->exit_state = EXIT_ZOMBIE; 1374 p->exit_state = EXIT_ZOMBIE;
1371 p = NULL; 1375 p = NULL;
1372 } 1376 }