diff options
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r-- | sys/kern/kern_fork.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 07b8b1bc2c7..b92ea4a2cdb 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.121 2010/07/23 14:19:02 miod Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.122 2010/07/26 01:56:27 guenther Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -158,12 +158,16 @@ process_new(struct proc *newproc, struct proc *parentproc) pr = pool_get(&process_pool, PR_WAITOK); pr->ps_mainproc = newproc; + parent = parentproc->p_p; + TAILQ_INIT(&pr->ps_threads); TAILQ_INSERT_TAIL(&pr->ps_threads, newproc, p_thr_link); + LIST_INSERT_AFTER(parent, pr, ps_pglist); + pr->ps_pptr = parent; + LIST_INSERT_HEAD(&parent->ps_children, pr, ps_sibling); + LIST_INIT(&pr->ps_children); pr->ps_refcnt = 1; - parent = parentproc->p_p; - /* * Make a process structure for the new process. * Start by zeroing the section of proc that is zero-initialized, @@ -180,6 +184,10 @@ process_new(struct proc *newproc, struct proc *parentproc) crhold(parent->ps_cred->pc_ucred); pr->ps_limit->p_refcnt++; + if (parent->ps_session->s_ttyvp != NULL && + parent->ps_flags & PS_CONTROLT) + atomic_setbits_int(&pr->ps_flags, PS_CONTROLT); + newproc->p_p = pr; } @@ -311,14 +319,10 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, else p2->p_fd = fdcopy(p1); - if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT) - atomic_setbits_int(&p2->p_flag, P_CONTROLT); if (flags & FORK_PPWAIT) atomic_setbits_int(&p2->p_flag, P_PPWAIT); - p2->p_pptr = p1; if (flags & FORK_NOZOMBIE) atomic_setbits_int(&p2->p_flag, P_NOZOMBIE); - LIST_INIT(&p2->p_children); #ifdef KTRACE /* @@ -396,12 +400,12 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, LIST_INSERT_HEAD(&allproc, p2, p_list); LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); - LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling); - LIST_INSERT_AFTER(p1, p2, p_pglist); + if (p2->p_flag & P_TRACED) { p2->p_oppid = p1->p_pid; - if (p2->p_pptr != p1->p_pptr) - proc_reparent(p2, p1->p_pptr); + if ((flags & FORK_THREAD) == 0 && + p2->p_p->ps_pptr != p1->p_p->ps_pptr) + proc_reparent(p2->p_p, p1->p_p->ps_pptr); /* * Set ptrace status. @@ -459,11 +463,11 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize, /* * Preserve synchronization semantics of vfork. If waiting for * child to exec or exit, set P_PPWAIT on child, and sleep on our - * proc (in case of exit). + * process (in case of exit). */ if (flags & FORK_PPWAIT) while (p2->p_flag & P_PPWAIT) - tsleep(p1, PWAIT, "ppwait", 0); + tsleep(p1->p_p, PWAIT, "ppwait", 0); /* * If we're tracing the child, alert the parent too. @@ -494,9 +498,10 @@ pidtaken(pid_t pid) return (1); if (pgfind(pid) != NULL) return (1); - LIST_FOREACH(p, &zombproc, p_list) - if (p->p_pid == pid || (p->p_pgrp && p->p_pgrp->pg_id == pid)) + LIST_FOREACH(p, &zombproc, p_list) { + if (p->p_pid == pid || (p->p_p->ps_pgrp && p->p_p->ps_pgrp->pg_id == pid)) return (1); + } return (0); } |