Reviewed by: Luoqi Chen, Jordan Hubbard

Submitted by:	 "Richard Seaman, Jr." <lists@tar.com>
Obtained from:	linux :-)

Code to allow Linux Threads to run under FreeBSD.

By default not enabled
This code is dependent on the conditional
COMPAT_LINUX_THREADS (suggested by Garret)
This is not yet a 'real' option but will be within some number of hours.
This commit is contained in:
Julian Elischer 1998-12-19 02:55:34 +00:00
parent 02489dd737
commit 6626c6045c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=41931
25 changed files with 638 additions and 45 deletions

View File

@ -36,7 +36,7 @@
static char sccsid[] = "@(#)keyword.c 8.5 (Berkeley) 4/2/94";
#else
static const char rcsid[] =
"$Id: keyword.c,v 1.19 1998/05/25 05:07:17 steve Exp $";
"$Id: keyword.c,v 1.20 1998/09/14 08:32:20 dfr Exp $";
#endif
#endif /* not lint */
@ -157,10 +157,12 @@ VAR var[] = {
{"ruser", "RUSER", NULL, LJUST|DSIZ, runame, s_runame, USERLEN},
{"sess", "SESS", NULL, 0, evar, NULL, 6, EOFF(e_sess), KPTR, "lx"},
{"sig", "PENDING", NULL, 0, pvar, NULL, 8, POFF(p_siglist), INT, "x"},
#ifndef COMPAT_LINUX_THREADS
{"sigcatch", "CAUGHT",
NULL, 0, pvar, NULL, 8, POFF(p_sigcatch), UINT, "x"},
{"sigignore", "IGNORED",
NULL, 0, pvar, NULL, 8, POFF(p_sigignore), UINT, "x"},
#endif /* COMPAT_LINUX_THREADS */
{"sigmask", "BLOCKED",
NULL, 0, pvar, NULL, 8, POFF(p_sigmask), UINT, "x"},
{"sl", "SL", NULL, 0, pvar, NULL, 3, POFF(p_slptime), UINT, "d"},

View File

@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: sigsuspend.S,v 1.6 1997/02/22 14:59:40 peter Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
.asciz "$Id$"
.asciz "$Id: sigsuspend.S,v 1.6 1997/02/22 14:59:40 peter Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@ -50,7 +50,9 @@ err:
#ifdef _THREAD_SAFE
ENTRY(_thread_sys_sigsuspend)
#else
ENTRY(sigsuspend)
ENTRY(_sigsuspend)
.weak CNAME(sigsuspend) ;
.set CNAME(sigsuspend), CNAME(_sigsuspend) ;
#endif
movl 4(%esp),%eax # fetch mask arg
movl (%eax),%eax # indirect to mask arg

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux.h,v 1.23 1998/10/05 16:37:36 jfieber Exp $
* $Id: linux.h,v 1.24 1998/11/12 00:42:08 jkh Exp $
*/
#ifndef _I386_LINUX_LINUX_H_
@ -418,6 +418,7 @@ struct trapframe;
#define LINUX_MAP_PRIVATE 0x0002
#define LINUX_MAP_FIXED 0x0010
#define LINUX_MAP_ANON 0x0020
#define LINUX_MAP_GROWSDOWN 0x0100
/* SystemV ipc defines */
#define LINUX_SEMOP 1

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_dummy.c,v 1.7 1997/10/29 08:17:09 kato Exp $
* $Id: linux_dummy.c,v 1.8 1997/11/06 19:28:52 phk Exp $
*/
#include <sys/param.h>
@ -211,13 +211,6 @@ linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args)
return ENOSYS;
}
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_uname(struct proc *p, struct linux_uname_args *args)
{

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_sysvec.c,v 1.39 1998/12/14 18:54:01 dt Exp $
* $Id: linux_sysvec.c,v 1.40 1998/12/16 16:28:57 bde Exp $
*/
/* XXX we use functions that might not exist. */
@ -50,6 +50,10 @@
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#ifdef COMPAT_LINUX_THREADS
#include <sys/lock.h> /* needed, for now, by vm_map.h */
#include <vm/vm_map.h> /* needed, for now, for VM_STACK defines */
#endif /* COMPAT_LINUX_THREADS */
#include <sys/exec.h>
#include <sys/kernel.h>
#include <sys/module.h>
@ -217,7 +221,24 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
#ifdef COMPAT_LINUX_THREADS
#ifdef USE_VM_STACK
#ifndef USE_VM_STACK_FOR_EXEC
if ((((caddr_t)fp > p->p_vmspace->vm_maxsaddr &&
(caddr_t)fp < (caddr_t)USRSTACK &&
grow(p, (int)fp) == FALSE) ||
(((caddr_t)fp <= p->p_vmspace->vm_maxsaddr ||
(caddr_t)fp >= (caddr_t)USRSTACK) &&
grow_stack (p, (int)fp) == FALSE)) ||
#else
if ((grow_stack (p, (int)fp) == FALSE) ||
#endif
#else
#endif /* COMPAT_LINUX_THREADS */
if ((grow(p, (int)fp) == FALSE) ||
#ifdef COMPAT_LINUX_THREADS
#endif
#endif /* COMPAT_LINUX_THREADS */
(useracc((caddr_t)fp, sizeof (struct linux_sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal

View File

@ -1,4 +1,4 @@
$Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp $
$Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
; System call name/number master file (or rather, slave, from LINUX).
@ -171,7 +171,7 @@
caddr_t ptr); }
118 NOPROTO LINUX { int fsync(int fd); }
119 STD LINUX { int linux_sigreturn(struct linux_sigcontext *scp); }
120 STD LINUX { int linux_clone(void); }
120 STD LINUX { int linux_clone(int flags, void *stack); }
121 NOPROTO LINUX { int setdomainname(char *name, \
int len); }
122 STD LINUX { int linux_newuname(struct linux_newuname_t *buf); }

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_misc.c,v 1.46 1998/12/04 22:54:50 archie Exp $
* $Id: linux_misc.c,v 1.47 1998/12/10 13:47:18 jkh Exp $
*/
#include <sys/param.h>
@ -41,6 +41,9 @@
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#ifdef COMPAT_LINUX_THREADS
#include <sys/unistd.h>
#endif /* COMPAT_LINUX_THREADS */
#include <sys/vnode.h>
#include <sys/wait.h>
#include <sys/time.h>
@ -560,6 +563,84 @@ linux_fork(struct proc *p, struct linux_fork_args *args)
return 0;
}
#ifndef COMPAT_LINUX_THREADS
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
printf("linux_clone(%d): Not enabled\n", p->p_pid);
return (EOPNOTSUPP);
}
#else
#define CLONE_VM 0x100
#define CLONE_FS 0x200
#define CLONE_FILES 0x400
#define CLONE_SIGHAND 0x800
#define CLONE_PID 0x1000
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
int error, ff = RFPROC;
struct proc *p2;
int growable;
int initstacksize;
int maxstacksize;
int exit_signal;
vm_map_entry_t entry;
vm_map_t map;
vm_offset_t start;
struct rfork_args rf_args;
#ifdef SMP
printf("linux_clone(%d): does not work with SMP yet\n", p->p_pid);
return (EOPNOTSUPP);
#endif
#ifdef DEBUG
if (args->flags & CLONE_PID)
printf("linux_clone(%d): CLONE_PID not yet supported\n", p->p_pid);
printf ("linux_clone(%d): invoked with flags %x and stack %x\n", p->p_pid,
(unsigned int)args->flags, (unsigned int)args->stack);
#endif
if (!args->stack)
return (EINVAL);
exit_signal = args->flags & 0x000000ff;
if (exit_signal >= LINUX_NSIG)
return EINVAL;
exit_signal = linux_to_bsd_signal[exit_signal];
/* RFTHREAD probably not necessary here, but it shouldn't hurt either */
ff |= RFTHREAD;
if (args->flags & CLONE_VM)
ff |= RFMEM;
if (args->flags & CLONE_SIGHAND)
ff |= RFSIGSHARE;
if (!(args->flags & CLONE_FILES))
ff |= RFFDG;
error = 0;
start = 0;
rf_args.flags = ff;
if (error = rfork(p, &rf_args))
return error;
p2 = pfind(p->p_retval[0]);
if (p2 == 0)
return ESRCH;
p2->p_sigparent = exit_signal;
p2->p_md.md_regs->tf_esp = (unsigned int)args->stack;
#ifdef DEBUG
printf ("linux_clone(%d): successful rfork to %d\n", p->p_pid, p2->p_pid);
#endif
return 0;
}
#endif /* COMPAT_LINUX_THREADS */
/* XXX move */
struct linux_mmap_argv {
linux_caddr_t addr;
@ -570,6 +651,11 @@ struct linux_mmap_argv {
int pos;
};
#ifdef COMPAT_LINUX_THREADS
#define STACK_SIZE (2 * 1024 * 1024)
#define GUARD_SIZE (4 * PAGE_SIZE)
#endif /* COMPAT_LINUX_THREADS */
int
linux_mmap(struct proc *p, struct linux_mmap_args *args)
{
@ -602,8 +688,70 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.flags |= MAP_FIXED;
if (linux_args.flags & LINUX_MAP_ANON)
bsd_args.flags |= MAP_ANON;
#ifndef COMPAT_LINUX_THREADS
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
#else
#if !defined(USE_VM_STACK) && !defined(USE_VM_STACK_FOR_EXEC)
/* Linux Threads will map into the proc stack space, unless
we prevent it. This causes problems if we're not using
our VM_STACK options.
*/
if ((unsigned int)linux_args.addr + linux_args.len > (USRSTACK - MAXSSIZ))
return (EINVAL);
#endif
if (linux_args.flags & LINUX_MAP_GROWSDOWN) {
#ifdef USE_VM_STACK
/* USE_VM_STACK is defined (or not) in vm/vm_map.h */
bsd_args.flags |= MAP_STACK;
#endif
/* The linux MAP_GROWSDOWN option does not limit auto
growth of the region. Linux mmap with this option
takes as addr the inital BOS, and as len, the initial
region size. It can then grow down from addr without
limit. However, linux threads has an implicit internal
limit to stack size of STACK_SIZE. Its just not
enforced explicitly in linux. But, here we impose
a limit of (STACK_SIZE - GUARD_SIZE) on the stack
region, since we can do this with our mmap.
Our mmap with MAP_STACK takes addr as the maximum
downsize limit on BOS, and as len the max size of
the region. It them maps the top SGROWSIZ bytes,
and autgrows the region down, up to the limit
in addr.
If we don't use the MAP_STACK option, the effect
of this code is to allocate a stack region of a
fixed size of (STACK_SIZE - GUARD_SIZE).
*/
/* This gives us TOS */
bsd_args.addr = linux_args.addr + linux_args.len;
/* This gives us our maximum stack size */
if (linux_args.len > STACK_SIZE - GUARD_SIZE)
bsd_args.len = linux_args.len;
else
bsd_args.len = STACK_SIZE - GUARD_SIZE;
/* This gives us a new BOS. If we're using VM_STACK, then
mmap will just map the top SGROWSIZ bytes, and let
the stack grow down to the limit at BOS. If we're
not using VM_STACK we map the full stack, since we
don't have a way to autogrow it.
*/
bsd_args.addr -= bsd_args.len;
} else {
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
}
#endif /* COMPAT_LINUX_THREADS */
bsd_args.prot = linux_args.prot | PROT_READ; /* always required */
bsd_args.fd = linux_args.fd;
bsd_args.pos = linux_args.pos;
@ -830,11 +978,25 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
#endif
tmp.pid = args->pid;
tmp.status = args->status;
#ifndef COMPAT_LINUX_THREADS
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
think we need it, but I could be wrong. If we need
it, we need to fix wait4, since it will give us an
error return of EINVAL if we pass in _WCLONE, and
of course, it won't do anything with it.
*/
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = NULL;
if (error = wait4(p, &tmp))
#ifndef COMPAT_LINUX_THREADS
return error;
#else
return error;
#endif /* COMPAT_LINUX_THREADS */
if (args->status) {
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
@ -867,7 +1029,17 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
#endif
tmp.pid = args->pid;
tmp.status = args->status;
#ifndef COMPAT_LINUX_THREADS
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
think we need it, but I could be wrong. If we need
it, we need to fix wait4, since it will give us an
error return of EINVAL if we pass in _WCLONE, and
of course, it won't do anything with it.
*/
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = args->rusage;
if (error = wait4(p, &tmp))

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux.h,v 1.23 1998/10/05 16:37:36 jfieber Exp $
* $Id: linux.h,v 1.24 1998/11/12 00:42:08 jkh Exp $
*/
#ifndef _I386_LINUX_LINUX_H_
@ -418,6 +418,7 @@ struct trapframe;
#define LINUX_MAP_PRIVATE 0x0002
#define LINUX_MAP_FIXED 0x0010
#define LINUX_MAP_ANON 0x0020
#define LINUX_MAP_GROWSDOWN 0x0100
/* SystemV ipc defines */
#define LINUX_SEMOP 1

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_dummy.c,v 1.7 1997/10/29 08:17:09 kato Exp $
* $Id: linux_dummy.c,v 1.8 1997/11/06 19:28:52 phk Exp $
*/
#include <sys/param.h>
@ -211,13 +211,6 @@ linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args)
return ENOSYS;
}
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
return ENOSYS;
}
int
linux_uname(struct proc *p, struct linux_uname_args *args)
{

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_misc.c,v 1.46 1998/12/04 22:54:50 archie Exp $
* $Id: linux_misc.c,v 1.47 1998/12/10 13:47:18 jkh Exp $
*/
#include <sys/param.h>
@ -41,6 +41,9 @@
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#ifdef COMPAT_LINUX_THREADS
#include <sys/unistd.h>
#endif /* COMPAT_LINUX_THREADS */
#include <sys/vnode.h>
#include <sys/wait.h>
#include <sys/time.h>
@ -560,6 +563,84 @@ linux_fork(struct proc *p, struct linux_fork_args *args)
return 0;
}
#ifndef COMPAT_LINUX_THREADS
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
printf("linux_clone(%d): Not enabled\n", p->p_pid);
return (EOPNOTSUPP);
}
#else
#define CLONE_VM 0x100
#define CLONE_FS 0x200
#define CLONE_FILES 0x400
#define CLONE_SIGHAND 0x800
#define CLONE_PID 0x1000
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
int error, ff = RFPROC;
struct proc *p2;
int growable;
int initstacksize;
int maxstacksize;
int exit_signal;
vm_map_entry_t entry;
vm_map_t map;
vm_offset_t start;
struct rfork_args rf_args;
#ifdef SMP
printf("linux_clone(%d): does not work with SMP yet\n", p->p_pid);
return (EOPNOTSUPP);
#endif
#ifdef DEBUG
if (args->flags & CLONE_PID)
printf("linux_clone(%d): CLONE_PID not yet supported\n", p->p_pid);
printf ("linux_clone(%d): invoked with flags %x and stack %x\n", p->p_pid,
(unsigned int)args->flags, (unsigned int)args->stack);
#endif
if (!args->stack)
return (EINVAL);
exit_signal = args->flags & 0x000000ff;
if (exit_signal >= LINUX_NSIG)
return EINVAL;
exit_signal = linux_to_bsd_signal[exit_signal];
/* RFTHREAD probably not necessary here, but it shouldn't hurt either */
ff |= RFTHREAD;
if (args->flags & CLONE_VM)
ff |= RFMEM;
if (args->flags & CLONE_SIGHAND)
ff |= RFSIGSHARE;
if (!(args->flags & CLONE_FILES))
ff |= RFFDG;
error = 0;
start = 0;
rf_args.flags = ff;
if (error = rfork(p, &rf_args))
return error;
p2 = pfind(p->p_retval[0]);
if (p2 == 0)
return ESRCH;
p2->p_sigparent = exit_signal;
p2->p_md.md_regs->tf_esp = (unsigned int)args->stack;
#ifdef DEBUG
printf ("linux_clone(%d): successful rfork to %d\n", p->p_pid, p2->p_pid);
#endif
return 0;
}
#endif /* COMPAT_LINUX_THREADS */
/* XXX move */
struct linux_mmap_argv {
linux_caddr_t addr;
@ -570,6 +651,11 @@ struct linux_mmap_argv {
int pos;
};
#ifdef COMPAT_LINUX_THREADS
#define STACK_SIZE (2 * 1024 * 1024)
#define GUARD_SIZE (4 * PAGE_SIZE)
#endif /* COMPAT_LINUX_THREADS */
int
linux_mmap(struct proc *p, struct linux_mmap_args *args)
{
@ -602,8 +688,70 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args)
bsd_args.flags |= MAP_FIXED;
if (linux_args.flags & LINUX_MAP_ANON)
bsd_args.flags |= MAP_ANON;
#ifndef COMPAT_LINUX_THREADS
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
#else
#if !defined(USE_VM_STACK) && !defined(USE_VM_STACK_FOR_EXEC)
/* Linux Threads will map into the proc stack space, unless
we prevent it. This causes problems if we're not using
our VM_STACK options.
*/
if ((unsigned int)linux_args.addr + linux_args.len > (USRSTACK - MAXSSIZ))
return (EINVAL);
#endif
if (linux_args.flags & LINUX_MAP_GROWSDOWN) {
#ifdef USE_VM_STACK
/* USE_VM_STACK is defined (or not) in vm/vm_map.h */
bsd_args.flags |= MAP_STACK;
#endif
/* The linux MAP_GROWSDOWN option does not limit auto
growth of the region. Linux mmap with this option
takes as addr the inital BOS, and as len, the initial
region size. It can then grow down from addr without
limit. However, linux threads has an implicit internal
limit to stack size of STACK_SIZE. Its just not
enforced explicitly in linux. But, here we impose
a limit of (STACK_SIZE - GUARD_SIZE) on the stack
region, since we can do this with our mmap.
Our mmap with MAP_STACK takes addr as the maximum
downsize limit on BOS, and as len the max size of
the region. It them maps the top SGROWSIZ bytes,
and autgrows the region down, up to the limit
in addr.
If we don't use the MAP_STACK option, the effect
of this code is to allocate a stack region of a
fixed size of (STACK_SIZE - GUARD_SIZE).
*/
/* This gives us TOS */
bsd_args.addr = linux_args.addr + linux_args.len;
/* This gives us our maximum stack size */
if (linux_args.len > STACK_SIZE - GUARD_SIZE)
bsd_args.len = linux_args.len;
else
bsd_args.len = STACK_SIZE - GUARD_SIZE;
/* This gives us a new BOS. If we're using VM_STACK, then
mmap will just map the top SGROWSIZ bytes, and let
the stack grow down to the limit at BOS. If we're
not using VM_STACK we map the full stack, since we
don't have a way to autogrow it.
*/
bsd_args.addr -= bsd_args.len;
} else {
bsd_args.addr = linux_args.addr;
bsd_args.len = linux_args.len;
}
#endif /* COMPAT_LINUX_THREADS */
bsd_args.prot = linux_args.prot | PROT_READ; /* always required */
bsd_args.fd = linux_args.fd;
bsd_args.pos = linux_args.pos;
@ -830,11 +978,25 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args)
#endif
tmp.pid = args->pid;
tmp.status = args->status;
#ifndef COMPAT_LINUX_THREADS
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
think we need it, but I could be wrong. If we need
it, we need to fix wait4, since it will give us an
error return of EINVAL if we pass in _WCLONE, and
of course, it won't do anything with it.
*/
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = NULL;
if (error = wait4(p, &tmp))
#ifndef COMPAT_LINUX_THREADS
return error;
#else
return error;
#endif /* COMPAT_LINUX_THREADS */
if (args->status) {
if (error = copyin(args->status, &tmpstat, sizeof(int)))
return error;
@ -867,7 +1029,17 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args)
#endif
tmp.pid = args->pid;
tmp.status = args->status;
#ifndef COMPAT_LINUX_THREADS
tmp.options = args->options;
#else
/* This filters out the linux option _WCLONE. I don't
think we need it, but I could be wrong. If we need
it, we need to fix wait4, since it will give us an
error return of EINVAL if we pass in _WCLONE, and
of course, it won't do anything with it.
*/
tmp.options = (args->options & (WNOHANG | WUNTRACED));
#endif /* COMPAT_LINUX_THREADS */
tmp.rusage = args->rusage;
if (error = wait4(p, &tmp))

