projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
add POSIX-style byte-level record locking
[unix-history]
/
usr
/
src
/
sys
/
kern
/
kern_fork.c
diff --git
a/usr/src/sys/kern/kern_fork.c
b/usr/src/sys/kern/kern_fork.c
index
d32f74f
..
b783420
100644
(file)
--- a/
usr/src/sys/kern/kern_fork.c
+++ b/
usr/src/sys/kern/kern_fork.c
@@
-1,58
+1,66
@@
-/* kern_fork.c 6.5 84/08/29 */
-
-#include "../machine/reg.h"
-#include "../machine/pte.h"
-#include "../machine/psl.h"
+/*
+ * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * %sccs.include.redist.c%
+ *
+ * @(#)kern_fork.c 7.23 (Berkeley) %G%
+ */
#include "param.h"
#include "systm.h"
#include "map.h"
#include "param.h"
#include "systm.h"
#include "map.h"
-#include "dir.h"
#include "user.h"
#include "user.h"
+#include "filedesc.h"
#include "kernel.h"
#include "proc.h"
#include "kernel.h"
#include "proc.h"
-#include "
i
node.h"
+#include "
v
node.h"
#include "seg.h"
#include "seg.h"
-#include "vm.h"
-#include "text.h"
#include "file.h"
#include "acct.h"
#include "file.h"
#include "acct.h"
-#include "quota.h"
+#include "ktrace.h"
+
+#include "machine/reg.h"
+#include "machine/psl.h"
/*
* fork system call.
*/
/*
* fork system call.
*/
-fork()
+/* ARGSUSED */
+fork(p, uap, retval)
+ struct proc *p;
+ struct args *uap;
+ int retval[];
{
{
+ int error;
- u.u_cdmap = zdmap;
- u.u_csmap = zdmap;
- if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0) {
- u.u_r.r_val2 = 0;
- return;
- }
- fork1(0);
+ return (fork1(p, 0, retval));
}
}
-vfork()
+/* ARGSUSED */
+vfork(p, uap, retval)
+ struct proc *p;
+ struct args *uap;
+ int retval[];
{
{
-
fork1(1
);
+
return (fork1(p, 1, retval)
);
}
}
-fork1(isvfork)
- int isvfork;
+fork1(p1, isvfork, retval)
+ register struct proc *p1;
+ int isvfork, retval[];
{
{
- register struct proc *p
1, *p
2;
- register a;
+ register struct proc *p2;
+ register
int
a;
a = 0;
a = 0;
- if (
u.u
_uid != 0) {
- for (p
1 = allproc; p1; p1 = p1
->p_nxt)
- if (p
1->p_uid == u.u
_uid)
+ if (
p1->p
_uid != 0) {
+ for (p
2 = allproc; p2; p2 = p2
->p_nxt)
+ if (p
2->p_uid == p1->p
_uid)
a++;
a++;
- for (p
1 = zombproc; p1; p1 = p1
->p_nxt)
- if (p
1->p_uid == u.u
_uid)
+ for (p
2 = zombproc; p2; p2 = p2
->p_nxt)
+ if (p
2->p_uid == p1->p
_uid)
a++;
}
/*
a++;
}
/*
@@
-64,26
+72,20
@@
fork1(isvfork)
p2 = freeproc;
if (p2==NULL)
tablefull("proc");
p2 = freeproc;
if (p2==NULL)
tablefull("proc");
- if (p2==NULL || (u.u_uid!=0 && (p2->p_nxt == NULL || a>MAXUPRC))) {
- u.u_error = EAGAIN;
- if (!isvfork) {
- (void) vsexpand(0, &u.u_cdmap, 1);
- (void) vsexpand(0, &u.u_csmap, 1);
- }
- goto out;
+ if (p2 == NULL ||
+ (p1->p_uid != 0 && (p2->p_nxt == NULL || a > MAXUPRC))) {
+ retval[1] = 0;
+ return (EAGAIN);
}
}
- p1 = u.u_procp;
if (newproc(isvfork)) {
if (newproc(isvfork)) {
- u.u_r.r_val1 = p1->p_pid;
- u.u_r.r_val2 = 1; /* child */
- u.u_start = time;
+ retval[0] = p1->p_pid;
+ retval[1] = 1; /* child */
u.u_acflag = AFORK;
u.u_acflag = AFORK;
- return;
+ return
(0)
;
}
}
- u.u_r.r_val1 = p2->p_pid;
-
-out:
- u.u_r.r_val2 = 0;
+ retval[0] = p2->p_pid;
+ retval[1] = 0;
+ return (0);
}
/*
}
/*
@@
-95,7
+97,6
@@
newproc(isvfork)
int isvfork;
{
register struct proc *rpp, *rip;
int isvfork;
{
register struct proc *rpp, *rip;
- register int n;
register struct file *fp;
static int pidchecked = 0;
register struct file *fp;
static int pidchecked = 0;
@@
-107,14
+108,14
@@
newproc(isvfork)
*/
mpid++;
retry:
*/
mpid++;
retry:
- if (mpid >=
30000
) {
+ if (mpid >=
PID_MAX
) {
mpid = 100;
pidchecked = 0;
}
if (mpid >= pidchecked) {
int doingzomb = 0;
mpid = 100;
pidchecked = 0;
}
if (mpid >= pidchecked) {
int doingzomb = 0;
- pidchecked =
30000
;
+ pidchecked =
PID_MAX
;
/*
* Scan the proc table to check whether this pid
* is in use. Remember the lowest pid that's greater
/*
* Scan the proc table to check whether this pid
* is in use. Remember the lowest pid that's greater
@@
-123,15
+124,16
@@
retry:
rpp = allproc;
again:
for (; rpp != NULL; rpp = rpp->p_nxt) {
rpp = allproc;
again:
for (; rpp != NULL; rpp = rpp->p_nxt) {
- if (rpp->p_pid == mpid || rpp->p_pgrp == mpid) {
+ if (rpp->p_pid == mpid || rpp->p_pgrp
->pg_id
== mpid) {
mpid++;
if (mpid >= pidchecked)
goto retry;
}
if (rpp->p_pid > mpid && pidchecked > rpp->p_pid)
pidchecked = rpp->p_pid;
mpid++;
if (mpid >= pidchecked)
goto retry;
}
if (rpp->p_pid > mpid && pidchecked > rpp->p_pid)
pidchecked = rpp->p_pid;
- if (rpp->p_pgrp > mpid && pidchecked > rpp->p_pgrp)
- pidchecked = rpp->p_pgrp;
+ if (rpp->p_pgrp->pg_id > mpid &&
+ pidchecked > rpp->p_pgrp->pg_id)
+ pidchecked = rpp->p_pgrp->pg_id;
}
if (!doingzomb) {
doingzomb = 1;
}
if (!doingzomb) {
doingzomb = 1;
@@
-152,22
+154,27
@@
again:
* Make a proc table entry for the new process.
*/
rip = u.u_procp;
* Make a proc table entry for the new process.
*/
rip = u.u_procp;
-#if
def QUOTA
- rpp->p_
quota = rip->p_quota
;
- rpp->p_
quota->q_cnt++
;
+#if
defined(tahoe)
+ rpp->p_
ckey = rip->p_ckey
;
+ rpp->p_
dkey = 0
;
#endif
rpp->p_stat = SIDL;
timerclear(&rpp->p_realtimer.it_value);
#endif
rpp->p_stat = SIDL;
timerclear(&rpp->p_realtimer.it_value);
- rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SOUSIG));
- if (isvfork) {
+ rpp->p_flag = SLOAD | (rip->p_flag & (SPAGV|SHPUX));
+ if (rip->p_session->s_ttyvp != NULL && rip->p_flag & SCTTY)
+ rpp->p_flag |= SCTTY;
+ if (isvfork)
rpp->p_flag |= SVFORK;
rpp->p_flag |= SVFORK;
-
rpp->p_ndx = rip->p_ndx
;
- } else
-
rpp->p_ndx = rpp - proc
;
+
rpp->p_ndx = rpp - proc
;
+ bcopy(rip->p_comm, rpp->p_comm, MAXCOMLEN+1);
+
bcopy(rip->p_logname, rpp->p_logname, MAXLOGNAME)
;
rpp->p_uid = rip->p_uid;
rpp->p_uid = rip->p_uid;
+ rpp->p_ruid = rip->p_ruid;
+ rpp->p_rgid = rip->p_rgid;
rpp->p_pgrp = rip->p_pgrp;
rpp->p_pgrp = rip->p_pgrp;
+ rpp->p_pgrpnxt = rip->p_pgrpnxt;
+ rip->p_pgrpnxt = rpp;
rpp->p_nice = rip->p_nice;
rpp->p_nice = rip->p_nice;
- rpp->p_textp = isvfork ? 0 : rip->p_textp;
rpp->p_pid = mpid;
rpp->p_ppid = rip->p_pid;
rpp->p_pptr = rip;
rpp->p_pid = mpid;
rpp->p_ppid = rip->p_pid;
rpp->p_pptr = rip;
@@
-178,60
+185,61
@@
again:
rpp->p_cptr = NULL;
rip->p_cptr = rpp;
rpp->p_time = 0;
rpp->p_cptr = NULL;
rip->p_cptr = rpp;
rpp->p_time = 0;
+ bzero((caddr_t)&rpp->p_utime, sizeof (struct timeval));
+ bzero((caddr_t)&rpp->p_stime, sizeof (struct timeval));
rpp->p_cpu = 0;
rpp->p_sigmask = rip->p_sigmask;
rpp->p_sigcatch = rip->p_sigcatch;
rpp->p_sigignore = rip->p_sigignore;
rpp->p_cpu = 0;
rpp->p_sigmask = rip->p_sigmask;
rpp->p_sigcatch = rip->p_sigcatch;
rpp->p_sigignore = rip->p_sigignore;
- /* take along any pending signals like stops? */
- if (isvfork) {
- rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0;
- rpp->p_szpt = clrnd(ctopt(UPAGES));
- forkstat.cntvfork++;
- forkstat.sizvfork += rip->p_dsize + rip->p_ssize;
+#ifdef KTRACE
+ if (rip->p_traceflag&KTRFAC_INHERIT) {
+ rpp->p_traceflag = rip->p_traceflag;
+ if ((rpp->p_tracep = rip->p_tracep) != NULL)
+ VREF(rpp->p_tracep);
} else {
} else {
- rpp->p_tsize = rip->p_tsize;
- rpp->p_dsize = rip->p_dsize;
- rpp->p_ssize = rip->p_ssize;
- rpp->p_szpt = rip->p_szpt;
- forkstat.cntfork++;
- forkstat.sizfork += rip->p_dsize + rip->p_ssize;
+ rpp->p_tracep = NULL;
+ rpp->p_traceflag = 0;
}
}
+#endif
rpp->p_rssize = 0;
rpp->p_maxrss = rip->p_maxrss;
rpp->p_wchan = 0;
rpp->p_slptime = 0;
rpp->p_pctcpu = 0;
rpp->p_cpticks = 0;
rpp->p_rssize = 0;
rpp->p_maxrss = rip->p_maxrss;
rpp->p_wchan = 0;
rpp->p_slptime = 0;
rpp->p_pctcpu = 0;
rpp->p_cpticks = 0;
- n = PIDHASH(rpp->p_pid);
- rpp->p_idhash = pidhash[n];
- pidhash[n] = rpp - proc;
- multprog++;
+ {
+ struct proc **hash = &pidhash[PIDHASH(rpp->p_pid)];
+
+ rpp->p_hash = *hash;
+ *hash = rpp;
+ }
/*
* Increase reference counts on shared objects.
*/
/*
* Increase reference counts on shared objects.
*/
- for (n = 0; n < NOFILE; n++) {
- fp = u.u_ofile[n];
- if (fp == NULL)
- continue;
- fp->f_count++;
- }
- u.u_cdir->i_count++;
- if (u.u_rdir)
- u.u_rdir->i_count++;
+ rpp->p_fd = fddup(rip->p_fd, 0);
+#ifdef SYSVSHM
+ if (rip->p_shm)
+ shmfork(rip, rpp, isvfork);
+#endif
+ crhold(u.u_cred);
/*
* This begins the section where we must prevent the parent
* from being swapped.
*/
rip->p_flag |= SKEEP;
/*
* This begins the section where we must prevent the parent
* from being swapped.
*/
rip->p_flag |= SKEEP;
- if (procdup(rpp, isvfork))
+ if (procdup(rpp, isvfork)) {
+ (void) splclock();
+ u.u_start = time;
+ (void) spl0();
return (1);
return (1);
+ }
/*
* Make child runnable and add to run queue.
*/
/*
* Make child runnable and add to run queue.
*/
- (void) spl
6
();
+ (void) spl
clock
();
rpp->p_stat = SRUN;
setrq(rpp);
(void) spl0();
rpp->p_stat = SRUN;
setrq(rpp);
(void) spl0();
@@
-250,23
+258,15
@@
again:
rip->p_flag &= ~SKEEP;
/*
rip->p_flag &= ~SKEEP;
/*
- * If vfork make chain from parent process to child
- * (where virtal memory is temporarily). Wait for
- * child to finish, steal virtual memory back,
- * and wakeup child to let it die.
+ * XXX preserve synchronization semantics of vfork
*/
if (isvfork) {
*/
if (isvfork) {
- u.u_procp->p_xlink = rpp;
u.u_procp->p_flag |= SNOVM;
while (rpp->p_flag & SVFORK)
sleep((caddr_t)rpp, PZERO - 1);
if ((rpp->p_flag & SLOAD) == 0)
panic("newproc vfork");
u.u_procp->p_flag |= SNOVM;
while (rpp->p_flag & SVFORK)
sleep((caddr_t)rpp, PZERO - 1);
if ((rpp->p_flag & SLOAD) == 0)
panic("newproc vfork");
- uaccess(rpp, Vfmap, &vfutl);
- u.u_procp->p_xlink = 0;
- vpassvm(rpp, u.u_procp, &vfutl, &u, Vfmap);
u.u_procp->p_flag &= ~SNOVM;
u.u_procp->p_flag &= ~SNOVM;
- rpp->p_ndx = rpp - proc;
rpp->p_flag |= SVFDONE;
wakeup((caddr_t)rpp);
}
rpp->p_flag |= SVFDONE;
wakeup((caddr_t)rpp);
}