diff options
author | dim <dim@FreeBSD.org> | 2010-12-09 22:01:15 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-12-09 22:01:15 +0000 |
commit | a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9 (patch) | |
tree | 5f0a24f71baa3176c75a20a51a9e20a22c75426c /sys/kern/kern_fork.c | |
parent | ad01c620333d05c430d583ee40647e396be1ab91 (diff) | |
parent | 12dd9eb8e940c48f9fc30dbc137071b4fe5caead (diff) | |
download | FreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.zip FreeBSD-src-a3786f65f1e2fa3a4e925fdb4b2b5544b9021bf9.tar.gz |
Sync: merge r216133 through r216338 from ^/head.
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r-- | sys/kern/kern_fork.c | 119 |
1 files changed, 60 insertions, 59 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 126c668..61d9531 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -97,9 +97,7 @@ struct fork_args { /* ARGSUSED */ int -fork(td, uap) - struct thread *td; - struct fork_args *uap; +fork(struct thread *td, struct fork_args *uap) { int error; struct proc *p2; @@ -135,9 +133,7 @@ vfork(td, uap) } int -rfork(td, uap) - struct thread *td; - struct rfork_args *uap; +rfork(struct thread *td, struct rfork_args *uap) { struct proc *p2; int error; @@ -197,12 +193,59 @@ sysctl_kern_randompid(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_kern_randompid, "I", "Random PID modulus"); +static int +fork_norfproc(struct thread *td, int flags, struct proc **procp) +{ + int error; + struct proc *p1; + + KASSERT((flags & RFPROC) == 0, + ("fork_norfproc called with RFPROC set")); + p1 = td->td_proc; + *procp = NULL; + + if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && + (flags & (RFCFDG | RFFDG))) { + PROC_LOCK(p1); + if (thread_single(SINGLE_BOUNDARY)) { + PROC_UNLOCK(p1); + return (ERESTART); + } + PROC_UNLOCK(p1); + } + + error = vm_forkproc(td, NULL, NULL, NULL, flags); + if (error) + goto fail; + + /* + * Close all file descriptors. + */ + if (flags & RFCFDG) { + struct filedesc *fdtmp; + fdtmp = fdinit(td->td_proc->p_fd); + fdfree(td); + p1->p_fd = fdtmp; + } + + /* + * Unshare file descriptors (from parent). + */ + if (flags & RFFDG) + fdunshare(p1, td); + +fail: + if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && + (flags & (RFCFDG | RFFDG))) { + PROC_LOCK(p1); + thread_single_end(); + PROC_UNLOCK(p1); + } + return (error); +} + int -fork1(td, flags, pages, procp) - struct thread *td; - int flags; - int pages; - struct proc **procp; +fork1(struct thread *td, int flags, int pages, struct proc **procp) { struct proc *p1, *p2, *pptr; struct proc *newproc; @@ -227,47 +270,8 @@ fork1(td, flags, pages, procp) * Here we don't create a new process, but we divorce * certain parts of a process from itself. */ - if ((flags & RFPROC) == 0) { - if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && - (flags & (RFCFDG | RFFDG))) { - PROC_LOCK(p1); - if (thread_single(SINGLE_BOUNDARY)) { - PROC_UNLOCK(p1); - return (ERESTART); - } - PROC_UNLOCK(p1); - } - - error = vm_forkproc(td, NULL, NULL, NULL, flags); - if (error) - goto norfproc_fail; - - /* - * Close all file descriptors. - */ - if (flags & RFCFDG) { - struct filedesc *fdtmp; - fdtmp = fdinit(td->td_proc->p_fd); - fdfree(td); - p1->p_fd = fdtmp; - } - - /* - * Unshare file descriptors (from parent). - */ - if (flags & RFFDG) - fdunshare(p1, td); - -norfproc_fail: - if (((p1->p_flag & (P_HADTHREADS|P_SYSTEM)) == P_HADTHREADS) && - (flags & (RFCFDG | RFFDG))) { - PROC_LOCK(p1); - thread_single_end(); - PROC_UNLOCK(p1); - } - *procp = NULL; - return (error); - } + if ((flags & RFPROC) == 0) + return (fork_norfproc(td, flags, procp)); /* * XXX @@ -539,6 +543,7 @@ again: td2->td_sigstk = td->td_sigstk; td2->td_sigmask = td->td_sigmask; td2->td_flags = TDF_INMEM; + td2->td_lend_user_pri = PRI_MAX; #ifdef VIMAGE td2->td_vnet = NULL; @@ -798,10 +803,8 @@ fail1: * is called from the MD fork_trampoline() entry point. */ void -fork_exit(callout, arg, frame) - void (*callout)(void *, struct trapframe *); - void *arg; - struct trapframe *frame; +fork_exit(void (*callout)(void *, struct trapframe *), void *arg, + struct trapframe *frame) { struct proc *p; struct thread *td; @@ -855,9 +858,7 @@ fork_exit(callout, arg, frame) * first parameter and is called when returning to a new userland process. */ void -fork_return(td, frame) - struct thread *td; - struct trapframe *frame; +fork_return(struct thread *td, struct trapframe *frame) { userret(td, frame); |