summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/i386/trap.c27
-rw-r--r--sys/compat/linux/files.linux3
-rw-r--r--sys/compat/linux/linux_dummy.c10
-rw-r--r--sys/compat/linux/linux_misc.c28
-rw-r--r--sys/compat/linux/linux_misc.h58
-rw-r--r--sys/compat/linux/linux_sched.c321
-rw-r--r--sys/compat/linux/linux_sched.h66
-rw-r--r--sys/compat/linux/linux_signal.c18
-rw-r--r--sys/compat/linux/syscalls.master19
-rw-r--r--sys/kern/init_main.c12
-rw-r--r--sys/kern/kern_exit.c27
-rw-r--r--sys/kern/kern_fork.c24
-rw-r--r--sys/kern/kern_kthread.c10
-rw-r--r--sys/kern/kern_sig.c81
-rw-r--r--sys/sys/proc.h9
-rw-r--r--sys/sys/signalvar.h10
-rw-r--r--sys/sys/user.h8
-rw-r--r--sys/sys/wait.h5
-rw-r--r--sys/uvm/uvm_glue.c9
-rw-r--r--sys/vm/vm_glue.c10
20 files changed, 669 insertions, 86 deletions
diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c
index c89e50ca3a3..7075ed44924 100644
--- a/sys/arch/i386/i386/trap.c
+++ b/sys/arch/i386/i386/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.36 2001/03/22 23:36:51 niklas Exp $ */
+/* $OpenBSD: trap.c,v 1.37 2001/04/02 21:43:10 niklas Exp $ */
/* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */
#undef DEBUG
@@ -479,8 +479,16 @@ trap(frame)
&& map != kernel_map) {
nss = clrnd(btoc(USRSTACK-(unsigned)va));
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
- rv = KERN_FAILURE;
- goto nogo;
+ /*
+ * We used to fail here. However, it may
+ * just have been an mmap()ed page low
+ * in the stack, which is legal. If it
+ * wasn't, uvm_fault() will fail below.
+ *
+ * Set nss to 0, since this case is not
+ * a "stack extension".
+ */
+ nss = 0;
}
}
@@ -518,7 +526,9 @@ trap(frame)
goto out;
}
+#ifndef PMAP_NEW
nogo:
+#endif
if (type == T_PAGEFLT) {
if (pcb->pcb_onfault != 0)
goto copyfault;
@@ -609,7 +619,7 @@ trapwrite(addr)
if ((caddr_t)va >= vm->vm_maxsaddr) {
nss = clrnd(btoc(USRSTACK-(unsigned)va));
if (nss > btoc(p->p_rlimit[RLIMIT_STACK].rlim_cur))
- return 1;
+ nss = 0;
}
#if defined(UVM)
@@ -641,7 +651,7 @@ syscall(frame)
register caddr_t params;
register struct sysent *callp;
register struct proc *p;
- int error, opc, nsys;
+ int orig_error, error, opc, nsys;
size_t argsize;
register_t code, args[8], rval[2];
u_quad_t sticks;
@@ -755,6 +765,7 @@ syscall(frame)
error = copyin(params, (caddr_t)args, argsize);
else
error = 0;
+ orig_error = error;
#ifdef SYSCALL_DEBUG
scdebug_call(p, code, args);
#endif
@@ -766,7 +777,7 @@ syscall(frame)
goto bad;
rval[0] = 0;
rval[1] = frame.tf_edx;
- error = (*callp->sy_call)(p, args, rval);
+ orig_error = error = (*callp->sy_call)(p, args, rval);
switch (error) {
case 0:
/*
@@ -799,12 +810,12 @@ syscall(frame)
}
#ifdef SYSCALL_DEBUG
- scdebug_ret(p, code, error, rval);
+ scdebug_ret(p, code, orig_error, rval);
#endif
userret(p, frame.tf_eip, sticks);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p, code, error, rval[0]);
+ ktrsysret(p, code, orig_error, rval[0]);
#endif
}
diff --git a/sys/compat/linux/files.linux b/sys/compat/linux/files.linux
index b7ab1852dd2..407c37545fe 100644
--- a/sys/compat/linux/files.linux
+++ b/sys/compat/linux/files.linux
@@ -1,4 +1,4 @@
-# $OpenBSD: files.linux,v 1.11 2000/12/22 07:34:01 jasoni Exp $
+# $OpenBSD: files.linux,v 1.12 2001/04/02 21:43:11 niklas Exp $
# $NetBSD: files.linux,v 1.4 1996/03/08 04:55:59 mycroft Exp $
#
# Config.new file description for machine-independent Linux compat code.
@@ -18,6 +18,7 @@ file compat/linux/linux_ipc.c compat_linux
file compat/linux/linux_misc.c compat_linux
file compat/linux/linux_mount.c compat_linux
file compat/linux/linux_resource.c compat_linux
+file compat/linux/linux_sched.c compat_linux
file compat/linux/linux_signal.c compat_linux
file compat/linux/linux_socket.c compat_linux
file compat/linux/linux_syscalls.c compat_linux & syscall_debug
diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index e4b66d15a5e..99752dd80ed 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_dummy.c,v 1.3 2001/01/29 07:23:54 jasoni Exp $ */
+/* $OpenBSD: linux_dummy.c,v 1.4 2001/04/02 21:43:11 niklas Exp $ */
/*-
* Copyright (c) 1994-1995 Søren Schmidt
@@ -80,7 +80,6 @@ DUMMY(idle); /* #112 */
DUMMY(vm86old); /* #113 */
DUMMY(swapoff); /* #115 */
DUMMY(sysinfo); /* #116 */
-DUMMY(clone); /* #120 */
#ifndef __i386__
DUMMY(modify_ldt); /* #123 */
#endif
@@ -95,13 +94,6 @@ DUMMY(sysfs); /* #135 */
DUMMY(afs_syscall); /* #137 */
DUMMY(mlockall); /* #152 */
DUMMY(munlockall); /* #153 */
-DUMMY(sched_setparam); /* #154 */
-DUMMY(sched_getparam); /* #155 */
-DUMMY(sched_setscheduler); /* #156 */
-DUMMY(sched_getscheduler); /* #157 */
-DUMMY(sched_yield); /* #158 */
-DUMMY(sched_get_priority_max); /* #159 */
-DUMMY(sched_get_priority_min); /* #160 */
DUMMY(sched_rr_get_interval); /* #161 */
DUMMY(vm86); /* #166 */
DUMMY(query_module); /* #167 */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index a4e73229cc5..30262a7c8b0 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_misc.c,v 1.34 2001/01/23 05:48:05 csapuntz Exp $ */
+/* $OpenBSD: linux_misc.c,v 1.35 2001/04/02 21:43:11 niklas Exp $ */
/* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */
/*
@@ -71,7 +71,9 @@
#include <compat/linux/linux_types.h>
#include <compat/linux/linux_fcntl.h>
+#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_mmap.h>
+#include <compat/linux/linux_sched.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_syscallargs.h>
#include <compat/linux/linux_util.h>
@@ -80,17 +82,16 @@
#include <compat/common/compat_dir.h>
/* linux_misc.c */
-static void bsd_to_linux_wstat __P((int *));
static void bsd_to_linux_statfs __P((struct statfs *, struct linux_statfs *));
-int linux_select1 __P((struct proc *, register_t *, int, fd_set *, fd_set *,
- fd_set *, struct timeval *));
+int linux_select1 __P((struct proc *, register_t *, int, fd_set *,
+ fd_set *, fd_set *, struct timeval *));
/*
* The information on a terminated (or stopped) process needs
* to be converted in order for Linux binaries to get a valid signal
* number out of it.
*/
-static void
+void
bsd_to_linux_wstat(status)
int *status;
{
@@ -166,7 +167,7 @@ linux_sys_wait4(p, v, retval)
syscallarg(struct rusage *) rusage;
} */ *uap = v;
struct sys_wait4_args w4a;
- int error, *status, tstat;
+ int error, *status, tstat, linux_options, options;
caddr_t sg;
if (SCARG(uap, status) != NULL) {
@@ -175,9 +176,22 @@ linux_sys_wait4(p, v, retval)
} else
status = NULL;
+ linux_options = SCARG(uap, options);
+ options = 0;
+ if (linux_options &
+ ~(LINUX_WAIT4_WNOHANG|LINUX_WAIT4_WUNTRACED|LINUX_WAIT4_WCLONE))
+ return (EINVAL);
+
+ if (linux_options & LINUX_WAIT4_WNOHANG)
+ options |= WNOHANG;
+ if (linux_options & LINUX_WAIT4_WUNTRACED)
+ options |= WUNTRACED;
+ if (linux_options & LINUX_WAIT4_WCLONE)
+ options |= WALTSIG;
+
SCARG(&w4a, pid) = SCARG(uap, pid);
SCARG(&w4a, status) = status;
- SCARG(&w4a, options) = SCARG(uap, options);
+ SCARG(&w4a, options) = options;
SCARG(&w4a, rusage) = SCARG(uap, rusage);
if ((error = sys_wait4(p, &w4a, retval)))
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
new file mode 100644
index 00000000000..095d6769e6a
--- /dev/null
+++ b/sys/compat/linux/linux_misc.h
@@ -0,0 +1,58 @@
+/* $OpenBSD: linux_misc.h,v 1.1 2001/04/02 21:43:11 niklas Exp $ */
+/* $NetBSD: linux_misc.h,v 1.3 1999/05/13 00:31:57 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Eric Haszlakiewicz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_MISC_H
+#define _LINUX_MISC_H
+
+/*
+ * Options passed to the Linux wait4() system call.
+ */
+#define LINUX_WAIT4_WNOHANG 0x00000001
+#define LINUX_WAIT4_WUNTRACED 0x00000002
+#define LINUX_WAIT4_WCLONE 0x80000000
+
+#ifdef _KERNEL
+__BEGIN_DECLS
+void bsd_to_linux_wstat __P((int *));
+int linux_select1 __P((struct proc *, register_t *, int, fd_set *, fd_set *,
+ fd_set *, struct timeval *));
+__END_DECLS
+#endif /* !_KERNEL */
+
+#endif /* !_LINUX_MISC_H */
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c
new file mode 100644
index 00000000000..bb34ad0c322
--- /dev/null
+++ b/sys/compat/linux/linux_sched.c
@@ -0,0 +1,321 @@
+/* $OpenBSD: linux_sched.c,v 1.1 2001/04/02 21:43:11 niklas Exp $ */
+/* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center; by Matthias Scheler.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Linux compatibility module. Try to deal with scheduler related syscalls.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/syscallargs.h>
+
+#include <machine/cpu.h>
+
+#include <compat/linux/linux_types.h>
+#include <compat/linux/linux_sched.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_syscallargs.h>
+
+int
+linux_sys_clone(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_clone_args /* {
+ syscallarg(int) flags;
+ syscallarg(void *) stack;
+ } */ *uap = v;
+ int flags = FORK_RFORK, sig;
+
+ /*
+ * We don't support the Linux CLONE_PID or CLONE_PTRACE flags.
+ */
+ if (SCARG(uap, flags) & (LINUX_CLONE_PID | LINUX_CLONE_PTRACE))
+ return (EINVAL);
+
+ if (SCARG(uap, flags) & LINUX_CLONE_VM)
+ flags |= FORK_SHAREVM;
+ /* XXX We pretend to support CLONE_FS for the moment. */
+ if (SCARG(uap, flags) & LINUX_CLONE_FILES)
+ flags |= FORK_SHAREFILES;
+ if (SCARG(uap, flags) & LINUX_CLONE_SIGHAND)
+ flags |= FORK_SIGHAND;
+ if (SCARG(uap, flags) & LINUX_CLONE_VFORK) {
+ flags |= FORK_PPWAIT;
+ }
+
+ sig = SCARG(uap, flags) & LINUX_CLONE_CSIGNAL;
+ if (sig < 0 || sig >= LINUX__NSIG)
+ return (EINVAL);
+ sig = linux_to_bsd_sig[sig];
+
+ /*
+ * Note that Linux does not provide a portable way of specifying
+ * the stack area; the caller must know if the stack grows up
+ * or down. So, we pass a stack size of 0, so that the code
+ * that makes this adjustment is a noop.
+ */
+ return (fork1(p, sig, flags, SCARG(uap, stack), 0, retval));
+}
+
+int
+linux_sys_sched_setparam(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_setparam_args /* {
+ syscallarg(linux_pid_t) pid;
+ syscallarg(const struct linux_sched_param *) sp;
+ } */ *uap = v;
+ int error;
+ struct linux_sched_param lp;
+ struct proc *p;
+
+ /*
+ * We only check for valid parameters and return afterwards.
+ */
+
+ if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
+ return (EINVAL);
+
+ error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
+ if (error)
+ return (error);
+
+ if (SCARG(uap, pid) != 0) {
+ struct pcred *pc = cp->p_cred;
+
+ if ((p = pfind(SCARG(uap, pid))) == NULL)
+ return (ESRCH);
+ if (!(cp == p ||
+ pc->pc_ucred->cr_uid == 0 ||
+ pc->p_ruid == p->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
+ pc->p_ruid == p->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
+ return (EPERM);
+ }
+
+ return (0);
+}
+
+int
+linux_sys_sched_getparam(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_getparam_args /* {
+ syscallarg(linux_pid_t) pid;
+ syscallarg(struct linux_sched_param *) sp;
+ } */ *uap = v;
+ struct proc *p;
+ struct linux_sched_param lp;
+
+ /*
+ * We only check for valid parameters and return a dummy priority
+ * afterwards.
+ */
+ if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
+ return (EINVAL);
+
+ if (SCARG(uap, pid) != 0) {
+ struct pcred *pc = cp->p_cred;
+
+ if ((p = pfind(SCARG(uap, pid))) == NULL)
+ return (ESRCH);
+ if (!(cp == p ||
+ pc->pc_ucred->cr_uid == 0 ||
+ pc->p_ruid == p->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
+ pc->p_ruid == p->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
+ return (EPERM);
+ }
+
+ lp.sched_priority = 0;
+ return (copyout(&lp, SCARG(uap, sp), sizeof lp));
+}
+
+int
+linux_sys_sched_setscheduler(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_setscheduler_args /* {
+ syscallarg(linux_pid_t) pid;
+ syscallarg(int) policy;
+ syscallarg(cont struct linux_sched_scheduler *) sp;
+ } */ *uap = v;
+ int error;
+ struct linux_sched_param lp;
+ struct proc *p;
+
+ /*
+ * We only check for valid parameters and return afterwards.
+ */
+
+ if (SCARG(uap, pid) < 0 || SCARG(uap, sp) == NULL)
+ return (EINVAL);
+
+ error = copyin(SCARG(uap, sp), &lp, sizeof(lp));
+ if (error)
+ return (error);
+
+ if (SCARG(uap, pid) != 0) {
+ struct pcred *pc = cp->p_cred;
+
+ if ((p = pfind(SCARG(uap, pid))) == NULL)
+ return (ESRCH);
+ if (!(cp == p ||
+ pc->pc_ucred->cr_uid == 0 ||
+ pc->p_ruid == p->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
+ pc->p_ruid == p->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
+ return (EPERM);
+ }
+
+ /*
+ * We can't emulate anything put the default scheduling policy.
+ */
+ if (SCARG(uap, policy) != LINUX_SCHED_OTHER || lp.sched_priority != 0)
+ return (EINVAL);
+
+ return (0);
+}
+
+int
+linux_sys_sched_getscheduler(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_getscheduler_args /* {
+ syscallarg(linux_pid_t) pid;
+ } */ *uap = v;
+ struct proc *p;
+
+ *retval = -1;
+
+ /*
+ * We only check for valid parameters and return afterwards.
+ */
+
+ if (SCARG(uap, pid) != 0) {
+ struct pcred *pc = cp->p_cred;
+
+ if ((p = pfind(SCARG(uap, pid))) == NULL)
+ return (ESRCH);
+ if (!(cp == p ||
+ pc->pc_ucred->cr_uid == 0 ||
+ pc->p_ruid == p->p_cred->p_ruid ||
+ pc->pc_ucred->cr_uid == p->p_cred->p_ruid ||
+ pc->p_ruid == p->p_ucred->cr_uid ||
+ pc->pc_ucred->cr_uid == p->p_ucred->cr_uid))
+ return (EPERM);
+ }
+
+ /*
+ * We can't emulate anything put the default scheduling policy.
+ */
+ *retval = LINUX_SCHED_OTHER;
+ return (0);
+}
+
+int
+linux_sys_sched_yield(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ need_resched();
+ return (0);
+}
+
+int
+linux_sys_sched_get_priority_max(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_get_priority_max_args /* {
+ syscallarg(int) policy;
+ } */ *uap = v;
+
+ /*
+ * We can't emulate anything put the default scheduling policy.
+ */
+ if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
+ *retval = -1;
+ return (EINVAL);
+ }
+
+ *retval = 0;
+ return (0);
+}
+
+int
+linux_sys_sched_get_priority_min(cp, v, retval)
+ struct proc *cp;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sched_get_priority_min_args /* {
+ syscallarg(int) policy;
+ } */ *uap = v;
+
+ /*
+ * We can't emulate anything put the default scheduling policy.
+ */
+ if (SCARG(uap, policy) != LINUX_SCHED_OTHER) {
+ *retval = -1;
+ return (EINVAL);
+ }
+
+ *retval = 0;
+ return (0);
+}
diff --git a/sys/compat/linux/linux_sched.h b/sys/compat/linux/linux_sched.h
new file mode 100644
index 00000000000..64007452a8d
--- /dev/null
+++ b/sys/compat/linux/linux_sched.h
@@ -0,0 +1,66 @@
+/* $OpenBSD: linux_sched.h,v 1.1 2001/04/02 21:43:11 niklas Exp $ */
+/* $NetBSD: linux_sched.h,v 1.1 1999/05/12 19:49:09 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LINUX_SCHED_H
+#define _LINUX_SCHED_H
+
+/*
+ * Flags passed to the Linux __clone(2) system call.
+ */
+#define LINUX_CLONE_CSIGNAL 0x000000ff /* signal to be sent at exit */
+#define LINUX_CLONE_VM 0x00000100 /* share address space */
+#define LINUX_CLONE_FS 0x00000200 /* share "file system" info */
+#define LINUX_CLONE_FILES 0x00000400 /* share file descriptors */
+#define LINUX_CLONE_SIGHAND 0x00000800 /* share signal actions */
+#define LINUX_CLONE_PID 0x00001000 /* share process ID */
+#define LINUX_CLONE_PTRACE 0x00002000 /* ptrace(2) continues on
+ child */
+#define LINUX_CLONE_VFORK 0x00004000 /* parent blocks until child
+ exits */
+
+struct linux_sched_param {
+ int sched_priority;
+};
+
+#define LINUX_SCHED_OTHER 0
+#define LINUX_SCHED_FIFO 1
+#define LINUX_SCHED_RR 2
+
+#endif /* _LINUX_SCHED_H */
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 6b1e78fb400..f6a1e856a92 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_signal.c,v 1.7 2000/06/07 14:11:38 niklas Exp $ */
+/* $OpenBSD: linux_signal.c,v 1.8 2001/04/02 21:43:11 niklas Exp $ */
/* $NetBSD: linux_signal.c,v 1.10 1996/04/04 23:51:36 christos Exp $ */
/*
@@ -73,12 +73,12 @@ int bsd_to_linux_sig[NSIG] = {
LINUX_SIGILL,
LINUX_SIGTRAP,
LINUX_SIGABRT,
- 0, /* SIGEMT */
+ LINUX_NSIG, /* XXX Kludge to get RT signal #32 to work */
LINUX_SIGFPE,
LINUX_SIGKILL,
LINUX_SIGBUS,
LINUX_SIGSEGV,
- 0, /* SIGSYS */
+ LINUX_NSIG + 1, /* XXX Kludge to get RT signal #32 to work */
LINUX_SIGPIPE,
LINUX_SIGALRM,
LINUX_SIGTERM,
@@ -133,8 +133,8 @@ int linux_to_bsd_sig[LINUX__NSIG] = {
SIGIO,
0, /* SIGUNUSED */
0,
- 0,
- 0,
+ SIGEMT, /* XXX Gruesome hack for linuxthreads: */
+ SIGSYS, /* Map 1st 2 RT signals onto ones we handle. */
0,
0,
0,
@@ -373,7 +373,7 @@ linux_sys_sigaction(p, v, retval)
caddr_t sg;
int error;
- if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX_NSIG)
+ if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
return (EINVAL);
sg = stackgap_init(p->p_emul);
@@ -434,7 +434,7 @@ linux_sys_rt_sigaction(p, v, retval)
if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
return (EINVAL);
- if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX_NSIG)
+ if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
return (EINVAL);
sg = stackgap_init(p->p_emul);
@@ -496,7 +496,7 @@ linux_sys_signal(p, v, retval)
struct sigaction *osa, *nsa, tmpsa;
int error;
- if (SCARG(uap, sig) < 0 || SCARG(uap, sig) >= LINUX_NSIG)
+ if (SCARG(uap, sig) < 0 || SCARG(uap, sig) >= LINUX__NSIG)
return (EINVAL);
sg = stackgap_init(p->p_emul);
@@ -855,7 +855,7 @@ linux_sys_kill(p, v, retval)
struct sys_kill_args ka;
SCARG(&ka, pid) = SCARG(uap, pid);
- if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX_NSIG)
+ if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
return (EINVAL);
SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
return (sys_kill(p, &ka, retval));
diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master
index 20831cf90f2..9097fbcb330 100644
--- a/sys/compat/linux/syscalls.master
+++ b/sys/compat/linux/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.27 2001/01/29 07:23:54 jasoni Exp $
+ $OpenBSD: syscalls.master,v 1.28 2001/04/02 21:43:11 niklas Exp $
; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -200,7 +200,7 @@
caddr_t ptr); }
118 NOARGS { int sys_fsync(int fd); }
119 STD { int linux_sys_sigreturn(struct linux_sigcontext *scp); }
-120 STD { int linux_sys_clone(void); }
+120 STD { int linux_sys_clone(int flags, void *stack); }
121 NOARGS { int compat_09_sys_setdomainname(char *name, \
int len); }
122 STD { int linux_sys_uname(struct linux_utsname *up); }
@@ -247,13 +247,16 @@
151 NOARGS { int sys_munlock(caddr_t addr, size_t len); }
152 STD { int linux_sys_mlockall(void); }
153 STD { int linux_sys_munlockall(void); }
-154 STD { int linux_sys_sched_setparam(void); }
-155 STD { int linux_sys_sched_getparam(void); }
-156 STD { int linux_sys_sched_setscheduler(void); }
-157 STD { int linux_sys_sched_getscheduler(void); }
+154 STD { int linux_sys_sched_setparam(linux_pid_t pid, \
+ const struct linux_sched_param *sp); }
+155 STD { int linux_sys_sched_getparam(linux_pid_t pid, \
+ struct linux_sched_param *sp); }
+156 STD { int linux_sys_sched_setscheduler(linux_pid_t pid, \
+ int policy, const struct linux_sched_param *sp); }
+157 STD { int linux_sys_sched_getscheduler(linux_pid_t pid); }
158 STD { int linux_sys_sched_yield(void); }
-159 STD { int linux_sys_sched_get_priority_max(void); }
-160 STD { int linux_sys_sched_get_priority_min(void); }
+159 STD { int linux_sys_sched_get_priority_max(int policy); }
+160 STD { int linux_sys_sched_get_priority_min(int policy); }
161 STD { int linux_sys_sched_rr_get_interval(void); }
162 NOARGS { int sys_nanosleep(const struct timespec *rqtp, \
struct timespec *rmtp); }
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 11ed4f6511e..7b53d5d6a43 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.60 2001/03/16 15:49:05 art Exp $ */
+/* $OpenBSD: init_main.c,v 1.61 2001/04/02 21:43:11 niklas Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -118,6 +118,7 @@ struct pcred cred0;
struct filedesc0 filedesc0;
struct plimit limit0;
struct vmspace vmspace0;
+struct sigacts sigacts0;
#ifndef curproc
struct proc *curproc;
#endif
@@ -305,11 +306,10 @@ main(framep)
p->p_addr = proc0paddr; /* XXX */
/*
- * We continue to place resource usage info and signal
- * actions in the user struct so they're pageable.
+ * We continue to place resource usage info in the
+ * user struct so they're pageable.
*/
p->p_stats = &p->p_addr->u_stats;
- p->p_sigacts = &p->p_addr->u_sigacts;
/*
* Charge root for one process.
@@ -416,10 +416,12 @@ main(framep)
p->p_rtime.tv_sec = p->p_rtime.tv_usec = 0;
/* Initialize signal state for process 0. */
+ signal_init();
+ p->p_sigacts = &sigacts0;
siginit(p);
/* Create process 1 (init(8)). */
- if (fork1(p, FORK_FORK, NULL, 0, rval))
+ if (fork1(p, SIGCHLD, 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_exit.c b/sys/kern/kern_exit.c
index 575394f72ae..bbe76ff7bc7 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.29 2001/03/23 18:42:06 art Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.30 2001/04/02 21:43:11 niklas Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -286,6 +286,10 @@ exit1(p, rv)
wakeup((caddr_t)pp);
}
+ if ((p->p_flag & P_FSTRACE) == 0 && p->p_exitsig != 0)
+ psignal(p->p_pptr, P_EXITSIG(p));
+ wakeup((caddr_t)p->p_pptr);
+
/*
* Notify procfs debugger
*/
@@ -293,6 +297,11 @@ exit1(p, rv)
wakeup((caddr_t)p);
/*
+ * Release the process's signal state.
+ */
+ sigactsfree(p);
+
+ /*
* Clear curproc after we've done all operations
* that could block, and before tearing down the rest
* of the process state that might be used from clock, etc.
@@ -433,6 +442,16 @@ loop:
p->p_pid != SCARG(uap, pid) &&
p->p_pgid != -SCARG(uap, pid)))
continue;
+
+ /*
+ * Wait for processes with p_exitsig != SIGCHLD processes only
+ * if WALTSIG is set; wait for processes with pexitsig ==
+ * SIGCHLD only if WALTSIG is clear.
+ */
+ if ((SCARG(uap, options) & WALTSIG) ?
+ (p->p_exitsig == SIGCHLD) : (P_EXITSIG(p) != SIGCHLD))
+ continue;
+
nfound++;
if (p->p_stat == SZOMB) {
retval[0] = p->p_pid;
@@ -458,7 +477,8 @@ loop:
if (p->p_oppid && (t = pfind(p->p_oppid))) {
p->p_oppid = 0;
proc_reparent(p, t);
- psignal(t, SIGCHLD);
+ if (p->p_exitsig != 0)
+ psignal(t, P_EXITSIG(p));
wakeup((caddr_t)t);
return (0);
}
@@ -509,6 +529,9 @@ proc_reparent(child, parent)
if (child->p_pptr == parent)
return;
+ if (parent == initproc)
+ child->p_exitsig = SIGCHLD;
+
LIST_REMOVE(child, p_sibling);
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 3179f7b07ae..094903ef13e 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.38 2001/03/23 18:42:06 art Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.39 2001/04/02 21:43:11 niklas Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -50,6 +50,7 @@
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <sys/file.h>
#include <sys/acct.h>
@@ -81,7 +82,7 @@ sys_fork(p, v, retval)
void *v;
register_t *retval;
{
- return (fork1(p, FORK_FORK, NULL, 0, retval));
+ return (fork1(p, SIGCHLD, FORK_FORK, NULL, 0, retval));
}
/*ARGSUSED*/
@@ -91,7 +92,7 @@ sys_vfork(p, v, retval)
void *v;
register_t *retval;
{
- return (fork1(p, FORK_VFORK|FORK_PPWAIT, NULL, 0, retval));
+ return (fork1(p, SIGCHLD, FORK_VFORK|FORK_PPWAIT, NULL, 0, retval));
}
int
@@ -103,6 +104,7 @@ sys_rfork(p, v, retval)
struct sys_rfork_args /* {
syscallarg(int) flags;
} */ *uap = v;
+
int rforkflags;
int flags;
@@ -131,12 +133,13 @@ sys_rfork(p, v, retval)
if (rforkflags & RFMEM)
flags |= FORK_VMNOSTACK;
- return (fork1(p, flags, NULL, 0, retval));
+ return (fork1(p, SIGCHLD, flags, NULL, 0, retval));
}
int
-fork1(p1, flags, stack, stacksize, retval)
+fork1(p1, exitsig, flags, stack, stacksize, retval)
register struct proc *p1;
+ int exitsig;
int flags;
void *stack;
size_t stacksize;
@@ -246,6 +249,7 @@ again:
p2 = newproc;
p2->p_stat = SIDL; /* protect against others */
p2->p_pid = lastpid;
+ p2->p_exitsig = exitsig;
LIST_INSERT_HEAD(&allproc, p2, p_list);
p2->p_forw = p2->p_back = NULL; /* shouldn't be necessary */
LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
@@ -338,6 +342,14 @@ again:
scheduler_fork_hook(p1, p2);
/*
+ * Create signal actions for the child process.
+ */
+ if (flags & FORK_SIGHAND)
+ sigactsshare(p1, p2);
+ else
+ p2->p_sigacts = sigactsinit(p1);
+
+ /*
* This begins the section where we must prevent the parent
* from being swapped.
*/
@@ -382,7 +394,7 @@ again:
*/
#if defined(UVM)
uvm_fork(p1, p2, ((flags & FORK_SHAREVM) ? TRUE : FALSE), stack,
- stacksize);
+ stacksize);
#else /* UVM */
vm_fork(p1, p2, stack, stacksize);
#endif /* UVM */
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index 9652514957b..c81d2f7386e 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_kthread.c,v 1.10 2000/07/17 16:25:16 deraadt Exp $ */
+/* $OpenBSD: kern_kthread.c,v 1.11 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: kern_kthread.c,v 1.3 1998/12/22 21:21:36 kleink Exp $ */
/*-
@@ -79,14 +79,16 @@ kthread_create(func, arg, newpp, fmt, va_alist)
va_list ap;
/*
- * First, create the new process. Share the memory, copy file
+ * First, create the new process. Share the memory, file
* descriptors and don't leave the exit status around for the
* parent to wait for.
*/
#ifdef UVM
- error = fork1(&proc0, FORK_SHAREVM|FORK_NOZOMBIE, NULL, 0, rv);
+ error = fork1(&proc0, 0,
+ FORK_SHAREVM|FORK_NOZOMBIE|FORK_SIGHAND, NULL, 0, rv);
#else
- error = fork1(&proc0, FORK_VMNOSTACK|FORK_NOZOMBIE, NULL, 0, rv);
+ error = fork1(&proc0, 0,
+ FORK_VMNOSTACK|FORK_NOZOMBIE|FORK_SIGHAND, NULL, 0, rv);
#endif
if (error)
return (error);
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 8dd275ecdb7..fb6239eedb6 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.41 2001/02/19 10:21:48 art Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.42 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -63,6 +63,8 @@
#include <sys/syslog.h>
#include <sys/stat.h>
#include <sys/core.h>
+#include <sys/malloc.h>
+#include <sys/pool.h>
#include <sys/ptrace.h>
#include <sys/mount.h>
@@ -73,9 +75,7 @@
#include <vm/vm.h>
#include <sys/user.h> /* for coredump */
-#if defined(UVM)
#include <uvm/uvm_extern.h>
-#endif
int filt_sigattach(struct knote *kn);
void filt_sigdetach(struct knote *kn);
@@ -88,6 +88,8 @@ void stop __P((struct proc *p));
void killproc __P((struct proc *, char *));
int cansignal __P((struct proc *, struct pcred *, struct proc *, int));
+struct pool sigacts_pool; /* memory pool for sigacts structures */
+
/*
* Can process p, with pcred pc, send the signal signum to process q?
*/
@@ -145,6 +147,79 @@ cansignal(p, pc, q, signum)
}
+/*
+ * Initialize signal-related data structures.
+ */
+void
+signal_init()
+{
+ pool_init(&sigacts_pool, sizeof(struct sigacts), 0, 0, 0, "sigapl",
+ 0, pool_page_alloc_nointr, pool_page_free_nointr, M_SUBPROC);
+}
+
+/*
+ * Create an initial sigacts structure, using the same signal state
+ * as p.
+ */
+struct sigacts *
+sigactsinit(p)
+ struct proc *p;
+{
+ struct sigacts *ps;
+
+ ps = pool_get(&sigacts_pool, PR_WAITOK);
+ memcpy(ps, p->p_sigacts, sizeof(struct sigacts));
+ ps->ps_refcnt = 1;
+ return (ps);
+}
+
+/*
+ * Make p2 share p1's sigacts.
+ */
+void
+sigactsshare(p1, p2)
+ struct proc *p1, *p2;
+{
+
+ p2->p_sigacts = p1->p_sigacts;
+ p1->p_sigacts->ps_refcnt++;
+}
+
+/*
+ * Make this process not share its sigacts, maintaining all
+ * signal state.
+ */
+void
+sigactsunshare(p)
+ struct proc *p;
+{
+ struct sigacts *newps;
+
+ if (p->p_sigacts->ps_refcnt == 1)
+ return;
+
+ newps = sigactsinit(p);
+ sigactsfree(p);
+ p->p_sigacts = newps;
+}
+
+/*
+ * Release a sigacts structure.
+ */
+void
+sigactsfree(p)
+ struct proc *p;
+{
+ struct sigacts *ps = p->p_sigacts;
+
+ if (--ps->ps_refcnt > 0)
+ return;
+
+ p->p_sigacts = NULL;
+
+ pool_put(&sigacts_pool, ps);
+}
+
/* ARGSUSED */
int
sys_sigaction(p, v, retval)
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index c3c8f6b0e45..a1c719f13e5 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.39 2001/03/25 18:09:18 csapuntz Exp $ */
+/* $OpenBSD: proc.h,v 1.40 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -248,6 +248,10 @@ struct proc {
#define P_NOCLDWAIT 0x080000 /* Let pid 1 wait for my children */
#define P_NOZOMBIE 0x100000 /* Pid 1 waits for me instead of dad */
+/* Macro to compute the exit signal to be delivered. */
+#define P_EXITSIG(p) \
+ (((p)->p_flag & (P_TRACED | P_FSTRACE)) ? SIGCHLD : (p)->p_exitsig)
+
/*
* These flags are kept in p_schedflags. p_schedflags may be modified
* only at splstatclock().
@@ -314,6 +318,7 @@ struct pcred {
#define FORK_NOZOMBIE 0x00000040
#define FORK_SHAREVM 0x00000080
#define FORK_VMNOSTACK 0x00000100
+#define FORK_SIGHAND 0x00000200
#define PIDHASH(pid) (&pidhashtbl[(pid) & pidhash])
extern LIST_HEAD(pidhashhead, proc) *pidhashtbl;
@@ -380,7 +385,7 @@ void wakeup __P((void *chan));
void reaper __P((void));
void exit1 __P((struct proc *, int));
void exit2 __P((struct proc *));
-int fork1 __P((struct proc *, int, void *, size_t, register_t *));
+int fork1 __P((struct proc *, int, int, void *, size_t, register_t *));
void kmeminit __P((void));
void rqinit __P((void));
int groupmember __P((gid_t, struct ucred *));
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index 7c60cdd5897..653a5fe9da9 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: signalvar.h,v 1.7 1997/08/31 20:42:01 deraadt Exp $ */
+/* $OpenBSD: signalvar.h,v 1.8 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */
/*
@@ -61,6 +61,7 @@ struct sigacts {
int ps_sig; /* for core dump/debugger XXX */
long ps_code; /* for core dump/debugger XXX */
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
+ int ps_refcnt; /* reference count */
};
/* signal flags */
@@ -168,6 +169,13 @@ void sigexit __P((struct proc *, int));
void setsigvec __P((struct proc *, int, struct sigaction *));
int killpg1 __P((struct proc *, int, int, int));
+void signal_init __P((void));
+
+struct sigacts *sigactsinit __P((struct proc *));
+void sigactsshare __P((struct proc *, struct proc *));
+void sigactsunshare __P((struct proc *));
+void sigactsfree __P((struct proc *));
+
/*
* Machine-dependent functions:
*/
diff --git a/sys/sys/user.h b/sys/sys/user.h
index c4617d5cc48..45eb714501f 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: user.h,v 1.3 1996/04/21 22:32:17 deraadt Exp $ */
+/* $OpenBSD: user.h,v 1.4 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: user.h,v 1.10 1996/04/09 20:55:49 cgd Exp $ */
/*
@@ -46,7 +46,6 @@
#include <sys/uio.h>
#endif
#include <sys/resourcevar.h>
-#include <sys/signalvar.h>
#include <vm/vm.h> /* XXX */
#include <sys/sysctl.h>
@@ -61,7 +60,6 @@
struct user {
struct pcb u_pcb;
- struct sigacts u_sigacts; /* p_sigacts points here (use it!) */
struct pstats u_stats; /* p_stats points here (use it!) */
/*
@@ -81,14 +79,10 @@ struct user {
#define U_tsize u_kproc.kp_eproc.e_vm.vm_tsize
#define U_dsize u_kproc.kp_eproc.e_vm.vm_dsize
#define U_ssize u_kproc.kp_eproc.e_vm.vm_ssize
-#define U_sig u_sigacts.ps_sig
-#define U_code u_sigacts.ps_code
#ifndef _KERNEL
#define u_ar0 U_ar0
#define u_tsize U_tsize
#define u_dsize U_dsize
#define u_ssize U_ssize
-#define u_sig U_sig
-#define u_code U_code
#endif /* _KERNEL */
diff --git a/sys/sys/wait.h b/sys/sys/wait.h
index 44ddd818424..75eeacf658c 100644
--- a/sys/sys/wait.h
+++ b/sys/sys/wait.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wait.h,v 1.5 1996/11/14 20:28:35 etheisen Exp $ */
+/* $OpenBSD: wait.h,v 1.6 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: wait.h,v 1.11 1996/04/09 20:55:51 cgd Exp $ */
/*
@@ -81,6 +81,9 @@
*/
#define WNOHANG 1 /* don't hang in wait */
#define WUNTRACED 2 /* tell about stopped, untraced children */
+#ifndef _POSIX_SOURCE
+#define WALTSIG 4 /* wait for child with alternate exit signal */
+#endif
#ifndef _POSIX_SOURCE
/* POSIX extensions and 4.2/4.3 compatability: */
diff --git a/sys/uvm/uvm_glue.c b/sys/uvm/uvm_glue.c
index 26a5276798c..03ff8844e8b 100644
--- a/sys/uvm/uvm_glue.c
+++ b/sys/uvm/uvm_glue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_glue.c,v 1.9 2001/01/29 02:07:44 niklas Exp $ */
+/* $OpenBSD: uvm_glue.c,v 1.10 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: uvm_glue.c,v 1.23 1999/05/28 20:49:51 thorpej Exp $ */
/*
@@ -295,13 +295,10 @@ uvm_fork(p1, p2, shared, stack, stacksize)
panic("uvm_fork: uvm_fault_wire failed: %d", rv);
/*
- * p_stats and p_sigacts currently point at fields in the user
- * struct but not at &u, instead at p_addr. Copy p_sigacts and
- * parts of p_stats; zero the rest of p_stats (statistics).
+ * p_stats currently point at fields in the user struct. Copy
+ * parts of p_stats, and zero out the rest.
*/
p2->p_stats = &up->u_stats;
- p2->p_sigacts = &up->u_sigacts;
- up->u_sigacts = *p1->p_sigacts;
memset(&up->u_stats.pstat_startzero, 0,
(unsigned) ((caddr_t)&up->u_stats.pstat_endzero -
(caddr_t)&up->u_stats.pstat_startzero));
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index f76b5e7316a..431518c8bc5 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm_glue.c,v 1.35 1999/09/03 18:02:27 art Exp $ */
+/* $OpenBSD: vm_glue.c,v 1.36 2001/04/02 21:43:12 niklas Exp $ */
/* $NetBSD: vm_glue.c,v 1.55.4.1 1996/06/13 17:25:45 cgd Exp $ */
/*
@@ -237,14 +237,10 @@ vm_fork(p1, p2, stack, stacksize)
(vm_offset_t)up + USPACE, FALSE);
/*
- * p_stats and p_sigacts currently point at fields
- * in the user struct but not at &u, instead at p_addr.
- * Copy p_sigacts and parts of p_stats; zero the rest
- * of p_stats (statistics).
+ * p_stats currently point at fields in the user struct. Copy
+ * parts of p_stats, and zero out the rest.
*/
p2->p_stats = &up->u_stats;
- p2->p_sigacts = &up->u_sigacts;
- up->u_sigacts = *p1->p_sigacts;
bzero(&up->u_stats.pstat_startzero,
(unsigned) ((caddr_t)&up->u_stats.pstat_endzero -
(caddr_t)&up->u_stats.pstat_startzero));