summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2000-01-31 19:57:22 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2000-01-31 19:57:22 +0000
commitd9be13a593426dad5ab4c996f5351c88e2d396a0 (patch)
treeeaf918d2b1f05c81819e49c32e49525a479d533d /sys
parenta9e4cdae52383e691efc78d72fa386a66fdd32a6 (diff)
re-add fixed vfork code from art
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/netbsd/netbsd_misc.c5
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_fork.c102
-rw-r--r--sys/kern/kern_kthread.c4
-rw-r--r--sys/sys/proc.h19
5 files changed, 76 insertions, 58 deletions
diff --git a/sys/compat/netbsd/netbsd_misc.c b/sys/compat/netbsd/netbsd_misc.c
index 90ffab99d0f..8cf60355bab 100644
--- a/sys/compat/netbsd/netbsd_misc.c
+++ b/sys/compat/netbsd/netbsd_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netbsd_misc.c,v 1.7 2000/01/31 01:09:11 deraadt Exp $ */
+/* $OpenBSD: netbsd_misc.c,v 1.8 2000/01/31 19:57:21 deraadt Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@@ -61,7 +61,8 @@ netbsd_sys___vfork14(p, v, retval)
void *v;
register_t *retval;
{
- return (fork1(p, ISVFORK, 0, NULL, 0, retval));
+ /* XXX - should add FORK_SHAREVM */
+ return (fork1(p, FORK_VFORK|FORK_PPWAIT, NULL, 0, retval));
}
/* XXX syncs whole file */
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index c71301dd274..b16a3293678 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.45 2000/01/31 01:09:10 deraadt Exp $ */
+/* $OpenBSD: init_main.c,v 1.46 2000/01/31 19:57:18 deraadt Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -399,7 +399,7 @@ main(framep)
siginit(p);
/* Create process 1 (init(8)). */
- if (fork1(p, ISFORK, 0, NULL, 0, rval))
+ if (fork1(p, FORK_FORK, NULL, 0, rval))
panic("fork init");
#ifdef cpu_set_init_frame /* XXX should go away */
if (rval[1]) {
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index f355abab4a7..152dd5edb84 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.26 2000/01/31 01:09:10 deraadt Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.27 2000/01/31 19:57:18 deraadt Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -78,7 +78,7 @@ sys_fork(p, v, retval)
void *v;
register_t *retval;
{
- return (fork1(p, ISFORK, 0, NULL, 0, retval));
+ return (fork1(p, FORK_FORK, NULL, 0, retval));
}
/*ARGSUSED*/
@@ -88,7 +88,7 @@ sys_vfork(p, v, retval)
void *v;
register_t *retval;
{
- return (fork1(p, ISVFORK, 0, NULL, 0, retval));
+ return (fork1(p, FORK_VFORK|FORK_PPWAIT, NULL, 0, retval));
}
int
@@ -100,15 +100,41 @@ sys_rfork(p, v, retval)
struct sys_rfork_args /* {
syscallarg(int) flags;
} */ *uap = v;
+ int rforkflags;
+ int flags;
+
+ flags = FORK_RFORK;
+ rforkflags = SCARG(uap, flags);
+
+ if ((rforkflags & RFPROC) == 0)
+ return (EINVAL);
+
+ switch(rforkflags & (RFFDG|RFCFDG)) {
+ case (RFFDG|RFCFDG):
+ return EINVAL;
+ case RFCFDG:
+ flags |= FORK_CLEANFILES;
+ break;
+ case RFFDG:
+ break;
+ default:
+ flags |= FORK_SHAREFILES;
+ break;
+ }
+
+ if (rforkflags & RFNOWAIT)
+ flags |= FORK_NOZOMBIE;
- return (fork1(p, ISRFORK, SCARG(uap, flags), NULL, 0, retval));
+ if (rforkflags & RFMEM)
+ flags |= FORK_SHAREVM;
+
+ return (fork1(p, flags, NULL, 0, retval));
}
int
-fork1(p1, forktype, rforkflags, stack, stacksize, retval)
+fork1(p1, flags, stack, stacksize, retval)
register struct proc *p1;
- int forktype;
- int rforkflags;
+ int flags;
void *stack;
size_t stacksize;
register_t *retval;
@@ -119,21 +145,8 @@ fork1(p1, forktype, rforkflags, stack, stacksize, retval)
struct vmspace *vm;
int count;
static int pidchecked = 0;
- int dupfd = 1, cleanfd = 0;
vaddr_t uaddr;
- 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 & RFCFDG)
- cleanfd = 1;
- }
-
/*
* Although process entries are dynamically created, we still keep
* a global limit on the maximum number we will create. We reserve
@@ -257,12 +270,12 @@ again:
if (p2->p_textvp)
VREF(p2->p_textvp);
- if (cleanfd)
+ if (flags & FORK_CLEANFILES)
p2->p_fd = fdinit(p1);
- else if (dupfd)
- p2->p_fd = fdcopy(p1);
- else
+ else if (flags & FORK_SHAREFILES)
p2->p_fd = fdshare(p1);
+ else
+ p2->p_fd = fdcopy(p1);
/*
* If p_limit is still copy-on-write, bump refcnt,
@@ -279,11 +292,11 @@ again:
if (p1->p_session->s_ttyvp != NULL && p1->p_flag & P_CONTROLT)
p2->p_flag |= P_CONTROLT;
- if (forktype == ISVFORK)
+ if (flags & FORK_PPWAIT)
p2->p_flag |= P_PPWAIT;
LIST_INSERT_AFTER(p1, p2, p_pglist);
p2->p_pptr = p1;
- if (forktype == ISRFORK && (rforkflags & RFNOWAIT))
+ if (flags & FORK_NOZOMBIE)
p2->p_flag |= P_NOZOMBIE;
LIST_INSERT_HEAD(&p1->p_children, p2, p_sibling);
LIST_INIT(&p2->p_children);
@@ -293,7 +306,7 @@ again:
* Copy traceflag and tracefile if enabled.
* If not inherited, these were zeroed above.
*/
- if (p1->p_traceflag&KTRFAC_INHERIT) {
+ if (p1->p_traceflag & KTRFAC_INHERIT) {
p2->p_traceflag = p1->p_traceflag;
if ((p2->p_tracep = p1->p_tracep) != NULL)
VREF(p2->p_tracep);
@@ -314,7 +327,7 @@ again:
p1->p_holdcnt++;
#if !defined(UVM) /* We do this later for UVM */
- if (forktype == ISRFORK && (rforkflags & RFMEM)) {
+ if (flags & FORK_SHAREVM) {
/* share as much address space as possible */
(void) vm_map_inherit(&p1->p_vmspace->vm_map,
VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ,
@@ -344,28 +357,23 @@ again:
* different path later.
*/
#if defined(UVM)
- uvm_fork(p1, p2,
- (forktype == ISRFORK && (rforkflags & RFMEM)) ? TRUE : FALSE,
- stack, stacksize);
+ uvm_fork(p1, p2, ((flags & FORK_SHAREVM) ? TRUE : FALSE), stack,
+ stacksize);
#else /* UVM */
vm_fork(p1, p2, stack, stacksize);
#endif /* UVM */
#endif
vm = p2->p_vmspace;
- switch (forktype) {
- case ISFORK:
- forkstat.cntfork++;
- forkstat.sizfork += vm->vm_dsize + vm->vm_ssize;
- break;
- case ISVFORK:
- forkstat.cntvfork++;
- forkstat.sizvfork += vm->vm_dsize + vm->vm_ssize;
- break;
- case ISRFORK:
- forkstat.cntrfork++;
- forkstat.sizrfork += vm->vm_dsize + vm->vm_ssize;
- break;
+ if (flags & FORK_FORK) {
+ forkstat.cntfork++;
+ forkstat.sizfork += vm->vm_dsize + vm->vm_ssize;
+ } else if (flags & FORK_VFORK) {
+ forkstat.cntvfork++;
+ forkstat.sizvfork += vm->vm_dsize + vm->vm_ssize;
+ } else if (flags & FORK_RFORK) {
+ forkstat.cntrfork++;
+ forkstat.sizrfork += vm->vm_dsize + vm->vm_ssize;
}
/*
@@ -385,9 +393,9 @@ again:
#if defined(UVM)
uvmexp.forks++;
- if (forktype == ISVFORK)
+ if (flags & FORK_PPWAIT)
uvmexp.forks_ppwait++;
- if (forktype == ISRFORK && (rforkflags & RFMEM))
+ if (flags & FORK_SHAREVM)
uvmexp.forks_sharevm++;
#endif
@@ -396,7 +404,7 @@ again:
* child to exec or exit, set P_PPWAIT on child, and sleep on our
* proc (in case of exit).
*/
- if (forktype == ISVFORK)
+ if (flags & FORK_PPWAIT)
while (p2->p_flag & P_PPWAIT)
tsleep(p1, PWAIT, "ppwait", 0);
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index b4eef9770f5..4d4a90fec05 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_kthread.c,v 1.6 2000/01/31 01:09:10 deraadt Exp $ */
+/* $OpenBSD: kern_kthread.c,v 1.7 2000/01/31 19:57:19 deraadt Exp $ */
/* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */
/*-
@@ -83,7 +83,7 @@ kthread_create(func, arg, newpp, fmt, va_alist)
* descriptors and don't leave the exit status around for the
* parent to wait for.
*/
- error = fork1(&proc0, ISRFORK, RFPROC | RFMEM | RFFDG | RFNOWAIT, NULL,
+ error = fork1(&proc0, FORK_RFORK|FORK_SHAREVM|FORK_NOZOMBIE, NULL,
0, rv);
if (error)
return (error);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index adc5dddc645..70d531b392e 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.27 2000/01/31 01:09:09 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.28 2000/01/31 19:57:20 deraadt Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -283,6 +283,18 @@ struct pcred {
#endif
#define PRELE(p) (--(p)->p_holdcnt)
+/*
+ * Flags to fork1().
+ */
+#define FORK_FORK 0x00000001
+#define FORK_VFORK 0x00000002
+#define FORK_RFORK 0x00000004
+#define FORK_PPWAIT 0x00000008
+#define FORK_SHAREFILES 0x00000010
+#define FORK_CLEANFILES 0x00000020
+#define FORK_NOZOMBIE 0x00000040
+#define FORK_SHAREVM 0x00000080
+
#define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
extern u_long pidhash;
@@ -333,10 +345,7 @@ int tsleep __P((void *chan, int pri, char *wmesg, int timo));
void unsleep __P((struct proc *));
void wakeup __P((void *chan));
void exit1 __P((struct proc *, int));
-int fork1 __P((struct proc *, int, int, void *, size_t, register_t *));
-#define ISFORK 0
-#define ISVFORK 1
-#define ISRFORK 2
+int fork1 __P((struct proc *, int, void *, size_t, register_t *));
void kmeminit __P((void));
void rqinit __P((void));
int groupmember __P((gid_t, struct ucred *));