ec_rxstart doesn't eists
[unix-history] / usr / src / sys / kern / kern_fork.c
index 1762c57..9d2ea84 100644 (file)
@@ -1,10 +1,10 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
  * All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  * All rights reserved.
  *
  * %sccs.include.redist.c%
  *
- *     @(#)kern_fork.c 7.25 (Berkeley) %G%
+ *     @(#)kern_fork.c 7.31 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -16,7 +16,6 @@
 #include "proc.h"
 #include "resourcevar.h"
 #include "vnode.h"
 #include "proc.h"
 #include "resourcevar.h"
 #include "vnode.h"
-#include "seg.h"
 #include "file.h"
 #include "acct.h"
 #include "ktrace.h"
 #include "file.h"
 #include "acct.h"
 #include "ktrace.h"
@@ -24,7 +23,7 @@
 /* ARGSUSED */
 fork(p, uap, retval)
        struct proc *p;
 /* ARGSUSED */
 fork(p, uap, retval)
        struct proc *p;
-       struct args *uap;
+       void *uap;
        int retval[];
 {
 
        int retval[];
 {
 
@@ -34,7 +33,7 @@ fork(p, uap, retval)
 /* ARGSUSED */
 vfork(p, uap, retval)
        struct proc *p;
 /* ARGSUSED */
 vfork(p, uap, retval)
        struct proc *p;
-       struct args *uap;
+       void *uap;
        int retval[];
 {
 
        int retval[];
 {
 
@@ -61,7 +60,7 @@ fork1(p1, isvfork, retval)
                                count++;
        }
        /*
                                count++;
        }
        /*
-        * Although process entries are dynamically entries,
+        * Although process entries are dynamically created,
         * we still keep a global limit on the maximum number
         * we will create.  Don't allow a nonprivileged user
         * to exceed its current limit or to bring us within one
         * we still keep a global limit on the maximum number
         * we will create.  Don't allow a nonprivileged user
         * to exceed its current limit or to bring us within one
@@ -69,7 +68,6 @@ fork1(p1, isvfork, retval)
         * nprocs is the current number of processes,
         * maxproc is the limit.
         */
         * nprocs is the current number of processes,
         * maxproc is the limit.
         */
-       retval[1] = 0;
        if (nprocs >= maxproc || uid == 0 && nprocs >= maxproc + 1) {
                tablefull("proc");
                return (EAGAIN);
        if (nprocs >= maxproc || uid == 0 && nprocs >= maxproc + 1) {
                tablefull("proc");
                return (EAGAIN);
@@ -147,18 +145,23 @@ again:
            (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
        bcopy(&p1->p_startcopy, &p2->p_startcopy,
            (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
            (unsigned) ((caddr_t)&p2->p_endzero - (caddr_t)&p2->p_startzero));
        bcopy(&p1->p_startcopy, &p2->p_startcopy,
            (unsigned) ((caddr_t)&p2->p_endcopy - (caddr_t)&p2->p_startcopy));
+       p2->p_spare[0] = 0;     /* XXX - should be in zero range */
+       p2->p_spare[1] = 0;     /* XXX - should be in zero range */
+       p2->p_spare[2] = 0;     /* XXX - should be in zero range */
+       p2->p_spare[3] = 0;     /* XXX - should be in zero range */
 
        /*
         * Duplicate sub-structures as needed.
         * Increase reference counts on shared objects.
 
        /*
         * Duplicate sub-structures as needed.
         * Increase reference counts on shared objects.
+        * The p_stats and p_sigacts substructs are set in vm_fork.
         */
        MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
            M_SUBPROC, M_WAITOK);
        bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
         */
        MALLOC(p2->p_cred, struct pcred *, sizeof(struct pcred),
            M_SUBPROC, M_WAITOK);
        bcopy(p1->p_cred, p2->p_cred, sizeof(*p2->p_cred));
+       p2->p_cred->p_refcnt = 1;
        crhold(p1->p_ucred);
 
        p2->p_fd = fdcopy(p1);
        crhold(p1->p_ucred);
 
        p2->p_fd = fdcopy(p1);
-       p2->p_stats = p1->p_stats;              /* XXX move; in u. */
        /*
         * If p_limit is still copy-on-write, bump refcnt,
         * otherwise get a copy that won't be modified.
        /*
         * If p_limit is still copy-on-write, bump refcnt,
         * otherwise get a copy that won't be modified.
@@ -171,9 +174,8 @@ again:
                p2->p_limit = p1->p_limit;
                p2->p_limit->p_refcnt++;
        }
                p2->p_limit = p1->p_limit;
                p2->p_limit->p_refcnt++;
        }
-       p2->p_sigacts = p1->p_sigacts;          /* XXX move; in u. */
 
 
-       p2->p_flag = SLOAD | (p1->p_flag & (SPAGV|SHPUX));
+       p2->p_flag = SLOAD | (p1->p_flag & SHPUX);
        if (p1->p_session->s_ttyvp != NULL && p1->p_flag & SCTTY)
                p2->p_flag |= SCTTY;
        if (isvfork)
        if (p1->p_session->s_ttyvp != NULL && p1->p_flag & SCTTY)
                p2->p_flag |= SCTTY;
        if (isvfork)
@@ -205,7 +207,6 @@ again:
        }
 #endif
 
        }
 #endif
 
-       p2->p_regs = p1->p_regs;                 /* XXX move this */
 #if defined(tahoe)
        p2->p_vmspace->p_ckey = p1->p_vmspace->p_ckey; /* XXX move this */
 #endif
 #if defined(tahoe)
        p2->p_vmspace->p_ckey = p1->p_vmspace->p_ckey; /* XXX move this */
 #endif
@@ -215,16 +216,23 @@ again:
         * from being swapped.
         */
        p1->p_flag |= SKEEP;
         * from being swapped.
         */
        p1->p_flag |= SKEEP;
+       /*
+        * Set return values for child before vm_fork,
+        * so they can be copied to child stack.
+        * We return parent pid, and mark as child in retval[1].
+        * NOTE: the kernel stack may be at a different location in the child
+        * process, and thus addresses of automatic variables (including retval)
+        * may be invalid after vm_fork returns in the child process.
+        */
+       retval[0] = p1->p_pid;
+       retval[1] = 1;
        if (vm_fork(p1, p2, isvfork)) {
                /*
        if (vm_fork(p1, p2, isvfork)) {
                /*
-                * Child process.  Set start time, return parent pid,
-                * and mark as child in retval[1].
+                * Child process.  Set start time and get to work.
                 */
                (void) splclock();
                p2->p_stats->p_start = time;
                (void) spl0();
                 */
                (void) splclock();
                p2->p_stats->p_start = time;
                (void) spl0();
-               retval[0] = p1->p_pid;
-               retval[1] = 1;
                p2->p_acflag = AFORK;
                return (0);
        }
                p2->p_acflag = AFORK;
                return (0);
        }
@@ -243,18 +251,19 @@ again:
        p1->p_flag &= ~SKEEP;
 
        /*
        p1->p_flag &= ~SKEEP;
 
        /*
-        * XXX preserve synchronization semantics of vfork
+        * Preserve synchronization semantics of vfork.
         * If waiting for child to exec or exit, set SPPWAIT
         * on child, and sleep on our proc (in case of exit).
         */
        if (isvfork)
                while (p2->p_flag & SPPWAIT)
         * If waiting for child to exec or exit, set SPPWAIT
         * on child, and sleep on our proc (in case of exit).
         */
        if (isvfork)
                while (p2->p_flag & SPPWAIT)
-                       sleep((caddr_t)p1, PZERO - 1);
+                       tsleep((caddr_t)p1, PWAIT, "ppwait", 0);
 
        /*
 
        /*
-        * Return child pid to parent process.
-        * retval[1] was set above.
+        * Return child pid to parent process,
+        * marking us as parent via retval[1].
         */
        retval[0] = p2->p_pid;
         */
        retval[0] = p2->p_pid;
+       retval[1] = 0;
        return (0);
 }
        return (0);
 }