View File

@ -2,7 +2,7 @@
* System call prototypes.
*
* DO NOT EDIT-- this file is automatically generated.
* created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp
* created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp
*/
#ifndef _LINUX_SYSPROTO_H_
@ -301,7 +301,8 @@ struct linux_sigreturn_args {
struct linux_sigcontext * scp; char scp_[PAD_(struct linux_sigcontext *)];
};
struct linux_clone_args {
register_t dummy;
int flags; char flags_[PAD_(int)];
void * stack; char stack_[PAD_(void *)];
};
struct linux_newuname_args {
struct linux_newuname_t * buf; char buf_[PAD_(struct linux_newuname_t *)];

View File

@ -2,7 +2,7 @@
* System call numbers.
*
* DO NOT EDIT-- this file is automatically generated.
* created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp
* created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp
*/
#define LINUX_SYS_linux_setup 0

View File

@ -2,7 +2,7 @@
* System call switch table.
*
* DO NOT EDIT-- this file is automatically generated.
* created from Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp
* created from Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp
*/
#include "opt_compat.h"
@ -134,7 +134,7 @@ struct sysent linux_sysent[] = {
{ 5, (sy_call_t *)linux_ipc }, /* 117 = linux_ipc */
{ 1, (sy_call_t *)fsync }, /* 118 = fsync */
{ 1, (sy_call_t *)linux_sigreturn }, /* 119 = linux_sigreturn */
{ 0, (sy_call_t *)linux_clone }, /* 120 = linux_clone */
{ 2, (sy_call_t *)linux_clone }, /* 120 = linux_clone */
{ 2, (sy_call_t *)setdomainname }, /* 121 = setdomainname */
{ 1, (sy_call_t *)linux_newuname }, /* 122 = linux_newuname */
{ 3, (sy_call_t *)linux_modify_ldt }, /* 123 = linux_modify_ldt */

View File

@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: linux_sysvec.c,v 1.39 1998/12/14 18:54:01 dt Exp $
* $Id: linux_sysvec.c,v 1.40 1998/12/16 16:28:57 bde Exp $
*/
/* XXX we use functions that might not exist. */
@ -50,6 +50,10 @@
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#ifdef COMPAT_LINUX_THREADS
#include <sys/lock.h> /* needed, for now, by vm_map.h */
#include <vm/vm_map.h> /* needed, for now, for VM_STACK defines */
#endif /* COMPAT_LINUX_THREADS */
#include <sys/exec.h>
#include <sys/kernel.h>
#include <sys/module.h>
@ -217,7 +221,24 @@ linux_sendsig(sig_t catcher, int sig, int mask, u_long code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
#ifdef COMPAT_LINUX_THREADS
#ifdef USE_VM_STACK
#ifndef USE_VM_STACK_FOR_EXEC
if ((((caddr_t)fp > p->p_vmspace->vm_maxsaddr &&
(caddr_t)fp < (caddr_t)USRSTACK &&
grow(p, (int)fp) == FALSE) ||
(((caddr_t)fp <= p->p_vmspace->vm_maxsaddr ||
(caddr_t)fp >= (caddr_t)USRSTACK) &&
grow_stack (p, (int)fp) == FALSE)) ||
#else
if ((grow_stack (p, (int)fp) == FALSE) ||
#endif
#else
#endif /* COMPAT_LINUX_THREADS */
if ((grow(p, (int)fp) == FALSE) ||
#ifdef COMPAT_LINUX_THREADS
#endif
#endif /* COMPAT_LINUX_THREADS */
(useracc((caddr_t)fp, sizeof (struct linux_sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal

View File

@ -1,4 +1,4 @@
$Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde Exp $
$Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
; System call name/number master file (or rather, slave, from LINUX).
@ -171,7 +171,7 @@
caddr_t ptr); }
118 NOPROTO LINUX { int fsync(int fd); }
119 STD LINUX { int linux_sigreturn(struct linux_sigcontext *scp); }
120 STD LINUX { int linux_clone(void); }
120 STD LINUX { int linux_clone(int flags, void *stack); }
121 NOPROTO LINUX { int setdomainname(char *name, \
int len); }
122 STD LINUX { int linux_newuname(struct linux_newuname_t *buf); }

View File

@ -26,7 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: imgact_elf.c,v 1.42 1998/10/25 17:44:50 phk Exp $
* $Id: imgact_elf.c,v 1.43 1998/12/04 22:54:51 archie Exp $
*/
#include "opt_rlimit.h"
@ -854,7 +854,11 @@ elf_corehdr(p, vp, cred, numsegs, hdr, hdrsize)
status.pr_gregsetsz = sizeof(gregset_t);
status.pr_fpregsetsz = sizeof(fpregset_t);
status.pr_osreldate = osreldate;
#ifndef COMPAT_LINUX_THREADS
status.pr_cursig = p->p_sigacts->ps_sig;
#else
status.pr_cursig = p->p_sig;
#endif /* COMPAT_LINUX_THREADS */
status.pr_pid = p->p_pid;
fill_regs(p, &status.pr_reg);

View File

@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
* $Id: init_main.c,v 1.98 1998/10/09 23:42:47 peter Exp $
* $Id: init_main.c,v 1.99 1998/10/15 17:09:19 peter Exp $
*/
#include "opt_devfs.h"
@ -83,6 +83,9 @@ static struct session session0;
static struct pgrp pgrp0;
struct proc proc0;
static struct pcred cred0;
#ifdef COMPAT_LINUX_THREADS
static struct procsig procsig0;
#endif /* COMPAT_LINUX_THREADS */
static struct filedesc0 filedesc0;
static struct plimit limit0;
static struct vmspace vmspace0;
@ -415,6 +418,12 @@ proc0_init(dummy)
p->p_ucred = crget();
p->p_ucred->cr_ngroups = 1; /* group 0 */
#ifdef COMPAT_LINUX_THREADS
/* Create procsig. */
p->p_procsig = &procsig0;
p->p_procsig->ps_refcnt = 2;
#endif /* COMPAT_LINUX_THREADS */
/* Create the file descriptor table. */
fdp = &filedesc0;
p->p_fd = &fdp->fd_fd;
@ -461,11 +470,20 @@ proc0_init(dummy)
#endif
/*
#ifndef COMPAT_LINUX_THREADS
* We continue to place resource usage info and signal
* actions in the user struct so they're pageable.
*/
p->p_stats = &p->p_addr->u_stats;
p->p_sigacts = &p->p_addr->u_sigacts;
#else
* We continue to place resource usage info in the user struct so
* it's pageable.
*/
p->p_stats = &p->p_addr->u_stats;
p->p_sigacts = &p->p_procsig->ps_sigacts;
#endif /* COMPAT_LINUX_THREADS */
/*
* Charge root for one process.

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
* $Id: kern_exit.c,v 1.68 1998/11/10 09:16:29 peter Exp $
* $Id: kern_exit.c,v 1.69 1998/11/11 10:03:54 truckman Exp $
*/
#include "opt_compat.h"
@ -181,7 +181,9 @@ exit1(p, rv)
*/
p->p_flag &= ~(P_TRACED | P_PPWAIT);
p->p_flag |= P_WEXIT;
#ifndef COMPAT_LINUX_THREADS
p->p_sigignore = ~0;
#endif /* COMPAT_LINUX_THREADS */
p->p_siglist = 0;
if (timevalisset(&p->p_realtimer.it_value))
untimeout(realitexpire, (caddr_t)p, p->p_ithandle);
@ -282,6 +284,9 @@ exit1(p, rv)
LIST_REMOVE(q, p_sibling);
LIST_INSERT_HEAD(&initproc->p_children, q, p_sibling);
q->p_pptr = initproc;
#ifdef COMPAT_LINUX_THREADS
q->p_sigparent = 0;
#endif /* COMPAT_LINUX_THREADS */
/*
* Traced processes are killed
* since their existence means someone is screwing up.
@ -306,7 +311,11 @@ exit1(p, rv)
* flag set, notify process 1 instead (and hope it will handle
* this situation).
*/
#ifndef COMPAT_LINUX_THREADS
if (p->p_pptr->p_flag & P_NOCLDWAIT) {
#else
if (p->p_pptr->p_procsig->ps_flag & P_NOCLDWAIT) {
#endif /* COMPAT_LINUX_THREADS */
struct proc *pp = p->p_pptr;
proc_reparent(p, initproc);
/*
@ -318,7 +327,15 @@ exit1(p, rv)
wakeup((caddr_t)pp);
}
#ifndef COMPAT_LINUX_THREADS
psignal(p->p_pptr, SIGCHLD);
#else
if (p->p_sigparent && p->p_pptr != initproc) {
psignal(p->p_pptr, p->p_sigparent);
} else {
psignal(p->p_pptr, SIGCHLD);
}
#endif /* COMPAT_LINUX_THREADS */
wakeup((caddr_t)p->p_pptr);
#if defined(tahoe)
/* move this to cpu_exit */
@ -421,6 +438,14 @@ wait1(q, uap, compat)
if (uap->pid != WAIT_ANY &&
p->p_pid != uap->pid && p->p_pgid != -uap->pid)
continue;
#ifdef COMPAT_LINUX_THREADS
#if 0
if ((p->p_sigparent != 0) ^ ((uap->options & WLINUXCLONE) != 0)) {
continue;
}
#endif
#endif /* COMPAT_LINUX_THREADS */
nfound++;
if (p->p_stat == SZOMB) {
/* charge childs scheduling cpu usage to parent */
@ -488,6 +513,14 @@ wait1(q, uap, compat)
LIST_REMOVE(p, p_list); /* off zombproc */
LIST_REMOVE(p, p_sibling);
#ifdef COMPAT_LINUX_THREADS
if (--p->p_procsig->ps_refcnt == 0) {
free(p->p_procsig, M_TEMP);
p->p_procsig = NULL;
p->p_sigacts = NULL;
}
#endif /* COMPAT_LINUX_THREADS */
/*
* Give machine-dependent layer a chance
* to free anything that cpu_exit couldn't
@ -543,6 +576,11 @@ proc_reparent(child, parent)
LIST_REMOVE(child, p_sibling);
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
child->p_pptr = parent;
#ifdef COMPAT_LINUX_THREADS
#if 0
child->p_sigparent = 0;
#endif
#endif /* COMPAT_LINUX_THREADS */
}
/*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
* $Id: kern_fork.c,v 1.51 1998/01/22 17:29:46 dyson Exp $
* $Id: kern_fork.c,v 1.52 1998/11/09 15:07:41 truckman Exp $
*/
#include "opt_ktrace.h"
@ -62,6 +62,10 @@
#include <vm/vm_extern.h>
#include <vm/vm_zone.h>
#ifdef COMPAT_LINUX_THREADS
#include <machine/frame.h>
#endif /* COMPAT_LINUX_THREADS */
#ifdef SMP
static int fast_vfork = 0; /* Doesn't work on SMP yet. */
#else
@ -325,6 +329,24 @@ fork1(p1, flags)
p2->p_cred->p_refcnt = 1;
crhold(p1->p_ucred);
#ifdef COMPAT_LINUX_THREADS
if (flags & RFSIGSHARE) {
p2->p_procsig->ps_refcnt++;
} else {
p2->p_procsig = malloc(sizeof(struct procsig), M_TEMP, M_WAITOK);
p2->p_procsig->ps_refcnt = 1;
p2->p_procsig->ps_posix = 0;
bcopy(&p1->p_procsig->ps_begincopy, &p2->p_procsig->ps_begincopy,
(unsigned)&p1->p_procsig->ps_endcopy -
(unsigned)&p1->p_procsig->ps_begincopy);
}
if (flags & RFLINUXTHPN) {
p2->p_sigparent = SIGUSR1;
}
p2->p_sigacts = &p2->p_procsig->ps_sigacts;
if((flags & RFTHREAD) != 0 && (flags & RFPOSIXSIG) != 0)
p2->p_procsig->ps_posix = 1;
#endif /* COMPAT_LINUX_THREADS */
/* bump references to the text vnode (for procfs) */
p2->p_textvp = p1->p_textvp;
if (p2->p_textvp)

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
* $Id: kern_sig.c,v 1.49 1998/11/11 10:03:55 truckman Exp $
* $Id: kern_sig.c,v 1.50 1998/12/02 01:53:48 eivind Exp $
*/
#include "opt_compat.h"
@ -135,9 +135,17 @@ sigaction(p, uap)
sa->sa_flags |= SA_RESETHAND;
if ((ps->ps_signodefer & bit) != 0)
sa->sa_flags |= SA_NODEFER;
#ifndef COMPAT_LINUX_THREADS
if (signum == SIGCHLD && p->p_flag & P_NOCLDSTOP)
#else
if (signum == SIGCHLD && p->p_procsig->ps_flag & P_NOCLDSTOP)
#endif /* COMPAT_LINUX_THREADS */
sa->sa_flags |= SA_NOCLDSTOP;
#ifndef COMPAT_LINUX_THREADS
if (signum == SIGCHLD && p->p_flag & P_NOCLDWAIT)
#else
if (signum == SIGCHLD && p->p_procsig->ps_flag & P_NOCLDWAIT)
#endif /* COMPAT_LINUX_THREADS */
sa->sa_flags |= SA_NOCLDWAIT;
if ((error = copyout((caddr_t)sa, (caddr_t)uap->osa,
sizeof (vec))))
@ -195,9 +203,15 @@ setsigvec(p, signum, sa)
#endif
if (signum == SIGCHLD) {
if (sa->sa_flags & SA_NOCLDSTOP)
#ifndef COMPAT_LINUX_THREADS
p->p_flag |= P_NOCLDSTOP;
else
p->p_flag &= ~P_NOCLDSTOP;
#else
p->p_procsig->ps_flag |= P_NOCLDSTOP;
else
p->p_procsig->ps_flag &= ~P_NOCLDSTOP;
#endif /* COMPAT_LINUX_THREADS */
if (sa->sa_flags & SA_NOCLDWAIT) {
/*
* Paranoia: since SA_NOCLDWAIT is implemented by
@ -206,11 +220,21 @@ setsigvec(p, signum, sa)
* forbidden to set SA_NOCLDWAIT.
*/
if (p->p_pid == 1)
#ifndef COMPAT_LINUX_THREADS
p->p_flag &= ~P_NOCLDWAIT;
else
p->p_flag |= P_NOCLDWAIT;
#else
p->p_procsig->ps_flag &= ~P_NOCLDWAIT;
else
p->p_procsig->ps_flag |= P_NOCLDWAIT;
#endif /* COMPAT_LINUX_THREADS */
} else
#ifndef COMPAT_LINUX_THREADS
p->p_flag &= ~P_NOCLDWAIT;
#else
p->p_procsig->ps_flag &= ~P_NOCLDWAIT;
#endif /* COMPAT_LINUX_THREADS */
}
/*
* Set bit in p_sigignore for signals that are set to SIG_IGN,
@ -385,7 +409,11 @@ osigvec(p, uap)
if ((ps->ps_signodefer & bit) != 0)
sv->sv_flags |= SV_NODEFER;
#ifndef COMPAT_SUNOS
#ifndef COMPAT_LINUX_THREADS
if (signum == SIGCHLD && p->p_flag & P_NOCLDSTOP)
#else
if (signum == SIGCHLD && p->p_procsig->ps_flag & P_NOCLDSTOP)
#endif /* COMPAT_LINUX_THREADS */
sv->sv_flags |= SV_NOCLDSTOP;
#endif
if ((error = copyout((caddr_t)sv, (caddr_t)uap->osv,
@ -470,8 +498,12 @@ sigsuspend(p, uap)
* save it here and mark the sigacts structure
* to indicate this.
*/
#ifndef COMPAT_LINUX_THREADS
ps->ps_oldmask = p->p_sigmask;
ps->ps_flags |= SAS_OLDMASK;
#else
p->p_oldsigmask = p->p_sigmask;
#endif /* COMPAT_LINUX_THREADS */
p->p_sigmask = uap->mask &~ sigcantmask;
while (tsleep((caddr_t) ps, PPAUSE|PCATCH, "pause", 0) == 0)
/* void */;
@ -730,8 +762,13 @@ trapsignal(p, signum, code)
ps->ps_sigact[signum] = SIG_DFL;
}
} else {
#ifndef COMPAT_LINUX_THREADS
ps->ps_code = code; /* XXX for core dump/debugger */
ps->ps_sig = signum; /* XXX to verify code */
#else
p->p_code = code; /* XXX for core dump/debugger */
p->p_sig = signum; /* XXX to verify code */
#endif /* COMPAT_LINUX_THREADS */
psignal(p, signum);
}
}
@ -780,7 +817,11 @@ psignal(p, signum)
* and if it is set to SIG_IGN,
* action will be SIG_DFL here.)
*/
#ifndef COMPAT_LINUX_THREADS
if (p->p_sigignore & mask)
#else
if ((p->p_sigignore & mask) || (p->p_flag & P_WEXIT))
#endif /* COMPAT_LINUX_THREADS */
return;
if (p->p_sigmask & mask)
action = SIG_HOLD;
@ -862,7 +903,11 @@ psignal(p, signum)
goto out;
p->p_siglist &= ~mask;
p->p_xstat = signum;
#ifndef COMPAT_LINUX_THREADS
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
#else
if ((p->p_pptr->p_procsig->ps_flag & P_NOCLDSTOP) == 0)
#endif /* COMPAT_LINUX_THREADS */
psignal(p->p_pptr, SIGCHLD);
stop(p);
goto out;
@ -1069,7 +1114,11 @@ issignal(p)
break; /* == ignore */
p->p_xstat = signum;
stop(p);
#ifndef COMPAT_LINUX_THREADS
if ((p->p_pptr->p_flag & P_NOCLDSTOP) == 0)
#else
if ((p->p_pptr->p_procsig->ps_flag & P_NOCLDSTOP) == 0)
#endif /* COMPAT_LINUX_THREADS */
psignal(p->p_pptr, SIGCHLD);
mi_switch();
break;
@ -1144,8 +1193,13 @@ postsig(signum)
#ifdef KTRACE
if (KTRPOINT(p, KTR_PSIG))
ktrpsig(p->p_tracep,
#ifndef COMPAT_LINUX_THREADS
signum, action, ps->ps_flags & SAS_OLDMASK ?
ps->ps_oldmask : p->p_sigmask, 0);
#else
signum, action, p->p_oldsigmask ?
p->p_oldsigmask : p->p_sigmask, 0);
#endif /* COMPAT_LINUX_THREADS */
#endif
STOPEVENT(p, S_SIG, signum);
@ -1174,9 +1228,15 @@ postsig(signum)
* restored after the signal processing is completed.
*/
(void) splhigh();
#ifndef COMPAT_LINUX_THREADS
if (ps->ps_flags & SAS_OLDMASK) {
returnmask = ps->ps_oldmask;
ps->ps_flags &= ~SAS_OLDMASK;
#else
if (p->p_oldsigmask) {
returnmask = p->p_oldsigmask;
p->p_oldsigmask = 0;
#endif /* COMPAT_LINUX_THREADS */
} else
returnmask = p->p_sigmask;
p->p_sigmask |= ps->ps_catchmask[signum] |
@ -1192,12 +1252,22 @@ postsig(signum)
}
(void) spl0();
p->p_stats->p_ru.ru_nsignals++;
#ifndef COMPAT_LINUX_THREADS
if (ps->ps_sig != signum) {
#else
if (p->p_sig != signum) {
#endif /* COMPAT_LINUX_THREADS */
code = 0;
} else {
#ifndef COMPAT_LINUX_THREADS
code = ps->ps_code;
ps->ps_code = 0;
ps->ps_sig = 0;
#else
code = p->p_code;
p->p_code = 0;
p->p_sig = 0;
#endif /* COMPAT_LINUX_THREADS */
}
(*p->p_sysent->sv_sendsig)(action, signum, returnmask, code);
}
@ -1232,7 +1302,11 @@ sigexit(p, signum)
p->p_acflag |= AXSIG;
if (sigprop[signum] & SA_CORE) {
#ifndef COMPAT_LINUX_THREADS
p->p_sigacts->ps_sig = signum;
#else
p->p_sig = signum;
#endif /* COMPAT_LINUX_THREADS */
/*
* Log signals which would cause core dumps
* (Log as LOG_INFO to appease those who don't want

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.15 (Berkeley) 5/19/95
* $Id: proc.h,v 1.61 1998/11/11 10:56:05 truckman Exp $
* $Id: proc.h,v 1.62 1998/11/13 17:53:55 dg Exp $
*/
#ifndef _SYS_PROC_H_
@ -47,6 +47,9 @@
#include <sys/rtprio.h> /* For struct rtprio. */
#include <sys/select.h> /* For struct selinfo. */
#include <sys/signal.h>
#ifdef COMPAT_LINUX_THREADS
#include <sys/signalvar.h>
#endif /* COMPAT_LINUX_THREADS */
#ifndef KERNEL
#include <sys/time.h> /* For structs itimerval, timeval. */
#endif
@ -78,6 +81,19 @@ struct pgrp {
int pg_jobc; /* # procs qualifying pgrp for job control */
};
#ifdef COMPAT_LINUX_THREADS
struct procsig {
#define ps_begincopy ps_sigignore
sigset_t ps_sigignore; /* Signals being ignored. */
sigset_t ps_sigcatch; /* Signals being caught by user. */
int ps_flag;
struct sigacts ps_sigacts;
#define ps_endcopy ps_refcnt
int ps_refcnt;
int ps_posix;
};
#endif /* COMPAT_LINUX_THREADS */
/*
* Description of a process.
*
@ -164,17 +180,34 @@ struct proc {
char p_pad3[2]; /* padding for alignment */
register_t p_retval[2]; /* syscall aux returns */
struct sigiolst p_sigiolst; /* list of sigio sources */
#ifdef COMPAT_LINUX_THREADS
int p_sigparent; /* signal to parent on exit */
sigset_t p_oldsigmask; /* saved mask from before sigpause */
int p_sig; /* for core dump/debugger XXX */
u_long p_code; /* for core dump/debugger XXX */
#endif /* COMPAT_LINUX_THREADS */
/* End area that is zeroed on creation. */
#define p_endzero p_startcopy
/* The following fields are all copied upon creation in fork. */
#ifndef COMPAT_LINUX_THREADS
#define p_startcopy p_sigmask
#else
#define p_startcopy p_procsig
#endif /* COMPAT_LINUX_THREADS */
#ifdef COMPAT_LINUX_THREADS
struct procsig *p_procsig;
#define p_sigignore p_procsig->ps_sigignore
#define p_sigcatch p_procsig->ps_sigcatch
#endif /* COMPAT_LINUX_THREADS */
sigset_t p_sigmask; /* Current signal mask. */
#ifndef COMPAT_LINUX_THREADS
sigset_t p_sigignore; /* Signals being ignored. */
sigset_t p_sigcatch; /* Signals being caught by user. */
#endif /* COMPAT_LINUX_THREADS */
u_char p_priority; /* Process priority. */
u_char p_usrpri; /* User-priority based on p_cpu and p_nice. */
char p_nice; /* Process "nice" value. */
@ -349,7 +382,11 @@ void wakeup_one __P((void *chan));
void cpu_exit __P((struct proc *)) __dead2;
void exit1 __P((struct proc *, int)) __dead2;
void cpu_fork __P((struct proc *, struct proc *));
#ifndef COMPAT_LINUX_THREADS
int fork1 __P((struct proc *, int));
#else
int fork1 __P((struct proc *, int));
#endif /* COMPAT_LINUX_THREADS */
int trace_req __P((struct proc *));
void cpu_wait __P((struct proc *));
int cpu_coredump __P((struct proc *, struct vnode *, struct ucred *));

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)signalvar.h 8.6 (Berkeley) 2/19/95
* $Id: signalvar.h,v 1.19 1998/09/14 05:36:51 jdp Exp $
* $Id: signalvar.h,v 1.20 1998/11/11 10:04:13 truckman Exp $
*/
#ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */
@ -55,11 +55,15 @@ struct sigacts {
sigset_t ps_sigintr; /* signals that interrupt syscalls */
sigset_t ps_sigreset; /* signals that reset when caught */
sigset_t ps_signodefer; /* signals not masked while handled */
#ifndef COMPAT_LINUX_THREADS
sigset_t ps_oldmask; /* saved mask from before sigpause */
#endif /* COMPAT_LINUX_THREADS */
int ps_flags; /* signal flags, below */
struct sigaltstack ps_sigstk; /* sp & on stack state variable */
#ifndef COMPAT_LINUX_THREADS
int ps_sig; /* for core dump/debugger XXX */
u_long ps_code; /* for core dump/debugger XXX */
#endif /* COMPAT_LINUX_THREADS */
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
};

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)unistd.h 8.2 (Berkeley) 1/7/94
* $Id: unistd.h,v 1.16 1998/03/08 17:25:38 dufault Exp $
* $Id: unistd.h,v 1.17 1998/03/28 11:51:01 dufault Exp $
*/
#ifndef _SYS_UNISTD_H_
@ -186,6 +186,9 @@
#define RFCENVG (1<<11) /* UNIMPL zero plan9 `env space' */
#define RFCFDG (1<<12) /* zero fd table */
#define RFTHREAD (1<<13) /* enable kernel thread support */
#define RFSIGSHARE (1<<14) /* share signal handlers */
#define RFPOSIXSIG (1<<15) /* UNIMPL posix thread signal delivery */
#define RFLINUXTHPN (1<<16) /* do linux clone exit parent notification */
#define RFPPWAIT (1<<31) /* parent sleeps until child exits (vfork) */
#endif /* !_POSIX_SOURCE */

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)user.h 8.2 (Berkeley) 9/23/93
* $Id: user.h,v 1.15 1998/03/28 10:33:24 bde Exp $
* $Id: user.h,v 1.16 1998/07/15 20:18:00 dfr Exp $
*/
#ifndef _SYS_USER_H_
@ -102,7 +102,9 @@ void fill_eproc __P((struct proc *, struct eproc *));
struct user {
struct pcb u_pcb;
#ifndef COMPAT_LINUX_THREADS
struct sigacts u_sigacts; /* p_sigacts points here (use it!) */
#endif /* COMPAT_LINUX_THREADS */
struct pstats u_stats; /* p_stats points here (use it!) */
/*
@ -127,8 +129,13 @@ 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
#ifndef COMPAT_LINUX_THREADS
#define U_sig u_sigacts.ps_sig
#define U_code u_sigacts.ps_code
#else
#define U_sig u_kproc.kp_proc.p_sig
#define U_code u_kproc.kp_proc.p_code
#endif /* COMPAT_LINUX_THREADS */
#ifndef KERNEL
#define u_ar0 U_ar0

View File

@ -59,7 +59,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
* $Id: vm_glue.c,v 1.76 1998/09/29 17:33:59 abial Exp $
* $Id: vm_glue.c,v 1.77 1998/10/13 08:24:43 dg Exp $
*/
#include "opt_rlimit.h"
@ -230,13 +230,20 @@ vm_fork(p1, p2, flags)
up = p2->p_addr;
/*
#ifndef COMPAT_LINUX_THREADS
* 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
#else
* p_stats currently points at fields in the user struct
* but not at &u, instead at p_addr. Copy parts of
#endif /* COMPAT_LINUX_THREADS */
* p_stats; zero the rest of p_stats (statistics).
*/
p2->p_stats = &up->u_stats;
#ifndef COMPAT_LINUX_THREADS
p2->p_sigacts = &up->u_sigacts;
up->u_sigacts = *p1->p_sigacts;
#endif /* COMPAT_LINUX_THREADS */
bzero(&up->u_stats.pstat_startzero,
(unsigned) ((caddr_t) &up->u_stats.pstat_endzero -
(caddr_t) &up->u_stats.pstat_startzero));