diff options
author | Oleg Nesterov <oleg@tv-sign.ru> | 2008-04-30 03:53:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:38 -0400 |
commit | d839fd4d2e95a5fbc4d50aa9d17eed6a5f2094e6 (patch) | |
tree | bfeccf3201208a9ce0e994cff9eacdc4647002a6 | |
parent | 5a8da0ea82db6fa9737041381079fd16f25dcce2 (diff) |
ptrace: introduce task_detached() helper
exit.c has numerous "->exit_signal == -1" comparisons, this check is subtle
and deserves a helper. Imho makes the code more parseable for humans. At
least it's surely more greppable.
Also, a couple of whitespace cleanups. No functional changes.
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/exit.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 6d019aa8522e..4035d391a0d3 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -52,6 +52,11 @@ | |||
52 | 52 | ||
53 | static void exit_mm(struct task_struct * tsk); | 53 | static void exit_mm(struct task_struct * tsk); |
54 | 54 | ||
55 | static inline int task_detached(struct task_struct *p) | ||
56 | { | ||
57 | return p->exit_signal == -1; | ||
58 | } | ||
59 | |||
55 | static void __unhash_process(struct task_struct *p) | 60 | static 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); |
@@ -721,14 +726,14 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) | |||
721 | return; | 726 | return; |
722 | 727 | ||
723 | /* We don't want people slaying init. */ | 728 | /* We don't want people slaying init. */ |
724 | if (p->exit_signal != -1) | 729 | if (!task_detached(p)) |
725 | p->exit_signal = SIGCHLD; | 730 | p->exit_signal = SIGCHLD; |
726 | 731 | ||
727 | /* If we'd notified the old parent about this child's death, | 732 | /* If we'd notified the old parent about this child's death, |
728 | * also notify the new parent. | 733 | * also notify the new parent. |
729 | */ | 734 | */ |
730 | if (!traced && p->exit_state == EXIT_ZOMBIE && | 735 | if (!traced && p->exit_state == EXIT_ZOMBIE && |
731 | p->exit_signal != -1 && thread_group_empty(p)) | 736 | !task_detached(p) && thread_group_empty(p)) |
732 | do_notify_parent(p, p->exit_signal); | 737 | do_notify_parent(p, p->exit_signal); |
733 | 738 | ||
734 | kill_orphaned_pgrp(p, father); | 739 | kill_orphaned_pgrp(p, father); |
@@ -781,18 +786,18 @@ static void forget_original_parent(struct task_struct *father) | |||
781 | } else { | 786 | } else { |
782 | /* reparent ptraced task to its real parent */ | 787 | /* reparent ptraced task to its real parent */ |
783 | __ptrace_unlink (p); | 788 | __ptrace_unlink (p); |
784 | if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 && | 789 | if (p->exit_state == EXIT_ZOMBIE && !task_detached(p) && |
785 | thread_group_empty(p)) | 790 | thread_group_empty(p)) |
786 | do_notify_parent(p, p->exit_signal); | 791 | do_notify_parent(p, p->exit_signal); |
787 | } | 792 | } |
788 | 793 | ||
789 | /* | 794 | /* |
790 | * if the ptraced child is a zombie with exit_signal == -1 | 795 | * if the ptraced child is a detached zombie we must collect |
791 | * we must collect it before we exit, or it will remain | 796 | * it before we exit, or it will remain zombie forever since |
792 | * zombie forever since we prevented it from self-reap itself | 797 | * 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. | 798 | * traced by us, to be able to see it in wait4. |
794 | */ | 799 | */ |
795 | if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) | 800 | if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && task_detached(p))) |
796 | list_add(&p->ptrace_list, &ptrace_dead); | 801 | list_add(&p->ptrace_list, &ptrace_dead); |
797 | } | 802 | } |
798 | 803 | ||
@@ -849,26 +854,26 @@ static void exit_notify(struct task_struct *tsk, int group_dead) | |||
849 | * we have changed execution domain as these two values started | 854 | * we have changed execution domain as these two values started |
850 | * the same after a fork. | 855 | * the same after a fork. |
851 | */ | 856 | */ |
852 | if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 && | 857 | if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) && |
853 | (tsk->parent_exec_id != tsk->real_parent->self_exec_id || | 858 | (tsk->parent_exec_id != tsk->real_parent->self_exec_id || |
854 | tsk->self_exec_id != tsk->parent_exec_id) | 859 | tsk->self_exec_id != tsk->parent_exec_id) && |
855 | && !capable(CAP_KILL)) | 860 | !capable(CAP_KILL)) |
856 | tsk->exit_signal = SIGCHLD; | 861 | tsk->exit_signal = SIGCHLD; |
857 | 862 | ||
858 | |||
859 | /* If something other than our normal parent is ptracing us, then | 863 | /* If something other than our normal parent is ptracing us, then |
860 | * send it a SIGCHLD instead of honoring exit_signal. exit_signal | 864 | * send it a SIGCHLD instead of honoring exit_signal. exit_signal |
861 | * only has special meaning to our real parent. | 865 | * only has special meaning to our real parent. |
862 | */ | 866 | */ |
863 | if (tsk->exit_signal != -1 && thread_group_empty(tsk)) { | 867 | if (!task_detached(tsk) && thread_group_empty(tsk)) { |
864 | int signal = tsk->parent == tsk->real_parent ? tsk->exit_signal : SIGCHLD; | 868 | int signal = (tsk->parent == tsk->real_parent) |
869 | ? tsk->exit_signal : SIGCHLD; | ||
865 | do_notify_parent(tsk, signal); | 870 | do_notify_parent(tsk, signal); |
866 | } else if (tsk->ptrace) { | 871 | } else if (tsk->ptrace) { |
867 | do_notify_parent(tsk, SIGCHLD); | 872 | do_notify_parent(tsk, SIGCHLD); |
868 | } | 873 | } |
869 | 874 | ||
870 | state = EXIT_ZOMBIE; | 875 | state = EXIT_ZOMBIE; |
871 | if (tsk->exit_signal == -1 && likely(!tsk->ptrace)) | 876 | if (task_detached(tsk) && likely(!tsk->ptrace)) |
872 | state = EXIT_DEAD; | 877 | state = EXIT_DEAD; |
873 | tsk->exit_state = state; | 878 | tsk->exit_state = state; |
874 | 879 | ||
@@ -1173,7 +1178,7 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options, | |||
1173 | * Do not consider detached threads that are | 1178 | * Do not consider detached threads that are |
1174 | * not ptraced: | 1179 | * not ptraced: |
1175 | */ | 1180 | */ |
1176 | if (p->exit_signal == -1 && !p->ptrace) | 1181 | if (task_detached(p) && !p->ptrace) |
1177 | return 0; | 1182 | return 0; |
1178 | 1183 | ||
1179 | /* Wait for all children (clone and not) if __WALL is set; | 1184 | /* Wait for all children (clone and not) if __WALL is set; |
@@ -1365,9 +1370,9 @@ static int wait_task_zombie(struct task_struct *p, int noreap, | |||
1365 | * If it's still not detached after that, don't release | 1370 | * If it's still not detached after that, don't release |
1366 | * it now. | 1371 | * it now. |
1367 | */ | 1372 | */ |
1368 | if (p->exit_signal != -1) { | 1373 | if (!task_detached(p)) { |
1369 | do_notify_parent(p, p->exit_signal); | 1374 | do_notify_parent(p, p->exit_signal); |
1370 | if (p->exit_signal != -1) { | 1375 | if (!task_detached(p)) { |
1371 | p->exit_state = EXIT_ZOMBIE; | 1376 | p->exit_state = EXIT_ZOMBIE; |
1372 | p = NULL; | 1377 | p = NULL; |
1373 | } | 1378 | } |