plan9-like rfork() implimentation by me based on some earlier incomplete
authorderaadt <deraadt@openbsd.org>
Wed, 10 Jan 1996 18:02:12 +0000 (18:02 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 10 Jan 1996 18:02:12 +0000 (18:02 +0000)
work by rminnich@Sarnoff.COM. still needs RFNOWAIT support.

sys/kern/init_sysent.c
sys/kern/kern_fork.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/sys/param.h
sys/sys/syscall.h
sys/sys/syscallargs.h

index 51c3c1a..bd5c709 100644 (file)
@@ -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 */
 };
 
index 1beb55b..1209ce9 100644 (file)
 #include <sys/acct.h>
 #include <sys/ktrace.h>
 
+#include <vm/vm.h>
+
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+
 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);
 
index 71887e4..577d9f1 100644 (file)
@@ -326,4 +326,5 @@ char *syscallnames[] = {
        "#248 (unimplemented)",         /* 248 = unimplemented */
        "#249 (unimplemented)",         /* 249 = unimplemented */
        "minherit",                     /* 250 = minherit */
+       "rfork",                        /* 251 = rfork */
 };
index 45827ce..813c9c5 100644 (file)
 249    UNIMPL
 250    STD             { int sys_minherit(caddr_t addr, size_t len, \
                            int inherit); }
+251    STD             { int sys_rfork(int flags); }
index 9c36ba2..951aeae 100644 (file)
  */
 #define        FSHIFT  11              /* bits to right of fixed binary point */
 #define FSCALE (1<<FSHIFT)
+
+/*
+ * rfork() options.
+ *
+ * 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 */
index 1b32a84..098fc57 100644 (file)
 #define        SYS_shmdt       230
 #define        SYS_shmget      231
 #define        SYS_minherit    250
-#define        SYS_MAXSYSCALL  251
+#define        SYS_rfork       251
+#define        SYS_MAXSYSCALL  252
index dc2b768..40f7bb2 100644 (file)
@@ -946,6 +946,10 @@ struct sys_minherit_args {
        syscallarg(int) inherit;
 };
 
+struct sys_rfork_args {
+       syscallarg(int) flags;
+};
+
 /*
  * System call prototypes.
  */
@@ -1186,3 +1190,4 @@ int       sys_shmget      __P((struct proc *, void *, register_t *));
 #else
 #endif
 int    sys_minherit    __P((struct proc *, void *, register_t *));
+int    sys_rfork       __P((struct proc *, void *, register_t *));