summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2011-06-14 17:09:30 +0000
committerobrien <obrien@FreeBSD.org>2011-06-14 17:09:30 +0000
commitf797e31a8d7ffc81bda219abef89c378821566db (patch)
treeec2169de1ebd2afc08af998e233233161d6de798 /sys/kern/kern_exit.c
parent0b41fa9638f2db7aece9c1ee748bf6b0e621df18 (diff)
downloadFreeBSD-src-f797e31a8d7ffc81bda219abef89c378821566db.zip
FreeBSD-src-f797e31a8d7ffc81bda219abef89c378821566db.tar.gz
We should not return ECHILD when debugging a child and the parent does a
"wait4(-1, ..., WNOHANG, ...)". Instead wait(2) should behave as if the child does not wish to report status at this time. Reviewed by: jhb
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 6510e13..bb25d17 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -701,8 +701,9 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options,
*/
if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) {
PROC_LOCK(p);
- p->p_oppid = 0;
proc_reparent(p, t);
+ p->p_pptr->p_dbg_child--;
+ p->p_oppid = 0;
PROC_UNLOCK(p);
pksignal(t, SIGCHLD, p->p_ksi);
wakeup(t);
@@ -794,7 +795,8 @@ kern_wait(struct thread *td, pid_t pid, int *status, int options,
pid = -q->p_pgid;
PROC_UNLOCK(q);
}
- if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
+ /* If we don't know the option, just return. */
+ if (options & ~(WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
return (EINVAL);
loop:
if (q->p_flag & P_STATCHILD) {
@@ -873,7 +875,10 @@ loop:
}
if (nfound == 0) {
sx_xunlock(&proctree_lock);
- return (ECHILD);
+ if (td->td_proc->p_dbg_child)
+ return (0);
+ else
+ return (ECHILD);
}
if (options & WNOHANG) {
sx_xunlock(&proctree_lock);
OpenPOWER on IntegriCloud