From 3388b1b4ab64cffc1d1bf306ad1f48c006aa17ed Mon Sep 17 00:00:00 2001 From: deraadt Date: Wed, 10 Jan 1996 18:02:12 +0000 Subject: [PATCH] plan9-like rfork() implimentation by me based on some earlier incomplete work by rminnich@Sarnoff.COM. still needs RFNOWAIT support. --- sys/kern/init_sysent.c | 2 ++ sys/kern/kern_fork.c | 71 +++++++++++++++++++++++++++++++++++----- sys/kern/syscalls.c | 1 + sys/kern/syscalls.master | 1 + sys/sys/param.h | 16 +++++++++ sys/sys/syscall.h | 3 +- sys/sys/syscallargs.h | 5 +++ 7 files changed, 90 insertions(+), 9 deletions(-) diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 51c3c1ac731..bd5c709a8ac 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -636,5 +636,7 @@ struct sysent sysent[] = { sys_nosys }, /* 249 = unimplemented */ { 3, s(struct sys_minherit_args), sys_minherit }, /* 250 = minherit */ + { 1, s(struct sys_rfork_args), + sys_rfork }, /* 251 = rfork */ }; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 1beb55be014..1209ce90350 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -53,8 +53,17 @@ #include #include +#include + +#include +#include + int nprocs = 1; /* process 0 */ +#define ISFORK 0 +#define ISVFORK 1 +#define ISRFORK 2 + int sys_fork(p, v, retval) struct proc *p; @@ -62,7 +71,7 @@ sys_fork(p, v, retval) register_t *retval; { - return (fork1(p, 0, retval)); + return (fork1(p, ISFORK, 0, retval)); } int @@ -72,13 +81,27 @@ sys_vfork(p, v, retval) register_t *retval; { - return (fork1(p, 1, retval)); + return (fork1(p, ISVFORK, 0, retval)); } int -fork1(p1, isvfork, retval) +sys_rfork(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_rfork_args /* { + syscallarg(int) flags; + } */ *uap = v; + + return (fork1(p, ISRFORK, SCARG(uap, flags), retval)); +} + +int +fork1(p1, forktype, rforkflags, retval) register struct proc *p1; - int isvfork; + int forktype; + int rforkflags; register_t *retval; { register struct proc *p2; @@ -87,6 +110,21 @@ fork1(p1, isvfork, retval) 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; + } /* * Although process entries are dynamically created, we still keep @@ -198,7 +236,13 @@ again: if (p2->p_textvp) VREF(p2->p_textvp); - p2->p_fd = fdcopy(p1); + if (cleanfd) + p2->p_fd = fdinit(p1); + else if (dupfd) + p2->p_fd = fdcopy(p1); + else + p2->p_fd = fdshare(p1); + /* * If p_limit is still copy-on-write, bump refcnt, * otherwise get a copy that won't be modified. @@ -214,11 +258,15 @@ again: if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT) p2->p_flag |= P_CONTROLT; - if (isvfork) + if (forktype == ISVFORK) 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); + if (rforkflags & RFNOWAIT) { + /* XXX should we do anything? */ + } else { + LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling); + } LIST_INIT(&p2->p_children); #ifdef KTRACE @@ -239,6 +287,13 @@ again: */ p1->p_holdcnt++; + if (forktype == ISRFORK && (rforkflags & RFMEM)) { + /* share as much address space as possible */ + (void) vm_map_inherit(&p1->p_vmspace->vm_map, + VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ, + VM_INHERIT_SHARE); + } + #ifdef __FORK_BRAINDAMAGE /* * Set return values for child before vm_fork, @@ -281,7 +336,7 @@ again: * child to exec or exit, set P_PPWAIT on child, and sleep on our * proc (in case of exit). */ - if (isvfork) + if (forktype == ISVFORK) while (p2->p_flag & P_PPWAIT) tsleep(p1, PWAIT, "ppwait", 0); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 71887e40837..577d9f1cdb2 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -326,4 +326,5 @@ char *syscallnames[] = { "#248 (unimplemented)", /* 248 = unimplemented */ "#249 (unimplemented)", /* 249 = unimplemented */ "minherit", /* 250 = minherit */ + "rfork", /* 251 = rfork */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 45827ce247c..813c9c5997f 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -445,3 +445,4 @@ 249 UNIMPL 250 STD { int sys_minherit(caddr_t addr, size_t len, \ int inherit); } +251 STD { int sys_rfork(int flags); } diff --git a/sys/sys/param.h b/sys/sys/param.h index 9c36ba235a2..951aeaec4cb 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -219,3 +219,19 @@ */ #define FSHIFT 11 /* bits to right of fixed binary point */ #define FSCALE (1<