Implement the RFNOWAIT flag for rfork(). If set this flag will cause the

forked child to be dissociated from the parent).

Cleanup fork1(), implement vfork() and fork() in terms of rfork() flags.

Remove RFENVG, RFNOTEG, RFCNAMEG, RFCENVG which are Plan9 specific and cannot
possibly be implemented in FreeBSD.

Renumbered the flags to make up for the removal of the above flags.

Reviewed by:	peter, smpatel
Submitted by:	Mike Grupenhoff <kashmir@umiacs.umd.edu>
This commit is contained in:
Sujal Patel 1996-04-17 17:05:08 +00:00
parent 4f789210dc
commit 0e3eb7ee6c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15277
2 changed files with 40 additions and 48 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $Id: kern_fork.c,v 1.18 1996/03/03 19:48:45 dyson Exp $
* $Id: kern_fork.c,v 1.2 1996/04/02 05:26:56 kashmir Exp $
*/
#include "opt_ktrace.h"
@ -62,11 +62,7 @@
#include <vm/vm_extern.h>
#include <vm/vm_inherit.h>
static int fork1(struct proc *p, int forktype, int rforkflags, int *retval);
#define ISFORK 0
#define ISVFORK 1
#define ISRFORK 2
static int fork1 __P((struct proc *p, int flags, int *retval));
#ifndef _SYS_SYSPROTO_H_
struct fork_args {
@ -81,7 +77,7 @@ fork(p, uap, retval)
struct fork_args *uap;
int retval[];
{
return (fork1(p, ISFORK, 0, retval));
return (fork1(p, (RFFDG|RFPROC), retval));
}
/* ARGSUSED */
@ -91,7 +87,7 @@ vfork(p, uap, retval)
struct vfork_args *uap;
int retval[];
{
return (fork1(p, ISVFORK, 0, retval));
return (fork1(p, (RFFDG|RFPROC|RFPPWAIT), retval));
}
/* ARGSUSED */
@ -101,40 +97,29 @@ rfork(p, uap, retval)
struct rfork_args *uap;
int retval[];
{
return (fork1(p, ISRFORK, uap->flags, retval));
return (fork1(p, uap->flags, retval));
}
int nprocs = 1; /* process 0 */
static int
fork1(p1, forktype, rforkflags, retval)
fork1(p1, flags, retval)
register struct proc *p1;
int forktype;
int rforkflags;
int flags;
int retval[];
{
register struct proc *p2;
register struct proc *p2, *pptr;
register uid_t uid;
struct proc *newproc;
struct proc **hash;
int count;
static int nextpid, pidchecked = 0;
int dupfd = 1, cleanfd = 0;
if (forktype == ISRFORK) {
dupfd = 0;
if ((rforkflags & RFPROC) == 0)
return (EINVAL);
if ((rforkflags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
return (EINVAL);
if (rforkflags & RFFDG)
dupfd = 1;
if (rforkflags & RFNOWAIT)
return (EINVAL); /* XXX unimplimented */
if (rforkflags & RFCFDG)
cleanfd = 1;
}
if ((flags & RFPROC) == 0)
return (EINVAL);
if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG))
return (EINVAL);
/*
* Although process entries are dynamically created, we still keep
@ -253,9 +238,9 @@ fork1(p1, forktype, rforkflags, retval)
if (p2->p_textvp)
VREF(p2->p_textvp);
if (cleanfd)
if (flags & RFCFDG)
p2->p_fd = fdinit(p1);
else if (dupfd)
else if (flags & RFFDG)
p2->p_fd = fdcopy(p1);
else
p2->p_fd = fdshare(p1);
@ -275,11 +260,23 @@ fork1(p1, forktype, rforkflags, retval)
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
p2->p_flag |= P_CONTROLT;
if (forktype == ISVFORK)
if (flags & RFPPWAIT)
p2->p_flag |= P_PPWAIT;
LIST_INSERT_AFTER(p1, p2, p_pglist);
p2->p_pptr = p1;
LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
/*
* Attach the new process to its parent.
*
* If RFNOWAIT is set, the newly created process becomes a child
* of init. This effectively disassociates the child from the
* parent.
*/
if (flags & RFNOWAIT)
pptr = initproc;
else
pptr = p1;
p2->p_pptr = pptr;
LIST_INSERT_HEAD(&pptr->p_children, p2, p_sibling);
LIST_INIT(&p2->p_children);
#ifdef KTRACE
@ -307,12 +304,12 @@ fork1(p1, forktype, rforkflags, retval)
/*
* share as much address space as possible
* XXX this should probably go in vm_fork()
*/
if (forktype == ISRFORK && (rforkflags & RFMEM)) {
if (flags & RFMEM)
(void) vm_map_inherit(&p1->p_vmspace->vm_map,
VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ,
VM_INHERIT_SHARE);
}
/*
* Set return values for child before vm_fork,
@ -352,9 +349,8 @@ fork1(p1, forktype, rforkflags, retval)
* child to exec or exit, set P_PPWAIT on child, and sleep on our
* proc (in case of exit).
*/
if (forktype == ISVFORK)
while (p2->p_flag & P_PPWAIT)
tsleep(p1, PWAIT, "ppwait", 0);
while (p2->p_flag & P_PPWAIT)
tsleep(p1, PWAIT, "ppwait", 0);
/*
* Return child pid to parent process,

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)unistd.h 8.2 (Berkeley) 1/7/94
* $Id: unistd.h,v 1.4 1995/05/11 07:52:49 bde Exp $
* $Id: unistd.h,v 1.2 1996/04/02 05:23:09 kashmir Exp $
*/
#ifndef _SYS_UNISTD_H_
@ -124,15 +124,11 @@
*
* XXX currently, operations without RFPROC set are not supported.
*/
#define RFNAMEG (1<<0) /* UNIMPL new plan9 `name space' */
#define RFENVG (1<<1) /* UNIMPL copy plan9 `env space' */
#define RFFDG (1<<2) /* copy fd table */
#define RFNOTEG (1<<3) /* UNIMPL create new plan9 `note group' */
#define RFPROC (1<<4) /* change child (else changes curproc) */
#define RFMEM (1<<5) /* share `address space' */
#define RFNOWAIT (1<<6) /* UNIMPL parent need not wait() on child */
#define RFCNAMEG (1<<10) /* UNIMPL zero plan9 `name space' */
#define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */
#define RFCFDG (1<<12) /* zero fd table */
#define RFFDG (1<<0) /* copy fd table */
#define RFPROC (1<<1) /* change child (else changes curproc) */
#define RFMEM (1<<2) /* share `address space' */
#define RFNOWAIT (1<<3) /* parent need not wait() on child */
#define RFCFDG (1<<4) /* zero fd table */
#define RFPPWAIT (1<<5) /* parent sleeps until child exits (vfork) */
#endif /* !_SYS_UNISTD_H_ */