return 0;
err = security_task_wait(p);
- if (err)
- return err;
+ if (likely(!err))
+ return 1;
- return 1;
+ if (pid <= 0)
+ return 0;
+ /* This child was explicitly requested, abort */
+ read_unlock(&tasklist_lock);
+ return err;
}
static int wait_noreap_copyout(struct task_struct *p, pid_t pid, uid_t uid,
DECLARE_WAITQUEUE(wait, current);
struct task_struct *tsk;
int flag, retval;
- int allowed, denied;
add_wait_queue(¤t->signal->wait_chldexit,&wait);
repeat:
* We will set this flag if we see any child that might later
* match our criteria, even if we are not able to reap it yet.
*/
- flag = 0;
- allowed = denied = 0;
+ flag = retval = 0;
current->state = TASK_INTERRUPTIBLE;
read_lock(&tasklist_lock);
tsk = current;
continue;
if (unlikely(ret < 0)) {
- denied = ret;
- continue;
- }
- allowed = 1;
-
- retval = 0;
- if (task_is_stopped_or_traced(p)) {
+ retval = ret;
+ } else if (task_is_stopped_or_traced(p)) {
/*
* It's stopped now, so it might later
* continue, exit, or stop again.
}
if (!flag) {
list_for_each_entry(p, &tsk->ptrace_children,
- ptrace_list) {
- if (!eligible_child(pid, options, p))
+ ptrace_list) {
+ flag = eligible_child(pid, options, p);
+ if (!flag)
continue;
- flag = 1;
- break;
+ if (likely(flag > 0))
+ break;
+ retval = flag;
+ goto end;
}
}
if (options & __WNOTHREAD)
tsk = next_thread(tsk);
BUG_ON(tsk->signal != current->signal);
} while (tsk != current);
-
read_unlock(&tasklist_lock);
+
if (flag) {
- retval = 0;
if (options & WNOHANG)
goto end;
retval = -ERESTARTSYS;
goto repeat;
}
retval = -ECHILD;
- if (unlikely(denied) && !allowed)
- retval = denied;
end:
current->state = TASK_RUNNING;
remove_wait_queue(¤t->signal->wait_chldexit,&wait);