summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-02-23 18:49:25 +0000
committerpeter <peter@FreeBSD.org>1996-02-23 18:49:25 +0000
commit5239b23b5dd3a758a93e0c2186e188e829e7ba19 (patch)
tree8062bc6b4973f0a1762ce55c879b8c3019d7662e /sys/kern
parent834adf89dc86160b3de01b8991acc8ec96028a47 (diff)
downloadFreeBSD-src-5239b23b5dd3a758a93e0c2186e188e829e7ba19.zip
FreeBSD-src-5239b23b5dd3a758a93e0c2186e188e829e7ba19.tar.gz
kern_descrip.c: add fdshare()/fdcopy()
kern_fork.c: add the tiny bit of code for rfork operation. kern/sysv_*: shmfork() takes one less arg, it was never used. sys/shm.h: drop "isvfork" arg from shmfork() prototype sys/param.h: declare rfork args.. (this is where OpenBSD put it..) sys/filedesc.h: protos for fdshare/fdcopy. vm/vm_mmap.c: add minherit code, add rounding to mmap() type args where it makes sense. vm/*: drop unused isvfork arg. Note: this rfork() implementation copies the address space mappings, it does not connect the mappings together. ie: once the two processes have split, the pages may be shared, but the address space is not. If one does a mmap() etc, it does not appear in the other. This makes it not useful for pthreads, but it is useful in it's own right for having light-weight threads in a static shared address space. Obtained from: Original by Ron Minnich, extended by OpenBSD
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_descrip.c46
-rw-r--r--sys/kern/kern_fork.c73
-rw-r--r--sys/kern/sysv_ipc.c5
-rw-r--r--sys/kern/sysv_shm.c5
4 files changed, 110 insertions, 19 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index d214f0d..8dc24d7 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
- * $Id: kern_descrip.c,v 1.24 1996/01/28 23:41:39 dyson Exp $
+ * $Id: kern_descrip.c,v 1.25 1996/02/04 19:56:34 dyson Exp $
*/
#include <sys/param.h>
@@ -82,6 +82,7 @@ static int finishdup(struct filedesc *fdp, int old, int new, int *retval);
*/
struct file *filehead; /* head of list of open files */
int nfiles; /* actual number of open files */
+extern int cmask;
/*
* System calls on descriptors.
@@ -701,6 +702,49 @@ ffree(fp)
}
/*
+ * Build a new filedesc structure.
+ */
+struct filedesc *
+fdinit(p)
+ struct proc *p;
+{
+ register struct filedesc0 *newfdp;
+ register struct filedesc *fdp = p->p_fd;
+
+ MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
+ M_FILEDESC, M_WAITOK);
+ bzero(newfdp, sizeof(struct filedesc0));
+ newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
+ VREF(newfdp->fd_fd.fd_cdir);
+ newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
+ if (newfdp->fd_fd.fd_rdir)
+ VREF(newfdp->fd_fd.fd_rdir);
+
+ /* Create the file descriptor table. */
+ newfdp->fd_fd.fd_refcnt = 1;
+ newfdp->fd_fd.fd_cmask = cmask;
+ newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
+ newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
+ newfdp->fd_fd.fd_nfiles = NDFILE;
+
+ newfdp->fd_fd.fd_freefile = 0;
+ newfdp->fd_fd.fd_lastfile = 0;
+
+ return (&newfdp->fd_fd);
+}
+
+/*
+ * Share a filedesc structure.
+ */
+struct filedesc *
+fdshare(p)
+ struct proc *p;
+{
+ p->p_fd->fd_refcnt++;
+ return (p->p_fd);
+}
+
+/*
* Copy a filedesc structure.
*/
struct filedesc *
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index d73ff1a..dbb56c4 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
- * $Id: kern_fork.c,v 1.15 1995/12/07 12:46:42 davidg Exp $
+ * $Id: kern_fork.c,v 1.16 1996/01/03 21:42:02 wollman Exp $
*/
#include "opt_ktrace.h"
@@ -56,9 +56,17 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
#include <vm/vm_extern.h>
+#include <vm/vm_inherit.h>
-static int fork1(struct proc *, int, int *);
+static int fork1(struct proc *p, int forktype, int rforkflags, int *retval);
+
+#define ISFORK 0
+#define ISVFORK 1
+#define ISRFORK 2
#ifndef _SYS_SYSPROTO_H_
struct fork_args {
@@ -73,27 +81,38 @@ fork(p, uap, retval)
struct fork_args *uap;
int retval[];
{
-
- return (fork1(p, 0, retval));
+ return (fork1(p, ISFORK, 0, retval));
}
/* ARGSUSED */
int
vfork(p, uap, retval)
struct proc *p;
- struct fork_args *uap;
+ struct vfork_args *uap;
int retval[];
{
+ return (fork1(p, ISVFORK, 0, retval));
+}
- return (fork1(p, 1, retval));
+/* ARGSUSED */
+int
+rfork(p, uap, retval)
+ struct proc *p;
+ struct rfork_args *uap;
+ int retval[];
+{
+ return (fork1(p, ISRFORK, uap->flags, retval));
}
+
int nprocs = 1; /* process 0 */
static int
-fork1(p1, isvfork, retval)
+fork1(p1, forktype, rforkflags, retval)
register struct proc *p1;
- int isvfork, retval[];
+ int forktype;
+ int rforkflags;
+ int retval[];
{
register struct proc *p2;
register uid_t uid;
@@ -101,6 +120,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
@@ -235,7 +269,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.
@@ -251,7 +291,7 @@ 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;
p2->p_pgrpnxt = p1->p_pgrpnxt;
p1->p_pgrpnxt = p2;
@@ -284,6 +324,15 @@ again:
p1->p_flag |= P_NOSWAP;
/*
+ * share as much address space as possible
+ */
+ if (forktype == ISRFORK && (rforkflags & RFMEM)) {
+ (void) vm_map_inherit(&p1->p_vmspace->vm_map,
+ VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS - MAXSSIZ,
+ VM_INHERIT_SHARE);
+ }
+
+ /*
* 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].
@@ -293,7 +342,7 @@ again:
*/
retval[0] = p1->p_pid;
retval[1] = 1;
- if (vm_fork(p1, p2, isvfork)) {
+ if (vm_fork(p1, p2)) {
/*
* Child process. Set start time and get to work.
*/
@@ -321,7 +370,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/sysv_ipc.c b/sys/kern/sysv_ipc.c
index bd7c0c8..e62068e 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -1,4 +1,4 @@
-/* $Id: sysv_ipc.c,v 1.2 1996/01/05 16:37:52 wollman Exp $ */
+/* $Id: sysv_ipc.c,v 1.3 1996/01/08 04:30:48 peter Exp $ */
/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */
/*
@@ -278,9 +278,8 @@ shmsys(p, uap, retval)
/* called from kern_fork.c */
void
-shmfork(p1, p2, isvfork)
+shmfork(p1, p2)
struct proc *p1, *p2;
- int isvfork;
{
return;
}
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 72c8a22..a68f8a6 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -1,4 +1,4 @@
-/* $Id: sysv_shm.c,v 1.16 1995/12/26 16:03:32 joerg Exp $ */
+/* $Id: sysv_shm.c,v 1.17 1996/01/05 16:38:03 wollman Exp $ */
/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */
/*
@@ -565,9 +565,8 @@ shmsys(p, uap, retval)
}
void
-shmfork(p1, p2, isvfork)
+shmfork(p1, p2)
struct proc *p1, *p2;
- int isvfork;
{
struct shmmap_state *shmmap_s;
size_t size;
OpenPOWER on IntegriCloud