diff options
author | jhb <jhb@FreeBSD.org> | 2001-03-07 02:17:43 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-03-07 02:17:43 +0000 |
commit | e2c9c435ffe8047a6d98aa3ad6a1c783ecedc9e9 (patch) | |
tree | f04fb43ffa9013834deedf5483807a7e925e6c79 /sys/compat/svr4/svr4_misc.c | |
parent | 6958204c78a2f8d8aeda75daa86f9a6502384a16 (diff) | |
download | FreeBSD-src-e2c9c435ffe8047a6d98aa3ad6a1c783ecedc9e9.zip FreeBSD-src-e2c9c435ffe8047a6d98aa3ad6a1c783ecedc9e9.tar.gz |
- Hold both an exclusive proctree lock and the proc lock when reparenting
a traced process during exit.
- Lock the parent process while sending it SIGCHLD.
Diffstat (limited to 'sys/compat/svr4/svr4_misc.c')
-rw-r--r-- | sys/compat/svr4/svr4_misc.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 3d40681..d6091d8 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1252,26 +1252,27 @@ loop: * parent a SIGCHLD. The rest of the cleanup will be * done when the old parent waits on the child. */ + PROCTREE_LOCK(PT_EXCLUSIVE); PROC_LOCK(q); if (q->p_flag & P_TRACED) { - PROC_UNLOCK(q); - PROCTREE_LOCK(PT_EXCLUSIVE); if (q->p_oppid != q->p_pptr->p_pid) { + PROC_UNLOCK(q); t = pfind(q->p_oppid); - proc_reparent(q, t ? t : initproc); - PROCTREE_LOCK(PT_RELEASE); PROC_LOCK(q); - q->p_oppid = 0; + proc_reparent(q, t ? t : initproc); + q->p_oppid = 0; q->p_flag &= ~(P_TRACED | P_WAITED); PROC_UNLOCK(q); - PROCTREE_LOCK(PT_SHARED); - wakeup((caddr_t)q->p_pptr); + PROC_LOCK(t); + psignal(t, SIGCHLD); + PROC_UNLOCK(t); PROCTREE_LOCK(PT_RELEASE); + wakeup(t); return 0; } - PROCTREE_LOCK(PT_RELEASE); - } else - PROC_UNLOCK(q); + } + PROC_UNLOCK(q); + PROCTREE_LOCK(PT_RELEASE); q->p_xstat = 0; ruadd(&p->p_stats->p_cru, q->p_ru); FREE(q->p_ru, M_ZOMBIE); |