Commit d839fd4d authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds

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: default avatarOleg Nesterov <oleg@tv-sign.ru>
Cc: Roland McGrath <roland@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5a8da0ea
...@@ -52,6 +52,11 @@ ...@@ -52,6 +52,11 @@
static void exit_mm(struct task_struct * tsk); static void exit_mm(struct task_struct * tsk);
static inline int task_detached(struct task_struct *p)
{
return p->exit_signal == -1;
}
static void __unhash_process(struct task_struct *p) static void __unhash_process(struct task_struct *p)
{ {
nr_threads--; nr_threads--;
...@@ -160,7 +165,7 @@ void release_task(struct task_struct * p) ...@@ -160,7 +165,7 @@ void release_task(struct task_struct * p)
zap_leader = 0; zap_leader = 0;
leader = p->group_leader; leader = p->group_leader;
if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) {
BUG_ON(leader->exit_signal == -1); BUG_ON(task_detached(leader));
do_notify_parent(leader, leader->exit_signal); do_notify_parent(leader, leader->exit_signal);
/* /*
* If we were the last child thread and the leader has * If we were the last child thread and the leader has
...@@ -170,7 +175,7 @@ void release_task(struct task_struct * p) ...@@ -170,7 +175,7 @@ void release_task(struct task_struct * p)
* do_notify_parent() will have marked it self-reaping in * do_notify_parent() will have marked it self-reaping in
* that case. * that case.
*/ */
zap_leader = (leader->exit_signal == -1); zap_leader = task_detached(leader);
} }
write_unlock_irq(&tasklist_lock); write_unlock_irq(&tasklist_lock);
...@@ -721,14 +726,14 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) ...@@ -721,14 +726,14 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
return; return;
/* We don't want people slaying init. */ /* We don't want people slaying init. */
if (p->exit_signal != -1) if (!task_detached(p))
p->exit_signal = SIGCHLD; p->exit_signal = SIGCHLD;
/* If we'd notified the old parent about this child's death, /* If we'd notified the old parent about this child's death,
* also notify the new parent. * also notify the new parent.
*/ */
if (!traced && p->exit_state == EXIT_ZOMBIE && if (!traced && p->exit_state == EXIT_ZOMBIE &&
p->exit_signal != -1 && thread_group_empty(p)) !task_detached(p) && thread_group_empty(p))
do_notify_parent(p, p->exit_signal); do_notify_parent(p, p->exit_signal);
kill_orphaned_pgrp(p, father); kill_orphaned_pgrp(p, father);
...@@ -781,18 +786,18 @@ static void forget_original_parent(struct task_struct *father) ...@@ -781,18 +786,18 @@ static void forget_original_parent(struct task_struct *father)
} else { } else {
/* reparent ptraced task to its real parent */ /* reparent ptraced task to its real parent */
__ptrace_unlink (p); __ptrace_unlink (p);
if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 && if (p->exit_state == EXIT_ZOMBIE && !task_detached(p) &&
thread_group_empty(p)) thread_group_empty(p))
do_notify_parent(p, p->exit_signal); do_notify_parent(p, p->exit_signal);
} }
/* /*
* if the ptraced child is a zombie with exit_signal == -1 * if the ptraced child is a detached zombie we must collect
* we must collect it before we exit, or it will remain * it before we exit, or it will remain zombie forever since
* zombie forever since we prevented it from self-reap itself * we prevented it from self-reap itself while it was being
* while it was being traced by us, to be able to see it in wait4. * traced by us, to be able to see it in wait4.
*/ */
if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && task_detached(p)))
list_add(&p->ptrace_list, &ptrace_dead); list_add(&p->ptrace_list, &ptrace_dead);
} }
...@@ -849,26 +854,26 @@ static void exit_notify(struct task_struct *tsk, int group_dead) ...@@ -849,26 +854,26 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
* we have changed execution domain as these two values started * we have changed execution domain as these two values started
* the same after a fork. * the same after a fork.
*/ */
if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 && if (tsk->exit_signal != SIGCHLD && !task_detached(tsk) &&
(tsk->parent_exec_id != tsk->real_parent->self_exec_id || (tsk->parent_exec_id != tsk->real_parent->self_exec_id ||
tsk->self_exec_id != tsk->parent_exec_id) tsk->self_exec_id != tsk->parent_exec_id) &&
&& !capable(CAP_KILL)) !capable(CAP_KILL))
tsk->exit_signal = SIGCHLD; tsk->exit_signal = SIGCHLD;
/* If something other than our normal parent is ptracing us, then /* If something other than our normal parent is ptracing us, then
* send it a SIGCHLD instead of honoring exit_signal. exit_signal * send it a SIGCHLD instead of honoring exit_signal. exit_signal
* only has special meaning to our real parent. * only has special meaning to our real parent.
*/ */
if (tsk->exit_signal != -1 && thread_group_empty(tsk)) { if (!task_detached(tsk) && thread_group_empty(tsk)) {
int signal = tsk->parent == tsk->real_parent ? tsk->exit_signal : SIGCHLD; int signal = (tsk->parent == tsk->real_parent)
? tsk->exit_signal : SIGCHLD;
do_notify_parent(tsk, signal); do_notify_parent(tsk, signal);
} else if (tsk->ptrace) { } else if (tsk->ptrace) {
do_notify_parent(tsk, SIGCHLD); do_notify_parent(tsk, SIGCHLD);
} }
state = EXIT_ZOMBIE; state = EXIT_ZOMBIE;
if (tsk->exit_signal == -1 && likely(!tsk->ptrace)) if (task_detached(tsk) && likely(!tsk->ptrace))
state = EXIT_DEAD; state = EXIT_DEAD;
tsk->exit_state = state; tsk->exit_state = state;
...@@ -1173,7 +1178,7 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options, ...@@ -1173,7 +1178,7 @@ static int eligible_child(enum pid_type type, struct pid *pid, int options,
* Do not consider detached threads that are * Do not consider detached threads that are
* not ptraced: * not ptraced:
*/ */
if (p->exit_signal == -1 && !p->ptrace) if (task_detached(p) && !p->ptrace)
return 0; return 0;
/* Wait for all children (clone and not) if __WALL is set; /* 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,9 +1370,9 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
* If it's still not detached after that, don't release * If it's still not detached after that, don't release
* it now. * it now.
*/ */
if (p->exit_signal != -1) { if (!task_detached(p)) {
do_notify_parent(p, p->exit_signal); do_notify_parent(p, p->exit_signal);
if (p->exit_signal != -1) { if (!task_detached(p)) {
p->exit_state = EXIT_ZOMBIE; p->exit_state = EXIT_ZOMBIE;
p = NULL; p = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment