summaryrefslogtreecommitdiffstats
path: root/sys/compat/svr4/svr4_misc.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-03-07 02:17:43 +0000
committerjhb <jhb@FreeBSD.org>2001-03-07 02:17:43 +0000
commite2c9c435ffe8047a6d98aa3ad6a1c783ecedc9e9 (patch)
treef04fb43ffa9013834deedf5483807a7e925e6c79 /sys/compat/svr4/svr4_misc.c
parent6958204c78a2f8d8aeda75daa86f9a6502384a16 (diff)
downloadFreeBSD-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.c21
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);
OpenPOWER on IntegriCloud