summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-03-02 19:38:20 +0000
committerpeter <peter@FreeBSD.org>1996-03-02 19:38:20 +0000
commit8465726bdae0892d85c26b32cd01d2f6936303ef (patch)
tree83b4d342a731e2a76c19f214d574f24753abe420 /sys/i386
parent8283a18c8bf4ad6c988d73b3290e9d4b4a743ae3 (diff)
downloadFreeBSD-src-8465726bdae0892d85c26b32cd01d2f6936303ef.zip
FreeBSD-src-8465726bdae0892d85c26b32cd01d2f6936303ef.tar.gz
Mega-commit for Linux emulator update.. This has been stress tested under
netscape-2.0 for Linux running all the Java stuff. The scrollbars are now working, at least on my machine. (whew! :-) I'm uncomfortable with the size of this commit, but it's too inter-dependant to easily seperate out. The main changes: COMPAT_LINUX is *GONE*. Most of the code has been moved out of the i386 machine dependent section into the linux emulator itself. The int 0x80 syscall code was almost identical to the lcall 7,0 code and a minor tweak allows them to both be used with the same C code. All kernels can now just modload the lkm and it'll DTRT without having to rebuild the kernel first. Like IBCS2, you can statically compile it in with "options LINUX". A pile of new syscalls implemented, including getdents(), llseek(), readv(), writev(), msync(), personality(). The Linux-ELF libraries want to use some of these. linux_select() now obeys Linux semantics, ie: returns the time remaining of the timeout value rather than leaving it the original value. Quite a few bugs removed, including incorrect arguments being used in syscalls.. eg: mixups between passing the sigset as an int, vs passing it as a pointer and doing a copyin(), missing return values, unhandled cases, SIOC* ioctls, etc. The build for the code has changed. i386/conf/files now knows how to build linux_genassym and generate linux_assym.h on the fly. Supporting changes elsewhere in the kernel: The user-mode signal trampoline has moved from the U area to immediately below the top of the stack (below PS_STRINGS). This allows the different binary emulations to have their own signal trampoline code (which gets rid of the hardwired syscall 103 (sigreturn on BSD, syslog on Linux)) and so that the emulator can provide the exact "struct sigcontext *" argument to the program's signal handlers. The sigstack's "ss_flags" now uses SS_DISABLE and SS_ONSTACK flags, which have the same values as the re-used SA_DISABLE and SA_ONSTACK which are intended for sigaction only. This enables the support of a SA_RESETHAND flag to sigaction to implement the gross SYSV and Linux SA_ONESHOT signal semantics where the signal handler is reset when it's triggered. makesyscalls.sh no longer appends the struct sysentvec on the end of the generated init_sysent.c code. It's a lot saner to have it in a seperate file rather than trying to update the structure inside the awk script. :-) At exec time, the dozen bytes or so of signal trampoline code are copied to the top of the user's stack, rather than obtaining the trampoline code the old way by getting a clone of the parent's user area. This allows Linux and native binaries to freely exec each other without getting trampolines mixed up.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/conf/LINT3
-rw-r--r--sys/i386/conf/Makefile.i3865
-rw-r--r--sys/i386/conf/NOTES3
-rw-r--r--sys/i386/conf/files.i38623
-rw-r--r--sys/i386/conf/options.i3862
-rw-r--r--sys/i386/i386/exception.s12
-rw-r--r--sys/i386/i386/locore.s14
-rw-r--r--sys/i386/i386/machdep.c39
-rw-r--r--sys/i386/i386/trap.c137
-rw-r--r--sys/i386/ibcs2/ibcs2_sysvec.c10
-rw-r--r--sys/i386/ibcs2/ibcs2_util.h6
-rw-r--r--sys/i386/include/md_var.h4
-rw-r--r--sys/i386/include/pcb.h3
-rw-r--r--sys/i386/linux/imgact_linux.c15
-rw-r--r--sys/i386/linux/linux.h62
-rw-r--r--sys/i386/linux/linux_dummy.c105
-rw-r--r--sys/i386/linux/linux_file.c397
-rw-r--r--sys/i386/linux/linux_genassym.c22
-rw-r--r--sys/i386/linux/linux_ioctl.c47
-rw-r--r--sys/i386/linux/linux_ipc.c54
-rw-r--r--sys/i386/linux/linux_locore.s26
-rw-r--r--sys/i386/linux/linux_misc.c433
-rw-r--r--sys/i386/linux/linux_proto.h465
-rw-r--r--sys/i386/linux/linux_signal.c210
-rw-r--r--sys/i386/linux/linux_socket.c9
-rw-r--r--sys/i386/linux/linux_stats.c161
-rw-r--r--sys/i386/linux/linux_syscall.h151
-rw-r--r--sys/i386/linux/linux_sysent.c386
-rw-r--r--sys/i386/linux/linux_sysvec.c358
-rw-r--r--sys/i386/linux/linux_util.c179
-rw-r--r--sys/i386/linux/linux_util.h (renamed from sys/i386/linux/linux_generic.c)81
-rw-r--r--sys/i386/linux/sysproto.h210
32 files changed, 2554 insertions, 1078 deletions
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index ce1bae2..c2e6a38 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.240 1996/02/23 15:47:41 phk Exp $
+# $Id: LINT,v 1.241 1996/02/28 21:39:54 gpalmer Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -846,7 +846,6 @@ options POWERFAIL_NMI # make it beep instead of panicing
# More undocumented options for linting.
options APM_SLOWSTART=1
-options COMPAT_LINUX
options DEBUG
options "EXT2FS"
options "IBCS2"
diff --git a/sys/i386/conf/Makefile.i386 b/sys/i386/conf/Makefile.i386
index f88dd84..3ba84a5 100644
--- a/sys/i386/conf/Makefile.i386
+++ b/sys/i386/conf/Makefile.i386
@@ -1,6 +1,6 @@
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.74 1996/01/07 22:31:27 phk Exp $
+# $Id: Makefile.i386,v 1.75 1996/01/08 03:55:36 peter Exp $
#
# Makefile for FreeBSD
#
@@ -136,7 +136,8 @@ genassym: genassym.o
# XXX this assumes that the options for NORMAL_C* and DRIVER_C* are identical.
depend: assym.s param.c vnode_if.h ${BEFORE_DEPEND}
- mkdep ${COPTS} ${CFILES} ${SYSTEM_CFILES}
+ rm -f .depend
+ mkdep -a ${COPTS} ${CFILES} ${SYSTEM_CFILES}
mkdep -a ${COPTS} ${PARAM} -UKERNEL ${I386}/i386/genassym.c
MKDEP_CPP=${CPP} ; export MKDEP_CPP ; \
mkdep -a -DLOCORE ${COPTS} ${SFILES} ${SYSTEM_SFILES}
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index ce1bae2..c2e6a38 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.240 1996/02/23 15:47:41 phk Exp $
+# $Id: LINT,v 1.241 1996/02/28 21:39:54 gpalmer Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -846,7 +846,6 @@ options POWERFAIL_NMI # make it beep instead of panicing
# More undocumented options for linting.
options APM_SLOWSTART=1
-options COMPAT_LINUX
options DEBUG
options "EXT2FS"
options "IBCS2"
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index bef328a..5c0bef2 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,18 +1,32 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.128 1996/02/26 00:58:38 gibbs Exp $
+# $Id: files.i386,v 1.129 1996/03/02 03:48:11 pst Exp $
#
aic7xxx_asm optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_asm.c" \
compile-with "${CC} -Wall -o $@ $>" \
no-obj no-implicit-rule \
clean "aic7xxx_asm"
+#
aic7xxx_seq.h optional ahc device-driver \
compile-with "./aic7xxx_asm -o $@ $S/dev/aic7xxx/aic7xxx.seq" \
no-obj no-implicit-rule before-depend \
clean "aic7xxx_seq.h" \
dependency "$S/dev/aic7xxx/aic7xxx_reg.h $S/dev/aic7xxx/aic7xxx.seq aic7xxx_asm"
+#
+linux_genassym optional linux \
+ dependency "$S/i386/linux/linux_genassym.c $S/i386/linux/linux.h" \
+ compile-with "${CC} ${CFLAGS} -o $@ $<" \
+ no-obj no-implicit-rule \
+ clean "linux_genassym"
+#
+linux_assym.h optional linux \
+ dependency "linux_genassym" \
+ compile-with "./linux_genassym > $@" \
+ no-obj no-implicit-rule before-depend \
+ clean "linux_assym.h"
+#
i386/scsi/93cx6.c optional ahc device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
@@ -37,7 +51,6 @@ i386/i386/mem.c standard
i386/i386/microtime.s standard
i386/i386/ns_cksum.c optional ns
i386/i386/pmap.c standard
-# used by ptrace now
i386/i386/procfs_machdep.c standard
i386/i386/support.s standard
i386/i386/swtch.s standard
@@ -64,8 +77,6 @@ i386/ibcs2/ibcs2_errno.c optional ibcs2
i386/ibcs2/ibcs2_sysent.c optional ibcs2
i386/ibcs2/ibcs2_sysvec.c optional ibcs2
i386/ibcs2/imgact_coff.c optional ibcs2
-#i386/ibcs2/imgact_elf.c optional svr4
-#i386/ibcs2/imgact_xout.c optional ibcs2
i386/isa/aha1542.c optional aha device-driver
i386/isa/aic6360.c optional aic device-driver
i386/isa/ata.c optional ata device-driver
@@ -187,14 +198,16 @@ i386/isa/wt.c optional wt device-driver
i386/linux/imgact_linux.c optional linux
i386/linux/linux_dummy.c optional linux
i386/linux/linux_file.c optional linux
-i386/linux/linux_generic.c optional linux
i386/linux/linux_ioctl.c optional linux
i386/linux/linux_ipc.c optional linux
+i386/linux/linux_locore.s optional linux
i386/linux/linux_misc.c optional linux
i386/linux/linux_signal.c optional linux
i386/linux/linux_socket.c optional linux
i386/linux/linux_stats.c optional linux
i386/linux/linux_sysent.c optional linux
+i386/linux/linux_sysvec.c optional linux
+i386/linux/linux_util.c optional linux
i386/scsi/aic7xxx.c optional ahc device-driver \
dependency "$S/dev/aic7xxx/aic7xxx_reg.h aic7xxx_seq.h"
i386/scsi/bt.c optional bt device-driver
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index b48ef2c..f30187d 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -8,3 +8,5 @@ SHOW_BUSYBUFS opt_machdep.h
PANIC_REBOOT_WAIT_TIME opt_machdep.h
LARGEMEM opt_machdep.h
MAXMEM opt_machdep.h
+LINUX opt_linux.h
+COMPAT_LINUX opt_linux.h
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index c32df17..a22e644 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.13 1995/12/19 14:30:24 davidg Exp $
+ * $Id: exception.s,v 1.14 1995/12/21 19:20:57 davidg Exp $
*/
#include "npx.h" /* NNPX */
@@ -232,6 +232,7 @@ IDTVEC(syscall)
movl %ax,%es
movl TF_ERR(%esp),%eax /* copy saved eflags to final spot */
movl %eax,TF_EFLAGS(%esp)
+ movl $7,TF_ERR(%esp) /* sizeof "lcall 7,0" */
FAKE_MCOUNT(12*4(%esp))
incl _cnt+V_SYSCALL
movl $SWI_AST_MASK,_cpl
@@ -245,12 +246,11 @@ IDTVEC(syscall)
MEXITCOUNT
jmp _doreti
-#if defined(COMPAT_LINUX) || defined(LINUX)
/*
- * Call gate entry for Linux syscall (int 0x80)
+ * Call gate entry for Linux/NetBSD syscall (int 0x80)
*/
SUPERALIGN_TEXT
-IDTVEC(linux_syscall)
+IDTVEC(int0x80_syscall)
subl $8,%esp /* skip over tf_trapno and tf_err */
pushal
pushl %ds
@@ -258,10 +258,11 @@ IDTVEC(linux_syscall)
movl $KDSEL,%eax /* switch to kernel segments */
movl %ax,%ds
movl %ax,%es
+ movl $2,TF_ERR(%esp) /* sizeof "int 0x80" */
FAKE_MCOUNT(12*4(%esp))
incl _cnt+V_SYSCALL
movl $SWI_AST_MASK,_cpl
- call _linux_syscall
+ call _syscall
/*
* Return via _doreti to handle ASTs.
*/
@@ -270,7 +271,6 @@ IDTVEC(linux_syscall)
movb $1,_intr_nesting_level
MEXITCOUNT
jmp _doreti
-#endif /* COMPAT_LINUX || LINUX */
/*
* Include what was once config+isa-dependent code.
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index 6cafa00..e578692 100644
--- a/sys/i386/i386/locore.s
+++ b/sys/i386/i386/locore.s
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
- * $Id: locore.s,v 1.61 1996/01/30 07:59:02 davidg Exp $
+ * $Id: locore.s,v 1.62 1996/02/04 21:20:32 davidg Exp $
*/
/*
@@ -785,16 +785,22 @@ reloc_gdt:
#define LCALL(x,y) .byte 0x9a ; .long y ; .word x
+/*
+ * Signal trampoline, copied to top of user stack
+ */
NON_GPROF_ENTRY(sigcode)
call SIGF_HANDLER(%esp)
lea SIGF_SC(%esp),%eax /* scp (the call may have clobbered the */
/* copy at 8(%esp)) */
pushl %eax
pushl %eax /* junk to fake return address */
- movl $103,%eax /* XXX sigreturn() */
+ movl $SYS_sigreturn,%eax /* sigreturn() */
LCALL(0x7,0) /* enter kernel with args on stack */
hlt /* never gets here */
-
+ .align 2 /* long word align */
+_esigcode:
+ .data
.globl _szsigcode
_szsigcode:
- .long _szsigcode-_sigcode
+ .long _esigcode-_sigcode
+ .text
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 067d4e7..30f442e 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.174 1996/02/13 10:30:36 phk Exp $
+ * $Id: machdep.c,v 1.175 1996/03/02 18:24:00 peter Exp $
*/
#include "npx.h"
@@ -656,7 +656,7 @@ identifycpu()
* Send an interrupt to process.
*
* Stack is set up to allow sigcode stored
- * in u. to call routine, followed by kcall
+ * at top to call routine, followed by kcall
* to sigreturn routine below. After sigreturn
* resets the signal mask, the stack, and the
* frame pointer, it returns to the user
@@ -676,23 +676,17 @@ sendsig(catcher, sig, mask, code)
int oonstack;
regs = p->p_md.md_regs;
- oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
+ oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
/*
- * Allocate and validate space for the signal handler
- * context. Note that if the stack is in P0 space, the
- * call to grow() is a nop, and the useracc() check
- * will fail if the process has not already allocated
- * the space with a `brk'.
+ * Allocate and validate space for the signal handler context.
*/
- if ((psp->ps_flags & SAS_ALTSTACK) &&
- (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
+ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
(psp->ps_sigonstack & sigmask(sig))) {
fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
psp->ps_sigstk.ss_size - sizeof(struct sigframe));
- psp->ps_sigstk.ss_flags |= SA_ONSTACK;
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
} else {
- fp = (struct sigframe *)(regs[tESP]
- - sizeof(struct sigframe));
+ fp = (struct sigframe *)regs[tESP] - 1;
}
/*
@@ -765,7 +759,7 @@ sendsig(catcher, sig, mask, code)
};
regs[tESP] = (int)fp;
- regs[tEIP] = (int)((struct pcb *)kstack)->pcb_sigc;
+ regs[tEIP] = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode));
regs[tEFLAGS] &= ~PSL_VM;
regs[tCS] = _ucodesel;
regs[tDS] = _udatasel;
@@ -861,9 +855,9 @@ sigreturn(p, uap, retval)
return(EINVAL);
if (scp->sc_onstack & 01)
- p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
+ p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
else
- p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
p->p_sigmask = scp->sc_mask &~
(sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
regs[tEBP] = scp->sc_fp;
@@ -1277,12 +1271,7 @@ extern inthand_t
IDTVEC(bnd), IDTVEC(ill), IDTVEC(dna), IDTVEC(fpusegm),
IDTVEC(tss), IDTVEC(missing), IDTVEC(stk), IDTVEC(prot),
IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
- IDTVEC(syscall);
-
-#if defined(COMPAT_LINUX) || defined(LINUX)
-extern inthand_t
- IDTVEC(linux_syscall);
-#endif
+ IDTVEC(syscall), IDTVEC(int0x80_syscall);
void
sdtossd(sd, ssd)
@@ -1378,9 +1367,8 @@ init386(first)
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#if defined(COMPAT_LINUX) || defined(LINUX)
- setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
-#endif
+ setidt(0x80, &IDTVEC(int0x80_syscall),
+ SDT_SYS386TGT, SEL_UPL, GSEL(GCODE_SEL, SEL_KPL));
#include "isa.h"
#if NISA >0
@@ -1634,7 +1622,6 @@ init386(first)
_udatasel = LSEL(LUDATA_SEL, SEL_UPL);
/* setup proc 0's pcb */
- bcopy(&sigcode, proc0.p_addr->u_pcb.pcb_sigc, szsigcode);
proc0.p_addr->u_pcb.pcb_flags = 0;
proc0.p_addr->u_pcb.pcb_ptd = IdlePTD;
}
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index e270a58..8ecc511 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.71 1996/01/19 03:57:42 dyson Exp $
+ * $Id: trap.c,v 1.72 1996/02/25 03:02:46 dyson Exp $
*/
/*
@@ -90,7 +90,6 @@ int (*pmath_emulate) __P((struct trapframe *));
extern void trap __P((struct trapframe frame));
extern int trapwrite __P((unsigned addr));
extern void syscall __P((struct trapframe frame));
-extern void linux_syscall __P((struct trapframe frame));
static int trap_pfault __P((struct trapframe *, int));
static void trap_fatal __P((struct trapframe *));
@@ -875,22 +874,26 @@ syscall(frame)
p->p_md.md_regs = (int *)&frame;
params = (caddr_t)frame.tf_esp + sizeof(int);
code = frame.tf_eax;
- /*
- * Need to check if this is a 32 bit or 64 bit syscall.
- */
- if (code == SYS_syscall) {
- /*
- * Code is first argument, followed by actual args.
- */
- code = fuword(params);
- params += sizeof(int);
- } else if (code == SYS___syscall) {
+ if (p->p_sysent->sv_prepsyscall) {
+ (*p->p_sysent->sv_prepsyscall)(&frame, args, &code, &params);
+ } else {
/*
- * Like syscall, but code is a quad, so as to maintain
- * quad alignment for the rest of the arguments.
+ * Need to check if this is a 32 bit or 64 bit syscall.
*/
- code = fuword(params);
- params += sizeof(quad_t);
+ if (code == SYS_syscall) {
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = fuword(params);
+ params += sizeof(int);
+ } else if (code == SYS___syscall) {
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments.
+ */
+ code = fuword(params);
+ params += sizeof(quad_t);
+ }
}
if (p->p_sysent->sv_mask)
@@ -901,7 +904,7 @@ syscall(frame)
else
callp = &p->p_sysent->sv_table[code];
- if ((i = callp->sy_narg * sizeof(int)) &&
+ if (params && (i = callp->sy_narg * sizeof(int)) &&
(error = copyin(params, (caddr_t)args, (u_int)i))) {
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
@@ -933,9 +936,10 @@ syscall(frame)
case ERESTART:
/*
- * Reconstruct pc, assuming lcall $X,y is 7 bytes.
+ * Reconstruct pc, assuming lcall $X,y is 7 bytes,
+ * int 0x80 is 2 bytes. We saved this in tf_err.
*/
- frame.tf_eip -= 7;
+ frame.tf_eip -= frame.tf_err;
break;
case EJUSTRETURN:
@@ -966,98 +970,3 @@ bad:
ktrsysret(p->p_tracep, code, error, rval[0]);
#endif
}
-
-#if defined(COMPAT_LINUX) || defined(LINUX)
-void
-linux_syscall(frame)
- struct trapframe frame;
-{
- struct proc *p = curproc;
- struct sysent *callp;
- u_quad_t sticks;
- int error;
- int rval[2];
- u_int code;
- struct linux_syscall_args {
- int arg1;
- int arg2;
- int arg3;
- int arg4;
- int arg5;
- } args;
-
- args.arg1 = frame.tf_ebx;
- args.arg2 = frame.tf_ecx;
- args.arg3 = frame.tf_edx;
- args.arg4 = frame.tf_esi;
- args.arg5 = frame.tf_edi;
-
- sticks = p->p_sticks;
- if (ISPL(frame.tf_cs) != SEL_UPL)
- panic("linux syscall");
-
- p->p_md.md_regs = (int *)&frame;
- code = frame.tf_eax;
-
- if (p->p_sysent->sv_mask)
- code &= p->p_sysent->sv_mask;
-
- if (code >= p->p_sysent->sv_size)
- callp = &p->p_sysent->sv_table[0];
- else
- callp = &p->p_sysent->sv_table[code];
-
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSCALL))
- ktrsyscall(p->p_tracep, code, callp->sy_narg, (int *)&args);
-#endif
-
- rval[0] = 0;
-
- error = (*callp->sy_call)(p, &args, rval);
-
- switch (error) {
-
- case 0:
- /*
- * Reinitialize proc pointer `p' as it may be different
- * if this is a child returning from fork syscall.
- */
- p = curproc;
- frame.tf_eax = rval[0];
- frame.tf_eflags &= ~PSL_C;
- break;
-
- case ERESTART:
- /* Reconstruct pc, subtract size of int 0x80 */
- frame.tf_eip -= 2;
- break;
-
- case EJUSTRETURN:
- break;
-
- default:
- if (p->p_sysent->sv_errsize)
- if (error >= p->p_sysent->sv_errsize)
- error = -1; /* XXX */
- else
- error = p->p_sysent->sv_errtbl[error];
- frame.tf_eax = -error;
- frame.tf_eflags |= PSL_C;
- break;
- }
-
- if (frame.tf_eflags & PSL_T) {
- /* Traced syscall. */
- frame.tf_eflags &= ~PSL_T;
- trapsignal(p, SIGTRAP, 0);
- }
-
- userret(p, &frame, sticks);
-
-#ifdef KTRACE
- if (KTRPOINT(p, KTR_SYSRET))
- ktrsysret(p->p_tracep, code, error, rval[0]);
-#endif
-}
-#endif /* COMPAT_LINUX || LINUX */
diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c
index 160409e..4890473 100644
--- a/sys/i386/ibcs2/ibcs2_sysvec.c
+++ b/sys/i386/ibcs2/ibcs2_sysvec.c
@@ -27,7 +27,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$
+ * $Id: ibcs2_sysvec.c,v 1.1 1995/10/10 07:59:11 swallace Exp $
*/
#include <sys/param.h>
@@ -37,6 +37,8 @@
extern int bsd_to_ibcs2_sig[];
extern int bsd_to_ibcs2_errno[];
extern struct sysent ibcs2_sysent[IBCS2_SYS_MAXSYSCALL];
+extern int szsigcode;
+extern char sigcode[];
struct sysentvec ibcs2_svr3_sysvec = {
sizeof (ibcs2_sysent) / sizeof (ibcs2_sysent[0]),
@@ -46,5 +48,9 @@ struct sysentvec ibcs2_svr3_sysvec = {
bsd_to_ibcs2_sig,
ELAST,
bsd_to_ibcs2_errno,
- 0
+ 0, /* fixup */
+ 0, /* sendsig, ignore */
+ sigcode, /* use generic trampoline */
+ &szsigcode, /* use generic trampoline size */
+ 0 /* prepsyscall */
};
diff --git a/sys/i386/ibcs2/ibcs2_util.h b/sys/i386/ibcs2/ibcs2_util.h
index 67f859b..af972b6 100644
--- a/sys/i386/ibcs2/ibcs2_util.h
+++ b/sys/i386/ibcs2/ibcs2_util.h
@@ -45,6 +45,8 @@
#include <machine/vmparam.h>
#include <sys/exec.h>
#include <sys/cdefs.h>
+#include <sys/sysent.h>
+#include <sys/proc.h>
#ifndef SCARG
#define SCARG(p, x) (p)->x
@@ -56,8 +58,8 @@ static __inline void *stackgap_alloc(caddr_t *, size_t);
static __inline caddr_t
stackgap_init()
{
-#define szsigcode ((caddr_t)(esigcode - sigcode))
- return (caddr_t)(ALIGN(((caddr_t)PS_STRINGS) - SPARE_USRSPACE));
+#define szsigcode (*(curproc->p_sysent->sv_szsigcode), sizeof(char *))
+ return (caddr_t)(((caddr_t)PS_STRINGS) - szsigcode - SPARE_USRSPACE);
}
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 19e2822..5e28030 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: md_var.h,v 1.6 1996/01/27 02:33:25 bde Exp $
+ * $Id: md_var.h,v 1.7 1996/02/04 21:20:52 davidg Exp $
*/
#ifndef _MACHINE_MD_VAR_H_
@@ -45,7 +45,7 @@ extern char etext[];
extern char kstack[];
extern void (*netisrs[32]) __P((void));
extern int nfs_diskless_valid;
-extern int sigcode;
+extern char sigcode[];
extern int szsigcode;
struct proc;
diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h
index f8ea0dc..a3f2005 100644
--- a/sys/i386/include/pcb.h
+++ b/sys/i386/include/pcb.h
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)pcb.h 5.10 (Berkeley) 5/12/91
- * $Id: pcb.h,v 1.9 1995/08/17 11:30:03 davidg Exp $
+ * $Id: pcb.h,v 1.10 1996/01/23 02:39:24 davidg Exp $
*/
#ifndef _I386_PCB_H_
@@ -68,7 +68,6 @@ struct pcb {
#define FP_SOFTFP 0x01 /* process using software fltng pnt emulator */
u_char pcb_inl; /* intr_nesting_level at context switch */
caddr_t pcb_onfault; /* copyin/out fault recovery */
- long pcb_sigc[8]; /* XXX signal code trampoline */
};
/*
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
index 4319de2..9d6906d 100644
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -28,7 +28,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_linux.c,v 1.7 1996/01/19 22:59:23 dyson Exp $
+ * $Id: imgact_linux.c,v 1.8 1996/02/16 18:40:48 peter Exp $
*/
#include <sys/param.h>
@@ -50,7 +50,8 @@
#include <vm/vm_prot.h>
#include <vm/vm_extern.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux.h>
+#include <i386/linux/linux_proto.h>
extern int exec_linux_imgact __P((struct image_params *iparams));
@@ -83,6 +84,9 @@ exec_linux_imgact(imgp)
return (-1);
}
bss_size = round_page(a_out->a_bss);
+#ifdef DEBUG
+ printf("imgact: text: %08x, data: %08x, bss: %08x\n", a_out->a_text, a_out->a_data, bss_size);
+#endif
/*
* Check various fields in header for validity/bounds.
@@ -173,6 +177,9 @@ exec_linux_imgact(imgp)
if (error)
return (error);
+#ifdef DEBUG
+ printf("imgact: startaddr=%08x, length=%08x\n", vmaddr, a_out->a_text + a_out->a_data);
+#endif
/*
* allow read/write of data
*/
@@ -193,6 +200,10 @@ exec_linux_imgact(imgp)
bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
if (error)
return (error);
+#ifdef DEBUG
+ printf("imgact: bssaddr=%08x, length=%08x\n", vmaddr, bss_size);
+#endif
+
}
/* Indicate that this file should not be modified */
imgp->vp->v_flag |= VTEXT;
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index c0fbc0a..f6bab97 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -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.3 1995/12/29 22:12:10 sos Exp $
+ * $Id: linux.h,v 1.4 1996/01/30 22:56:29 mpp Exp $
*/
#ifndef _I386_LINUX_LINUX_H_
@@ -55,9 +55,56 @@ typedef struct {
} linux_sigaction_t;
typedef int linux_key_t;
+/*
+ * The Linux sigcontext, pretty much a standard 386 trapframe.
+ */
+
+struct linux_sigcontext {
+ int sc_gs;
+ int sc_fs;
+ int sc_es;
+ int sc_ds;
+ int sc_edi;
+ int sc_esi;
+ int sc_ebp;
+ int sc_esp;
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+ int sc_trapno;
+ int sc_err;
+ int sc_eip;
+ int sc_cs;
+ int sc_eflags;
+ int sc_esp_at_signal;
+ int sc_ss;
+ int sc_387;
+ int sc_mask;
+ int sc_cr2;
+};
+
+/*
+ * We make the stack look like Linux expects it when calling a signal
+ * handler, but use the BSD way of calling the handler and sigreturn().
+ * This means that we need to pass the pointer to the handler too.
+ * It is appended to the frame to not interfere with the rest of it.
+ */
+
+struct linux_sigframe {
+ int sf_sig;
+ struct linux_sigcontext sf_sc;
+ sig_t sf_handler;
+};
+
extern int bsd_to_linux_signal[];
extern int linux_to_bsd_signal[];
+extern struct sysentvec linux_sysvec;
+
+struct image_params;
+int linux_fixup __P((int **stack_base, struct image_params *iparams));
+
/* misc defines */
#define LINUX_NAME_MAX 255
@@ -421,9 +468,14 @@ extern int linux_to_bsd_signal[];
#define LINUX_SNDCTL_DSP_GETISPACE 0x500D
#define LINUX_SNDCTL_DSP_NONBLOCK 0x500E
-#ifdef KERNEL
-caddr_t ua_alloc_init __P((int len));
-caddr_t ua_alloc __P((int len));
-#endif
+/* Socket system defines */
+#define LINUX_SIOCGIFCONF 0x8912
+#define LINUX_SIOCGIFFLAGS 0x8913
+#define LINUX_SIOCGIFADDR 0x8915
+#define LINUX_SIOCGIFDSTADDR 0x8917
+#define LINUX_SIOCGIFBRDADDR 0x8919
+#define LINUX_SIOCGIFNETMASK 0x891b
+#define LINUX_SIOCADDMULTI 0x8931
+#define LINUX_SIOCDELMULTI 0x8932
#endif /* !_I386_LINUX_LINUX_H_ */
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 6c55613..2fcab46 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -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.1 1995/06/25 17:32:33 sos Exp $
+ * $Id: linux_dummy.c,v 1.2 1995/11/22 07:43:44 bde Exp $
*/
#include <sys/param.h>
@@ -34,283 +34,264 @@
#include <sys/proc.h>
#include <sys/resourcevar.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux.h>
+#include <i386/linux/linux_proto.h>
int
-linux_setup(struct proc *p, void *args, int *retval)
+linux_setup(struct proc *p, struct linux_setup_args *args, int *retval)
{
printf("Linux-emul(%d): setup() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_break(struct proc *p, void *args, int *retval)
+linux_break(struct proc *p, struct linux_break_args *args, int *retval)
{
printf("Linux-emul(%d): break() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_stat(struct proc *p, void *args, int *retval)
+linux_stat(struct proc *p, struct linux_stat_args *args, int *retval)
{
printf("Linux-emul(%d): stat() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_fstat(struct proc *p, void *args, int *retval)
+linux_fstat(struct proc *p, struct linux_fstat_args *args, int *retval)
{
printf("Linux-emul(%d): fstat() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_mount(struct proc *p, void *args, int *retval)
+linux_mount(struct proc *p, struct linux_mount_args *args, int *retval)
{
printf("Linux-emul(%d): mount() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_umount(struct proc *p, void *args, int *retval)
+linux_umount(struct proc *p, struct linux_umount_args *args, int *retval)
{
printf("Linux-emul(%d): umount() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_stime(struct proc *p, void *args, int *retval)
+linux_stime(struct proc *p, struct linux_stime_args *args, int *retval)
{
printf("Linux-emul(%d): stime() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_ptrace(struct proc *p, void *args, int *retval)
+linux_ptrace(struct proc *p, struct linux_ptrace_args *args, int *retval)
{
printf("Linux-emul(%d): ptrace() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_pause(struct proc *p, void *args, int *retval)
-{
- printf("Linux-emul(%d): pause() not supported\n", p->p_pid);
- return ENOSYS;
-}
-
-int
-linux_stty(struct proc *p, void *args, int *retval)
+linux_stty(struct proc *p, struct linux_stty_args *args, int *retval)
{
printf("Linux-emul(%d): stty() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_gtty(struct proc *p, void *args, int *retval)
+linux_gtty(struct proc *p, struct linux_gtty_args *args, int *retval)
{
printf("Linux-emul(%d): gtty() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_nice(struct proc *p, void *args, int *retval)
+linux_nice(struct proc *p, struct linux_nice_args *args, int *retval)
{
printf("Linux-emul(%d): nice() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_ftime(struct proc *p, void *args, int *retval)
+linux_ftime(struct proc *p, struct linux_ftime_args *args, int *retval)
{
printf("Linux-emul(%d): ftime() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_prof(struct proc *p, void *args, int *retval)
+linux_prof(struct proc *p, struct linux_prof_args *args, int *retval)
{
printf("Linux-emul(%d): prof() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_signal(struct proc *p, void *args, int *retval)
-{
- printf("Linux-emul(%d): signal() not supported\n", p->p_pid);
- return ENOSYS;
-}
-
-int
-linux_phys(struct proc *p, void *args, int *retval)
+linux_phys(struct proc *p, struct linux_phys_args *args, int *retval)
{
printf("Linux-emul(%d): phys() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_lock(struct proc *p, void *args, int *retval)
+linux_lock(struct proc *p, struct linux_lock_args *args, int *retval)
{
printf("Linux-emul(%d): lock() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_mpx(struct proc *p, void *args, int *retval)
+linux_mpx(struct proc *p, struct linux_mpx_args *args, int *retval)
{
printf("Linux-emul(%d): mpx() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_ulimit(struct proc *p, void *args, int *retval)
+linux_ulimit(struct proc *p, struct linux_ulimit_args *args, int *retval)
{
printf("Linux-emul(%d): ulimit() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_olduname(struct proc *p, void *args, int *retval)
+linux_olduname(struct proc *p, struct linux_olduname_args *args, int *retval)
{
printf("Linux-emul(%d): olduname() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_ustat(struct proc *p, void *args, int *retval)
+linux_ustat(struct proc *p, struct linux_ustat_args *args, int *retval)
{
printf("Linux-emul(%d): ustat() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_ioperm(struct proc *p, void *args, int *retval)
+linux_ioperm(struct proc *p, struct linux_ioperm_args *args, int *retval)
{
printf("Linux-emul(%d): ioperm() not supported\n", p->p_pid);
return 0; /* EINVAL SOS XXX */
}
int
-linux_syslog(struct proc *p, void *args, int *retval)
+linux_ksyslog(struct proc *p, struct linux_ksyslog_args *args, int *retval)
{
- printf("Linux-emul(%d): syslog() not supported (BSD sigreturn)\n",p->p_pid);
- return sigreturn(p, args, retval);
+ printf("Linux-emul(%d): ksyslog(%x) not supported\n",
+ p->p_pid, args->what);
+ return ENOSYS; /* EPERM - Peter - it's a root-only thing */
}
int
-linux_iopl(struct proc *p, void *args, int *retval)
+linux_iopl(struct proc *p, struct linux_iopl_args *args, int *retval)
{
printf("Linux-emul(%d): iopl() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_vhangup(struct proc *p, void *args, int *retval)
+linux_vhangup(struct proc *p, struct linux_vhangup_args *args, int *retval)
{
printf("Linux-emul(%d): vhangup() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_idle(struct proc *p, void *args, int *retval)
+linux_idle(struct proc *p, struct linux_idle_args *args, int *retval)
{
printf("Linux-emul(%d): idle() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_vm86(struct proc *p, void *args, int *retval)
+linux_vm86(struct proc *p, struct linux_vm86_args *args, int *retval)
{
printf("Linux-emul(%d): vm86() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_swapoff(struct proc *p, void *args, int *retval)
+linux_swapoff(struct proc *p, struct linux_swapoff_args *args, int *retval)
{
printf("Linux-emul(%d): swapoff() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_sysinfo(struct proc *p, void *args, int *retval)
+linux_sysinfo(struct proc *p, struct linux_sysinfo_args *args, int *retval)
{
printf("Linux-emul(%d): sysinfo() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_sigreturn(struct proc *p, void *args, int *retval)
-{
- printf("Linux-emul(%d): sigreturn() not supported\n", p->p_pid);
- return ENOSYS;
-}
-
-int
-linux_clone(struct proc *p, void *args, int *retval)
+linux_clone(struct proc *p, struct linux_clone_args *args, int *retval)
{
printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_uname(struct proc *p, void *args, int *retval)
+linux_uname(struct proc *p, struct linux_uname_args *args, int *retval)
{
printf("Linux-emul(%d): uname() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_modify_ldt(struct proc *p, void *args, int *retval)
+linux_modify_ldt(struct proc *p, struct linux_modify_ldt_args *args, int *retval)
{
printf("Linux-emul(%d): modify_ldt() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_adjtimex(struct proc *p, void *args, int *retval)
+linux_adjtimex(struct proc *p, struct linux_adjtimex_args *args, int *retval)
{
printf("Linux-emul(%d): adjtimex() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_create_module(struct proc *p, void *args, int *retval)
+linux_create_module(struct proc *p, struct linux_create_module_args *args, int *retval)
{
printf("Linux-emul(%d): create_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_init_module(struct proc *p, void *args, int *retval)
+linux_init_module(struct proc *p, struct linux_init_module_args *args, int *retval)
{
printf("Linux-emul(%d): init_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_delete_module(struct proc *p, void *args, int *retval)
+linux_delete_module(struct proc *p, struct linux_delete_module_args *args, int *retval)
{
printf("Linux-emul(%d): delete_module() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_get_kernel_syms(struct proc *p, void *args, int *retval)
+linux_get_kernel_syms(struct proc *p, struct linux_get_kernel_syms_args *args, int *retval)
{
printf("Linux-emul(%d): get_kernel_syms() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_quotactl(struct proc *p, void *args, int *retval)
+linux_quotactl(struct proc *p, struct linux_quotactl_args *args, int *retval)
{
printf("Linux-emul(%d): quotactl() not supported\n", p->p_pid);
return ENOSYS;
}
int
-linux_bdflush(struct proc *p, void *args, int *retval)
+linux_bdflush(struct proc *p, struct linux_bdflush_args *args, int *retval)
{
printf("Linux-emul(%d): bdflush() not supported\n", p->p_pid);
return ENOSYS;
diff --git a/sys/i386/linux/linux_file.c b/sys/i386/linux/linux_file.c
index 0918f22..93932df 100644
--- a/sys/i386/linux/linux_file.c
+++ b/sys/i386/linux/linux_file.c
@@ -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_file.c,v 1.4 1995/11/22 07:43:45 bde Exp $
+ * $Id: linux_file.c,v 1.5 1995/12/15 03:06:50 peter Exp $
*/
#include <sys/param.h>
@@ -41,16 +41,15 @@
#include <sys/malloc.h>
#include <sys/exec.h>
#include <sys/dirent.h>
+#include <sys/sysproto.h>
+#include <sys/conf.h>
+#include <sys/tty.h>
#include <ufs/ufs/dir.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
-
-struct linux_creat_args {
- char *path;
- int mode;
-};
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
int
linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
@@ -60,6 +59,10 @@ linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
int flags;
int mode;
} */ bsd_open_args;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTCREAT(p, &sg, args->path);
#ifdef DEBUG
printf("Linux-emul(%d): creat(%s, %d)\n",
@@ -71,12 +74,6 @@ linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
return open(p, &bsd_open_args, retval);
}
-struct linux_open_args {
- char *path;
- int flags;
- int mode;
-};
-
int
linux_open(struct proc *p, struct linux_open_args *args, int *retval)
{
@@ -86,7 +83,15 @@ linux_open(struct proc *p, struct linux_open_args *args, int *retval)
int mode;
} */ bsd_open_args;
int error;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ if (args->flags & LINUX_O_CREAT)
+ CHECKALTCREAT(p, &sg, args->path);
+ else
+ CHECKALTEXIST(p, &sg, args->path);
+
#ifdef DEBUG
printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n",
p->p_pid, args->path, args->flags, args->mode);
@@ -128,6 +133,10 @@ linux_open(struct proc *p, struct linux_open_args *args, int *retval)
if (fp->f_type == DTYPE_VNODE)
(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
}
+#ifdef DEBUG
+ printf("Linux-emul(%d): open returns error %d\n",
+ p->p_pid, error);
+#endif
return error;
}
@@ -179,12 +188,6 @@ bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock)
linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid;
}
-struct linux_fcntl_args {
- int fd;
- int cmd;
- int arg;
-};
-
int
linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
{
@@ -195,8 +198,19 @@ linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
int arg;
} */ fcntl_args;
struct linux_flock linux_flock;
- struct flock *bsd_flock =
- (struct flock *)ua_alloc_init(sizeof(struct flock));
+ struct flock *bsd_flock;
+ struct filedesc *fdp;
+ struct file *fp;
+ struct vnode *vp;
+ struct vattr va;
+ long pgid;
+ struct pgrp *pgrp;
+ struct tty *tp, *(*d_tty) __P((dev_t));
+ caddr_t sg;
+
+ sg = stackgap_init();
+ bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(struct flock));
+ d_tty = NULL;
#ifdef DEBUG
printf("Linux-emul(%d): fcntl(%d, %08x, *)\n",
@@ -269,22 +283,51 @@ linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
return fcntl(p, &fcntl_args, retval);
case LINUX_F_SETOWN:
- fcntl_args.cmd = F_SETOWN;
- return fcntl(p, &fcntl_args, retval);
-
case LINUX_F_GETOWN:
- fcntl_args.cmd = F_GETOWN;
- return fcntl(p, &fcntl_args, retval);
+ /*
+ * We need to route around the normal fcntl() for these calls,
+ * since it uses TIOC{G,S}PGRP, which is too restrictive for
+ * Linux F_{G,S}ETOWN semantics. For sockets, this problem
+ * does not exist.
+ */
+ fdp = p->p_fd;
+ if ((u_int)args->fd >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[args->fd]) == NULL)
+ return EBADF;
+ if (fp->f_type == DTYPE_SOCKET) {
+ fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
+ return fcntl(p, &fcntl_args, retval);
+ }
+ vp = (struct vnode *)fp->f_data;
+ if (vp->v_type != VCHR)
+ return EINVAL;
+ if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
+ return error;
+
+ d_tty = cdevsw[major(va.va_rdev)]->d_devtotty;
+ if (!d_tty || (!(tp = (*d_tty)(va.va_rdev))))
+ return EINVAL;
+ if (args->cmd == LINUX_F_GETOWN) {
+ retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
+ return 0;
+ }
+ if ((long)args->arg <= 0) {
+ pgid = -(long)args->arg;
+ } else {
+ struct proc *p1 = pfind((long)args->arg);
+ if (p1 == 0)
+ return (ESRCH);
+ pgid = (long)p1->p_pgrp->pg_id;
+ }
+ pgrp = pgfind(pgid);
+ if (pgrp == NULL || pgrp->pg_session != p->p_session)
+ return EPERM;
+ tp->t_pgrp = pgrp;
+ return 0;
}
return EINVAL;
}
-struct linux_lseek_args {
- int fdes;
- unsigned long off;
- int whence;
-};
-
int
linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval)
{
@@ -308,6 +351,34 @@ linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval)
return error;
}
+int
+linux_llseek(struct proc *p, struct linux_llseek_args *args, int *retval)
+{
+ struct lseek_args bsd_args;
+ int error;
+ off_t off;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n",
+ p->p_pid, args->fd, args->ohigh, args->olow, args->whence);
+#endif
+ off = (args->olow) | (((off_t) args->ohigh) << 32);
+
+ bsd_args.fd = args->fd;
+ bsd_args.offset = off;
+ bsd_args.whence = args->whence;
+
+ if ((error = lseek(p, &bsd_args, retval)))
+ return error;
+
+ if ((error = copyout(retval, (caddr_t)args->res, sizeof (off_t))))
+ return error;
+
+ retval[0] = 0;
+ return 0;
+}
+
+
struct linux_dirent {
long dino;
linux_off_t doff;
@@ -318,15 +389,20 @@ struct linux_dirent {
#define LINUX_RECLEN(de,namlen) \
ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1))
-struct linux_readdir_args {
- int fd;
- struct linux_dirent *dent;
- unsigned int count;
-};
-
int
linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval)
{
+ struct linux_getdents_args lda;
+
+ lda.fd = args->fd;
+ lda.dent = args->dent;
+ lda.count = 1;
+ return linux_getdents(p, &lda, retval);
+}
+
+int
+linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
+{
register struct dirent *bdp;
struct vnode *vp;
caddr_t inp, buf; /* BSD-format */
@@ -342,12 +418,12 @@ linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval)
int buflen, error, eofflag, nbytes, justone, blockoff;
#ifdef DEBUG
- printf("Linux-emul(%d): readdir(%d, *, %d)\n",
+ printf("Linux-emul(%d): getdents(%d, *, %d)\n",
p->p_pid, args->fd, args->count);
#endif
if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) {
return (error);
-}
+ }
if ((fp->f_flag & FREAD) == 0)
return (EBADF);
@@ -390,7 +466,7 @@ again:
(u_int **) NULL);
if (error) {
goto out;
-}
+ }
inp = buf;
inp += blockoff;
@@ -398,7 +474,7 @@ again:
resid = nbytes;
if ((len = buflen - auio.uio_resid - blockoff) == 0) {
goto eof;
- }
+ }
while (len > 0) {
bdp = (struct dirent *) inp;
@@ -426,7 +502,7 @@ again:
strcpy(linux_dirent.dname, bdp->d_name);
if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) {
goto out;
- }
+ }
inp += reclen;
off += reclen;
outp += linuxreclen;
@@ -450,3 +526,238 @@ out:
free(buf, M_TEMP);
return error;
}
+
+/*
+ * These exist mainly for hooks for doing /compat/linux translation.
+ */
+
+int
+linux_access(struct proc *p, struct linux_access_args *args, int *retval)
+{
+ struct access_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): access(%s, %d)\n",
+ p->p_pid, args->path, args->flags);
+#endif
+ bsd.path = args->path;
+ bsd.flags = args->flags;
+
+ return access(p, &bsd, retval);
+}
+
+int
+linux_unlink(struct proc *p, struct linux_unlink_args *args, int *retval)
+{
+ struct unlink_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): unlink(%s)\n",
+ p->p_pid, args->path);
+#endif
+ bsd.path = args->path;
+
+ return unlink(p, &bsd, retval);
+}
+
+int
+linux_chdir(struct proc *p, struct linux_chdir_args *args, int *retval)
+{
+ struct chdir_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): chdir(%s)\n",
+ p->p_pid, args->path);
+#endif
+ bsd.path = args->path;
+
+ return chdir(p, &bsd, retval);
+}
+
+int
+linux_chmod(struct proc *p, struct linux_chmod_args *args, int *retval)
+{
+ struct chmod_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): chmod(%s, %d)\n",
+ p->p_pid, args->path, args->mode);
+#endif
+ bsd.path = args->path;
+ bsd.mode = args->mode;
+
+ return chmod(p, &bsd, retval);
+}
+
+int
+linux_chown(struct proc *p, struct linux_chown_args *args, int *retval)
+{
+ struct chown_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): chown(%s, %d, %d)\n",
+ p->p_pid, args->path, args->uid, args->gid);
+#endif
+ bsd.path = args->path;
+ /* XXX size casts here */
+ bsd.uid = args->uid;
+ bsd.gid = args->gid;
+
+ return chown(p, &bsd, retval);
+}
+
+int
+linux_mkdir(struct proc *p, struct linux_mkdir_args *args, int *retval)
+{
+ struct mkdir_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTCREAT(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): mkdir(%s, %d)\n",
+ p->p_pid, args->path, args->mode);
+#endif
+ bsd.path = args->path;
+ bsd.mode = args->mode;
+
+ return mkdir(p, &bsd, retval);
+}
+
+int
+linux_rmdir(struct proc *p, struct linux_rmdir_args *args, int *retval)
+{
+ struct rmdir_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): rmdir(%s)\n",
+ p->p_pid, args->path);
+#endif
+ bsd.path = args->path;
+
+ return rmdir(p, &bsd, retval);
+}
+
+int
+linux_rename(struct proc *p, struct linux_rename_args *args, int *retval)
+{
+ struct rename_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->from);
+ CHECKALTCREAT(p, &sg, args->to);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): rename(%s, %s)\n",
+ p->p_pid, args->from, args->to);
+#endif
+ bsd.from = args->from;
+ bsd.to = args->to;
+
+ return rename(p, &bsd, retval);
+}
+
+int
+linux_symlink(struct proc *p, struct linux_symlink_args *args, int *retval)
+{
+ struct symlink_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+ CHECKALTCREAT(p, &sg, args->to);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): symlink(%s, %s)\n",
+ p->p_pid, args->path, args->to);
+#endif
+ bsd.path = args->path;
+ bsd.link = args->to;
+
+ return symlink(p, &bsd, retval);
+}
+
+int
+linux_execve(struct proc *p, struct linux_execve_args *args, int *retval)
+{
+ struct execve_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): execve(%s)\n",
+ p->p_pid, args->path);
+#endif
+ bsd.fname = args->path;
+ bsd.argv = args->argp;
+ bsd.envv = args->envp;
+
+ return execve(p, &bsd, retval);
+}
+
+int
+linux_readlink(struct proc *p, struct linux_readlink_args *args, int *retval)
+{
+ struct readlink_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->name);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): readlink(%s, 0x%x, %d)\n",
+ p->p_pid, args->name, args->buf, args->count);
+#endif
+ bsd.path = args->name;
+ bsd.buf = args->buf;
+ bsd.count = args->count;
+
+ return readlink(p, &bsd, retval);
+}
+
+int
+linux_truncate(struct proc *p, struct linux_truncate_args *args, int *retval)
+{
+ struct otruncate_args bsd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): truncate(%s)\n",
+ p->p_pid, args->path);
+#endif
+ bsd.path = args->path;
+
+ return otruncate(p, &bsd, retval);
+}
+
diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c
new file mode 100644
index 0000000..c522948
--- /dev/null
+++ b/sys/i386/linux/linux_genassym.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/proc.h>
+#include <i386/linux/linux.h>
+
+extern int main __P((void));
+
+int
+main()
+{
+ struct linux_sigframe *linux_sigf = (struct linux_sigframe *)0;
+ struct linux_sigcontext *linux_sc = (struct linux_sigcontext *)0;
+
+ printf("#define\tLINUX_SIGF_HANDLER %d\n", &linux_sigf->sf_handler);
+ printf("#define\tLINUX_SIGF_SC %d\n", &linux_sigf->sf_sc);
+ printf("#define\tLINUX_SC_FS %d\n", &linux_sc->sc_fs);
+ printf("#define\tLINUX_SC_GS %d\n", &linux_sc->sc_gs);
+ printf("#define\tLINUX_SC_EFLAGS %d\n", &linux_sc->sc_eflags);
+
+ return (0);
+}
diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c
index 03bc031..9680928 100644
--- a/sys/i386/linux/linux_ioctl.c
+++ b/sys/i386/linux/linux_ioctl.c
@@ -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_ioctl.c,v 1.4 1995/12/29 22:12:12 sos Exp $
+ * $Id: linux_ioctl.c,v 1.5 1995/12/30 00:42:25 sos Exp $
*/
#include <sys/param.h>
@@ -38,12 +38,16 @@
#include <sys/filedesc.h>
#include <sys/tty.h>
#include <sys/termios.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <sys/sockio.h>
#include <machine/console.h>
#include <machine/soundcard.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux_proto.h>
struct linux_termios {
unsigned long c_iflag;
@@ -351,13 +355,6 @@ linux_to_bsd_termios(struct linux_termios *linux_termios,
#endif
}
-
-struct linux_ioctl_args {
- int fd;
- int cmd;
- int arg;
-};
-
int
linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval)
{
@@ -456,6 +453,38 @@ linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval)
args->cmd = TIOCNOTTY;
return ioctl(p, (struct ioctl_args *)args, retval);
+ case LINUX_SIOCGIFCONF:
+ args->cmd = OSIOCGIFCONF;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCGIFFLAGS:
+ args->cmd = SIOCGIFFLAGS;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCGIFADDR:
+ args->cmd = OSIOCGIFADDR;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCGIFDSTADDR:
+ args->cmd = OSIOCGIFDSTADDR;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCGIFBRDADDR:
+ args->cmd = OSIOCGIFBRDADDR;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCGIFNETMASK:
+ args->cmd = OSIOCGIFNETMASK;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCADDMULTI:
+ args->cmd = SIOCADDMULTI;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
+ case LINUX_SIOCDELMULTI:
+ args->cmd = SIOCDELMULTI;
+ return ioctl(p, (struct ioctl_args *)args, retval);
+
case LINUX_TIOCSETD:
switch (args->arg) {
case LINUX_N_TTY:
diff --git a/sys/i386/linux/linux_ipc.c b/sys/i386/linux/linux_ipc.c
index 2e5b924..854766b 100644
--- a/sys/i386/linux/linux_ipc.c
+++ b/sys/i386/linux/linux_ipc.c
@@ -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_ipc.c,v 1.5 1996/01/05 19:52:49 wollman Exp $
+ * $Id: linux_ipc.c,v 1.6 1996/01/08 04:34:54 peter Exp $
*/
@@ -36,7 +36,20 @@
#include <sys/shm.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
+
+static int linux_semop __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_semget __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_semctl __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_msgsnd __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_msgrcv __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_msgop __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_msgctl __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_shmat __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_shmdt __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_shmget __P((struct proc *, struct linux_ipc_args *, int *));
+static int linux_shmctl __P((struct proc *, struct linux_ipc_args *, int *));
struct linux_ipc_perm {
linux_key_t key;
@@ -115,33 +128,25 @@ bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct linux_shmid_ds *lsp)
lsp->private3 = bsp->shm_internal; /* this goes (yet) SOS */
}
-struct linux_ipc_args {
- int what;
- int arg1;
- int arg2;
- int arg3;
- caddr_t ptr;
-};
-
-int
+static int
linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
-int
+static int
linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
-int
+static int
linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
return ENOSYS;
}
-int
+static int
linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct msgsnd_args /* {
@@ -158,7 +163,7 @@ linux_msgsnd(struct proc *p, struct linux_ipc_args *args, int *retval)
return msgsnd(p, &bsd_args, retval);
}
-int
+static int
linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct msgrcv_args /* {
@@ -177,7 +182,7 @@ linux_msgrcv(struct proc *p, struct linux_ipc_args *args, int *retval)
return msgrcv(p, &bsd_args, retval);
}
-int
+static int
linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct msgget_args /* {
@@ -190,7 +195,7 @@ linux_msgget(struct proc *p, struct linux_ipc_args *args, int *retval)
return msgget(p, &bsd_args, retval);
}
-int
+static int
linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct msgctl_args /* {
@@ -205,7 +210,7 @@ linux_msgctl(struct proc *p, struct linux_ipc_args *args, int *retval)
return msgctl(p, &bsd_args, retval);
}
-int
+static int
linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmat_args /* {
@@ -226,7 +231,7 @@ linux_shmat(struct proc *p, struct linux_ipc_args *args, int *retval)
return 0;
}
-int
+static int
linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmdt_args /* {
@@ -237,7 +242,7 @@ linux_shmdt(struct proc *p, struct linux_ipc_args *args, int *retval)
return shmdt(p, &bsd_args, retval);
}
-int
+static int
linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmget_args /* {
@@ -252,7 +257,7 @@ linux_shmget(struct proc *p, struct linux_ipc_args *args, int *retval)
return shmget(p, &bsd_args, retval);
}
-int
+static int
linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
{
struct shmid_ds bsd_shmid;
@@ -263,12 +268,13 @@ linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
struct shmid_ds *buf;
} */ bsd_args;
int error;
+ caddr_t sg = stackgap_init();
switch (args->arg2) {
case LINUX_IPC_STAT:
bsd_args.shmid = args->arg1;
bsd_args.cmd = IPC_STAT;
- bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
+ bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
if ((error = shmctl(p, &bsd_args, retval)))
return error;
if ((error = copyin((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
@@ -282,7 +288,7 @@ linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
- bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
+ bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
@@ -297,7 +303,7 @@ linux_shmctl(struct proc *p, struct linux_ipc_args *args, int *retval)
sizeof(linux_shmid))))
return error;
linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
- bsd_args.buf = (struct shmid_ds*)ua_alloc_init(sizeof(struct shmid_ds));
+ bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
sizeof(struct shmid_ds))))
return error;
diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s
new file mode 100644
index 0000000..1440218
--- /dev/null
+++ b/sys/i386/linux/linux_locore.s
@@ -0,0 +1,26 @@
+#include "linux_assym.h" /* system definitions */
+#include <machine/asmacros.h> /* miscellaneous asm macros */
+
+#include <i386/linux/linux_syscall.h> /* system call numbers */
+
+NON_GPROF_ENTRY(linux_sigcode)
+ call LINUX_SIGF_HANDLER(%esp)
+ leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
+ movl LINUX_SC_FS(%ebx),%ecx
+ movl LINUX_SC_GS(%ebx),%edx
+ movl %cx,%fs
+ movl %dx,%gs
+ push %eax /* fake ret addr */
+ movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
+ int $0x80 /* enter kernel with args on stack */
+ hlt /* never gets here */
+
+ .align 2 /* long word align */
+_linux_esigcode:
+
+ .data
+ .globl _linux_szsigcode
+_linux_szsigcode:
+ .long _linux_esigcode-_linux_sigcode
+
+ .text
diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c
index bc6e8d8..069ca28 100644
--- a/sys/i386/linux/linux_misc.c
+++ b/sys/i386/linux/linux_misc.c
@@ -6,7 +6,7 @@
* 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
+ * notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
@@ -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.11 1996/01/19 22:59:24 dyson Exp $
+ * $Id: linux_misc.c,v 1.12 1996/02/16 18:40:50 peter Exp $
*/
#include <sys/param.h>
@@ -50,6 +50,7 @@
#include <sys/utsname.h>
#include <sys/vnode.h>
#include <sys/wait.h>
+#include <sys/time.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -64,11 +65,8 @@
#include <machine/psl.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
-
-struct linux_alarm_args {
- unsigned int secs;
-};
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
int
linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval)
@@ -110,10 +108,6 @@ linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval)
return 0;
}
-struct linux_brk_args {
- linux_caddr_t dsend;
-};
-
int
linux_brk(struct proc *p, struct linux_brk_args *args, int *retval)
{
@@ -136,7 +130,7 @@ linux_brk(struct proc *p, struct linux_brk_args *args, int *retval)
return ENOMEM;
error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE,
VM_PROT_ALL, VM_PROT_ALL, 0);
- if (error)
+ if (error)
return error;
vm->vm_dsize += btoc((new-old));
*retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize));
@@ -164,10 +158,6 @@ linux_brk(struct proc *p, struct linux_brk_args *args, int *retval)
#endif
}
-struct linux_uselib_args {
- char *library;
-};
-
int
linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
{
@@ -178,12 +168,13 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
unsigned long vmaddr, file_offset;
unsigned long buffer, bss_size;
char *ptr;
- char path[MAXPATHLEN];
- const char *prefix = "/compat/linux";
- size_t sz, len;
int error;
+ caddr_t sg;
int locked;
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->library);
+
#ifdef DEBUG
printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library);
#endif
@@ -192,20 +183,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
locked = 0;
vp = NULL;
- for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ;
- sz = MAXPATHLEN - (ptr - path);
- if (error = copyinstr(args->library, ptr, sz, &len))
- goto cleanup;
- if (*ptr != '/') {
- error = EINVAL;
- goto cleanup;
- }
-
-#ifdef DEBUG
- printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path);
-#endif
-
- NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p);
+ NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, args->library, p);
if (error = namei(&ni))
goto cleanup;
@@ -361,7 +339,7 @@ printf("uselib: Non page aligned binary %d\n", file_offset);
goto cleanup;
/* copy from kernel VM space to user space */
- error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr,
+ error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr,
a_out->a_text + a_out->a_data);
/* release temporary kernel space */
@@ -404,7 +382,7 @@ printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]);
/*
* allocate some 'anon' space
*/
- error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
+ error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr,
bss_size, FALSE,
VM_PROT_ALL, VM_PROT_ALL, 0);
if (error)
@@ -427,49 +405,138 @@ cleanup:
return error;
}
-struct linux_select_args {
- void *ptr;
+/* XXX move */
+struct linux_select_argv {
+ int nfds;
+ fd_set *readfds;
+ fd_set *writefds;
+ fd_set *exceptfds;
+ struct timeval *timeout;
};
int
linux_select(struct proc *p, struct linux_select_args *args, int *retval)
{
- struct {
- int nfds;
- fd_set *readfds;
- fd_set *writefds;
- fd_set *exceptfds;
- struct timeval *timeout;
- } linux_args;
- struct select_args /* {
- unsigned int nd;
- fd_set *in;
- fd_set *ou;
- fd_set *ex;
- struct timeval *tv;
- } */ bsd_args;
+ struct linux_select_argv linux_args;
+ struct linux_newselect_args newsel;
int error;
+#ifdef SELECT_DEBUG
+ printf("Linux-emul(%d): select(%x)\n",
+ p->p_pid, args->ptr);
+#endif
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
+
+ newsel.nfds = linux_args.nfds;
+ newsel.readfds = linux_args.readfds;
+ newsel.writefds = linux_args.writefds;
+ newsel.exceptfds = linux_args.exceptfds;
+ newsel.timeout = linux_args.timeout;
+
+ return linux_newselect(p, &newsel, retval);
+}
+
+int
+linux_newselect(struct proc *p, struct linux_newselect_args *args, int *retval)
+{
+ struct select_args bsa;
+ struct timeval tv0, tv1, utv, *tvp;
+ caddr_t sg;
+ int error;
+
#ifdef DEBUG
- printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n",
- p->p_pid, linux_args.nfds, linux_args.readfds,
- linux_args.writefds, linux_args.exceptfds,
- linux_args.timeout);
+ printf("Linux-emul(%d): newselect(%d, %x, %x, %x, %x)\n",
+ p->p_pid, args->nfds, args->readfds, args->writefds,
+ args->exceptfds, args->timeout);
#endif
- bsd_args.nd = linux_args.nfds;
- bsd_args.in = linux_args.readfds;
- bsd_args.ou = linux_args.writefds;
- bsd_args.ex = linux_args.exceptfds;
- bsd_args.tv = linux_args.timeout;
- return select(p, &bsd_args, retval);
-}
+ error = 0;
+ bsa.nd = args->nfds;
+ bsa.in = args->readfds;
+ bsa.ou = args->writefds;
+ bsa.ex = args->exceptfds;
+ bsa.tv = args->timeout;
-struct linux_getpgid_args {
- int pid;
-};
+ /*
+ * Store current time for computation of the amount of
+ * time left.
+ */
+ if (args->timeout) {
+ if ((error = copyin(args->timeout, &utv, sizeof(utv))))
+ goto select_out;
+#ifdef DEBUG
+ printf("Linux-emul(%d): incoming timeout (%d/%d)\n",
+ p->p_pid, utv.tv_sec, utv.tv_usec);
+#endif
+ if (itimerfix(&utv)) {
+ /*
+ * The timeval was invalid. Convert it to something
+ * valid that will act as it does under Linux.
+ */
+ sg = stackgap_init();
+ tvp = stackgap_alloc(&sg, sizeof(utv));
+ utv.tv_sec += utv.tv_usec / 1000000;
+ utv.tv_usec %= 1000000;
+ if (utv.tv_usec < 0) {
+ utv.tv_sec -= 1;
+ utv.tv_usec += 1000000;
+ }
+ if (utv.tv_sec < 0)
+ timerclear(&utv);
+ if ((error = copyout(&utv, tvp, sizeof(utv))))
+ goto select_out;
+ bsa.tv = tvp;
+ }
+ microtime(&tv0);
+ }
+
+ error = select(p, &bsa, retval);
+#ifdef DEBUG
+ printf("Linux-emul(%d): real select returns %d\n",
+ p->p_pid, error);
+#endif
+
+ if (error) {
+ /*
+ * See fs/select.c in the Linux kernel. Without this,
+ * Maelstrom doesn't work.
+ */
+ if (error == ERESTART)
+ error = EINTR;
+ goto select_out;
+ }
+
+ if (args->timeout) {
+ if (*retval) {
+ /*
+ * Compute how much time was left of the timeout,
+ * by subtracting the current time and the time
+ * before we started the call, and subtracting
+ * that result from the user-supplied value.
+ */
+ microtime(&tv1);
+ timevalsub(&tv1, &tv0);
+ timevalsub(&utv, &tv1);
+ if (utv.tv_sec < 0)
+ timerclear(&utv);
+ } else
+ timerclear(&utv);
+#ifdef DEBUG
+ printf("Linux-emul(%d): outgoing timeout (%d/%d)\n",
+ p->p_pid, utv.tv_sec, utv.tv_usec);
+#endif
+ if ((error = copyout(&utv, args->timeout, sizeof(utv))))
+ goto select_out;
+ }
+
+select_out:
+#ifdef DEBUG
+ printf("Linux-emul(%d): newselect_out -> %d\n",
+ p->p_pid, error);
+#endif
+ return error;
+}
int
linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval)
@@ -490,35 +557,33 @@ linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval)
}
int
-linux_fork(struct proc *p, void *args, int *retval)
+linux_fork(struct proc *p, struct linux_fork_args *args, int *retval)
{
int error;
#ifdef DEBUG
printf("Linux-emul(%d): fork()\n", p->p_pid);
#endif
- if (error = fork(p, args, retval))
+ if (error = fork(p, (struct fork_args *)args, retval))
return error;
if (retval[1] == 1)
retval[0] = 0;
return 0;
}
-struct linux_mmap_args {
- void *ptr;
-};
-
-int
-linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
-{
- struct {
+/* XXX move */
+struct linux_mmap_argv {
linux_caddr_t addr;
int len;
int prot;
int flags;
int fd;
int pos;
- } linux_args;
+};
+
+int
+linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
+{
struct mmap_args /* {
caddr_t addr;
size_t len;
@@ -529,13 +594,14 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
off_t pos;
} */ bsd_args;
int error;
+ struct linux_mmap_argv linux_args;
if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args,
sizeof(linux_args))))
return error;
#ifdef DEBUG
printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n",
- p->p_pid, linux_args.addr, linux_args.len, linux_args.prot,
+ p->p_pid, linux_args.addr, linux_args.len, linux_args.prot,
linux_args.flags, linux_args.fd, linux_args.pos);
#endif
bsd_args.flags = 0;
@@ -556,9 +622,17 @@ linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval)
return mmap(p, &bsd_args, retval);
}
-struct linux_pipe_args {
- int *pipefds;
-};
+int
+linux_msync(struct proc *p, struct linux_msync_args *args, int *retval)
+{
+ struct msync_args bsd_args;
+
+ bsd_args.addr = args->addr;
+ bsd_args.len = args->len;
+ bsd_args.flags = 0; /* XXX ignore */
+
+ return msync(p, &bsd_args, retval);
+}
int
linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval)
@@ -576,10 +650,6 @@ linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval)
return 0;
}
-struct linux_time_args {
- linux_time_t *tm;
-};
-
int
linux_time(struct proc *p, struct linux_time_args *args, int *retval)
{
@@ -592,28 +662,24 @@ linux_time(struct proc *p, struct linux_time_args *args, int *retval)
#endif
microtime(&tv);
tm = tv.tv_sec;
- if (error = copyout(&tm, args->tm, sizeof(linux_time_t)))
+ if (args->tm && (error = copyout(&tm, args->tm, sizeof(linux_time_t))))
return error;
- *retval = tv.tv_sec;
+ *retval = tm;
return 0;
}
-struct linux_tms {
+struct linux_times_argv {
long tms_utime;
long tms_stime;
long tms_cutime;
long tms_cstime;
};
-struct linux_tms_args {
- char *buf;
-};
-
int
-linux_times(struct proc *p, struct linux_tms_args *args, int *retval)
+linux_times(struct proc *p, struct linux_times_args *args, int *retval)
{
struct timeval tv;
- struct linux_tms tms;
+ struct linux_times_argv tms;
#ifdef DEBUG
printf("Linux-emul(%d): times(*)\n", p->p_pid);
@@ -627,9 +693,10 @@ linux_times(struct proc *p, struct linux_tms_args *args, int *retval)
microtime(&tv);
*retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000;
return (copyout((caddr_t)&tms, (caddr_t)args->buf,
- sizeof(struct linux_tms)));
+ sizeof(struct linux_times_argv)));
}
+/* XXX move */
struct linux_newuname_t {
char sysname[65];
char nodename[65];
@@ -639,10 +706,6 @@ struct linux_newuname_t {
char domainname[65];
};
-struct linux_newuname_args {
- char *buf;
-};
-
int
linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval)
{
@@ -662,10 +725,6 @@ linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval)
sizeof(struct linux_newuname_t)));
}
-struct linux_utime_args {
- char *fname;
- linux_time_t *timeptr;
-};
int
linux_utime(struct proc *p, struct linux_utime_args *args, int *retval)
@@ -675,23 +734,21 @@ linux_utime(struct proc *p, struct linux_utime_args *args, int *retval)
struct timeval *tptr;
} */ bsdutimes;
struct timeval tv;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->fname);
#ifdef DEBUG
printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname);
#endif
- tv.tv_sec = (long)args->timeptr;
+ tv.tv_sec = (long)args->timeptr; /* XXX: wrong?? */
tv.tv_usec = 0;
bsdutimes.tptr = &tv;
bsdutimes.path = args->fname;
return utimes(p, &bsdutimes, retval);
}
-struct linux_waitpid_args {
- int pid;
- int *status;
- int options;
-};
-
int
linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval)
{
@@ -704,8 +761,8 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval)
int error, tmpstat;
#ifdef DEBUG
- printf("Linux-emul(%d): waitpid(%d, *, %d)\n",
- p->p_pid, args->pid, args->options);
+ printf("Linux-emul(%d): waitpid(%d, 0x%x, %d)\n",
+ p->p_pid, args->pid, args->status, args->options);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
@@ -714,25 +771,21 @@ linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval)
if (error = wait4(p, &tmp, retval))
return error;
- if (error = copyin(args->status, &tmpstat, sizeof(int)))
- return error;
- if (WIFSIGNALED(tmpstat))
- tmpstat = (tmpstat & 0xffffff80) |
- bsd_to_linux_signal[WTERMSIG(tmpstat)];
- else if (WIFSTOPPED(tmpstat))
- tmpstat = (tmpstat & 0xffff00ff) |
- (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
- return copyout(&tmpstat, args->status, sizeof(int));
+ if (args->status) {
+ if (error = copyin(args->status, &tmpstat, sizeof(int)))
+ return error;
+ if (WIFSIGNALED(tmpstat))
+ tmpstat = (tmpstat & 0xffffff80) |
+ bsd_to_linux_signal[WTERMSIG(tmpstat)];
+ else if (WIFSTOPPED(tmpstat))
+ tmpstat = (tmpstat & 0xffff00ff) |
+ (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
+ return copyout(&tmpstat, args->status, sizeof(int));
+ } else
+ return 0;
}
-struct linux_wait4_args {
- int pid;
- int *status;
- int options;
- struct rusage *rusage;
-};
-
-int
+int
linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval)
{
struct wait_args /* {
@@ -744,8 +797,8 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval)
int error, tmpstat;
#ifdef DEBUG
- printf("Linux-emul(%d): wait4(%d, *, %d, *)\n",
- p->p_pid, args->pid, args->options);
+ printf("Linux-emul(%d): wait4(%d, 0x%x, %d, 0x%x)\n",
+ p->p_pid, args->pid, args->status, args->options, args->rusage);
#endif
tmp.pid = args->pid;
tmp.status = args->status;
@@ -754,28 +807,108 @@ linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval)
if (error = wait4(p, &tmp, retval))
return error;
- if (error = copyin(args->status, &tmpstat, sizeof(int)))
- return error;
- if (WIFSIGNALED(tmpstat))
- tmpstat = (tmpstat & 0xffffff80) |
- bsd_to_linux_signal[WTERMSIG(tmpstat)];
- else if (WIFSTOPPED(tmpstat))
- tmpstat = (tmpstat & 0xffff00ff) |
- (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
- return copyout(&tmpstat, args->status, sizeof(int));
-}
-struct linux_mknod_args {
- char *path;
- int mode;
- int dev;
-};
+ p->p_siglist &= ~sigmask(SIGCHLD);
+
+ if (args->status) {
+ if (error = copyin(args->status, &tmpstat, sizeof(int)))
+ return error;
+ if (WIFSIGNALED(tmpstat))
+ tmpstat = (tmpstat & 0xffffff80) |
+ bsd_to_linux_signal[WTERMSIG(tmpstat)];
+ else if (WIFSTOPPED(tmpstat))
+ tmpstat = (tmpstat & 0xffff00ff) |
+ (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8);
+ return copyout(&tmpstat, args->status, sizeof(int));
+ } else
+ return 0;
+}
-int
+int
linux_mknod(struct proc *p, struct linux_mknod_args *args, int *retval)
{
- if (args->mode & S_IFIFO)
- return mkfifo(p, (struct mkfifo_args *)args, retval);
- else
- return mknod(p, (struct mknod_args *)args, retval);
+ caddr_t sg;
+ struct mknod_args bsd_mknod;
+ struct mkfifo_args bsd_mkfifo;
+
+ sg = stackgap_init();
+
+ CHECKALTCREAT(p, &sg, args->path);
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): mknod(%s, %d, %d)\n",
+ p->p_pid, args->path, args->mode, args->dev);
+#endif
+
+ if (args->mode & S_IFIFO) {
+ bsd_mkfifo.path = args->path;
+ bsd_mkfifo.mode = args->mode;
+ return mkfifo(p, &bsd_mkfifo, retval);
+ } else {
+ bsd_mknod.path = args->path;
+ bsd_mknod.mode = args->mode;
+ bsd_mknod.dev = args->dev;
+ return mknod(p, &bsd_mknod, retval);
+ }
+}
+
+/*
+ * UGH! This is just about the dumbest idea I've ever heard!!
+ */
+int
+linux_personality(struct proc *p, struct linux_personality_args *args,
+ int *retval)
+{
+#ifdef DEBUG
+ printf("Linux-emul(%d): personality(%d)\n",
+ p->p_pid, args->per);
+#endif
+ if (args->per != 0)
+ return EINVAL;
+
+ /* Yes Jim, it's still a Linux... */
+ retval[0] = 0;
+ return 0;
+}
+
+/*
+ * Wrappers for get/setitimer for debugging..
+ */
+int
+linux_setitimer(struct proc *p, struct linux_setitimer_args *args, int *retval)
+{
+ struct setitimer_args bsa;
+ struct itimerval foo;
+ int error;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): setitimer(%08x, %08x)\n",
+ p->p_pid, args->itv, args->oitv);
+#endif
+ bsa.which = args->which;
+ bsa.itv = args->itv;
+ bsa.oitv = args->oitv;
+ if (args->itv) {
+ if ((error = copyin((caddr_t)args->itv, (caddr_t)&foo,
+ sizeof(foo))))
+ return error;
+#ifdef DEBUG
+ printf("setitimer: value: sec: %d, usec: %d\n", foo.it_value.tv_sec, foo.it_value.tv_usec);
+ printf("setitimer: interval: sec: %d, usec: %d\n", foo.it_interval.tv_sec, foo.it_interval.tv_usec);
+#endif
+ }
+ return setitimer(p, &bsa, retval);
+}
+
+int
+linux_getitimer(struct proc *p, struct linux_getitimer_args *args, int *retval)
+{
+ struct getitimer_args bsa;
+#ifdef DEBUG
+ printf("Linux-emul(%d): getitimer(%08x)\n",
+ p->p_pid, args->itv);
+#endif
+ bsa.which = args->which;
+ bsa.itv = args->itv;
+ return getitimer(p, &bsa, retval);
}
diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h
new file mode 100644
index 0000000..a227f2c
--- /dev/null
+++ b/sys/i386/linux/linux_proto.h
@@ -0,0 +1,465 @@
+/*
+ * System call prototypes.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * created from Id: syscalls.master,v 1.1 1996/03/02 19:04:15 peter Exp
+ */
+
+#ifndef _LINUX_SYSPROTO_H_
+#define _LINUX_SYSPROTO_H_
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+
+struct linux_setup_args {
+ int dummy;
+};
+struct linux_fork_args {
+ int dummy;
+};
+struct linux_open_args {
+ char * path;
+ int flags;
+ int mode;
+};
+struct linux_waitpid_args {
+ int pid;
+ int * status;
+ int options;
+};
+struct linux_creat_args {
+ char * path;
+ int mode;
+};
+struct linux_unlink_args {
+ char * path;
+};
+struct linux_execve_args {
+ char * path;
+ char ** argp;
+ char ** envp;
+};
+struct linux_chdir_args {
+ char * path;
+};
+struct linux_time_args {
+ linux_time_t * tm;
+};
+struct linux_mknod_args {
+ char * path;
+ int mode;
+ int dev;
+};
+struct linux_chmod_args {
+ char * path;
+ int mode;
+};
+struct linux_chown_args {
+ char * path;
+ int uid;
+ int gid;
+};
+struct linux_break_args {
+ char * nsize;
+};
+struct linux_stat_args {
+ char * path;
+ struct ostat * up;
+};
+struct linux_lseek_args {
+ int fdes;
+ long off;
+ int whence;
+};
+struct linux_mount_args {
+ int dummy;
+};
+struct linux_umount_args {
+ int dummy;
+};
+struct linux_stime_args {
+ int dummy;
+};
+struct linux_ptrace_args {
+ int dummy;
+};
+struct linux_alarm_args {
+ unsigned int secs;
+};
+struct linux_fstat_args {
+ int fd;
+ struct ostat * up;
+};
+struct linux_pause_args {
+ int dummy;
+};
+struct linux_utime_args {
+ char * fname;
+ struct linux_time_t * timeptr;
+};
+struct linux_stty_args {
+ int dummy;
+};
+struct linux_gtty_args {
+ int dummy;
+};
+struct linux_access_args {
+ char * path;
+ int flags;
+};
+struct linux_nice_args {
+ int dummy;
+};
+struct linux_ftime_args {
+ int dummy;
+};
+struct linux_kill_args {
+ int pid;
+ int signum;
+};
+struct linux_rename_args {
+ char * from;
+ char * to;
+};
+struct linux_mkdir_args {
+ char * path;
+ int mode;
+};
+struct linux_rmdir_args {
+ char * path;
+};
+struct linux_pipe_args {
+ int * pipefds;
+};
+struct linux_times_args {
+ struct linux_times_argv * buf;
+};
+struct linux_prof_args {
+ int dummy;
+};
+struct linux_brk_args {
+ char * dsend;
+};
+struct linux_signal_args {
+ int sig;
+ linux_handler_t handler;
+};
+struct linux_phys_args {
+ int dummy;
+};
+struct linux_lock_args {
+ int dummy;
+};
+struct linux_ioctl_args {
+ int fd;
+ u_long cmd;
+ int arg;
+};
+struct linux_fcntl_args {
+ int fd;
+ int cmd;
+ int arg;
+};
+struct linux_mpx_args {
+ int dummy;
+};
+struct linux_ulimit_args {
+ int dummy;
+};
+struct linux_olduname_args {
+ struct linux_oldold_utsname * up;
+};
+struct linux_ustat_args {
+ int dummy;
+};
+struct linux_sigaction_args {
+ int sig;
+ struct linux_sigaction * nsa;
+ struct linux_sigaction * osa;
+};
+struct linux_siggetmask_args {
+ int dummy;
+};
+struct linux_sigsetmask_args {
+ linux_sigset_t mask;
+};
+struct linux_sigsuspend_args {
+ linux_sigset_t mask;
+};
+struct linux_sigpending_args {
+ linux_sigset_t * mask;
+};
+struct linux_select_args {
+ struct linux_select_argv * ptr;
+};
+struct linux_symlink_args {
+ char * path;
+ char * to;
+};
+struct linux_readlink_args {
+ char * name;
+ char * buf;
+ int count;
+};
+struct linux_uselib_args {
+ char * library;
+};
+struct linux_readdir_args {
+ int fd;
+ struct linux_dirent * dent;
+ unsigned int count;
+};
+struct linux_mmap_args {
+ struct linux_mmap_argv * ptr;
+};
+struct linux_truncate_args {
+ char * path;
+ long length;
+};
+struct linux_statfs_args {
+ char * path;
+ struct linux_statfs_buf * buf;
+};
+struct linux_fstatfs_args {
+ int fd;
+ struct linux_statfs_buf * buf;
+};
+struct linux_ioperm_args {
+ unsigned int lo;
+ unsigned int hi;
+ int val;
+};
+struct linux_socketcall_args {
+ int what;
+ void * args;
+};
+struct linux_ksyslog_args {
+ int what;
+};
+struct linux_setitimer_args {
+ u_int which;
+ struct itimerval * itv;
+ struct itimerval * oitv;
+};
+struct linux_getitimer_args {
+ u_int which;
+ struct itimerval * itv;
+};
+struct linux_newstat_args {
+ char * path;
+ struct linux_newstat * buf;
+};
+struct linux_newlstat_args {
+ char * path;
+ struct linux_newstat * buf;
+};
+struct linux_newfstat_args {
+ int fd;
+ struct linux_newstat * buf;
+};
+struct linux_uname_args {
+ struct linux_old_utsname * up;
+};
+struct linux_iopl_args {
+ int level;
+};
+struct linux_vhangup_args {
+ int dummy;
+};
+struct linux_idle_args {
+ int dummy;
+};
+struct linux_vm86_args {
+ int dummy;
+};
+struct linux_wait4_args {
+ int pid;
+ int * status;
+ int options;
+ struct rusage * rusage;
+};
+struct linux_swapoff_args {
+ int dummy;
+};
+struct linux_sysinfo_args {
+ int dummy;
+};
+struct linux_ipc_args {
+ int what;
+ int arg1;
+ int arg2;
+ int arg3;
+ caddr_t ptr;
+};
+struct linux_sigreturn_args {
+ struct linux_sigcontext * scp;
+};
+struct linux_clone_args {
+ int dummy;
+};
+struct linux_newuname_args {
+ struct linux_newuname_t * buf;
+};
+struct linux_modify_ldt_args {
+ int func;
+ void * ptr;
+ size_t bytecount;
+};
+struct linux_adjtimex_args {
+ int dummy;
+};
+struct linux_sigprocmask_args {
+ int how;
+ linux_sigset_t * mask;
+ linux_sigset_t * omask;
+};
+struct linux_create_module_args {
+ int dummy;
+};
+struct linux_init_module_args {
+ int dummy;
+};
+struct linux_delete_module_args {
+ int dummy;
+};
+struct linux_get_kernel_syms_args {
+ int dummy;
+};
+struct linux_quotactl_args {
+ int dummy;
+};
+struct linux_getpgid_args {
+ int pid;
+};
+struct linux_bdflush_args {
+ int dummy;
+};
+struct linux_personality_args {
+ int per;
+};
+struct linux_llseek_args {
+ int fd;
+ u_int32_t ohigh;
+ u_int32_t olow;
+ caddr_t res;
+ int whence;
+};
+struct linux_getdents_args {
+ int fd;
+ void * dent;
+ unsigned count;
+};
+struct linux_newselect_args {
+ int nfds;
+ fd_set * readfds;
+ fd_set * writefds;
+ fd_set * exceptfds;
+ struct timeval * timeout;
+};
+struct linux_msync_args {
+ caddr_t addr;
+ int len;
+ int fl;
+};
+int linux_setup __P((struct proc *, struct linux_setup_args *, int []));
+int linux_fork __P((struct proc *, struct linux_fork_args *, int []));
+int linux_open __P((struct proc *, struct linux_open_args *, int []));
+int linux_waitpid __P((struct proc *, struct linux_waitpid_args *, int []));
+int linux_creat __P((struct proc *, struct linux_creat_args *, int []));
+int linux_unlink __P((struct proc *, struct linux_unlink_args *, int []));
+int linux_execve __P((struct proc *, struct linux_execve_args *, int []));
+int linux_chdir __P((struct proc *, struct linux_chdir_args *, int []));
+int linux_time __P((struct proc *, struct linux_time_args *, int []));
+int linux_mknod __P((struct proc *, struct linux_mknod_args *, int []));
+int linux_chmod __P((struct proc *, struct linux_chmod_args *, int []));
+int linux_chown __P((struct proc *, struct linux_chown_args *, int []));
+int linux_break __P((struct proc *, struct linux_break_args *, int []));
+int linux_stat __P((struct proc *, struct linux_stat_args *, int []));
+int linux_lseek __P((struct proc *, struct linux_lseek_args *, int []));
+int linux_mount __P((struct proc *, struct linux_mount_args *, int []));
+int linux_umount __P((struct proc *, struct linux_umount_args *, int []));
+int linux_stime __P((struct proc *, struct linux_stime_args *, int []));
+int linux_ptrace __P((struct proc *, struct linux_ptrace_args *, int []));
+int linux_alarm __P((struct proc *, struct linux_alarm_args *, int []));
+int linux_fstat __P((struct proc *, struct linux_fstat_args *, int []));
+int linux_pause __P((struct proc *, struct linux_pause_args *, int []));
+int linux_utime __P((struct proc *, struct linux_utime_args *, int []));
+int linux_stty __P((struct proc *, struct linux_stty_args *, int []));
+int linux_gtty __P((struct proc *, struct linux_gtty_args *, int []));
+int linux_access __P((struct proc *, struct linux_access_args *, int []));
+int linux_nice __P((struct proc *, struct linux_nice_args *, int []));
+int linux_ftime __P((struct proc *, struct linux_ftime_args *, int []));
+int linux_kill __P((struct proc *, struct linux_kill_args *, int []));
+int linux_rename __P((struct proc *, struct linux_rename_args *, int []));
+int linux_mkdir __P((struct proc *, struct linux_mkdir_args *, int []));
+int linux_rmdir __P((struct proc *, struct linux_rmdir_args *, int []));
+int linux_pipe __P((struct proc *, struct linux_pipe_args *, int []));
+int linux_times __P((struct proc *, struct linux_times_args *, int []));
+int linux_prof __P((struct proc *, struct linux_prof_args *, int []));
+int linux_brk __P((struct proc *, struct linux_brk_args *, int []));
+int linux_signal __P((struct proc *, struct linux_signal_args *, int []));
+int linux_phys __P((struct proc *, struct linux_phys_args *, int []));
+int linux_lock __P((struct proc *, struct linux_lock_args *, int []));
+int linux_ioctl __P((struct proc *, struct linux_ioctl_args *, int []));
+int linux_fcntl __P((struct proc *, struct linux_fcntl_args *, int []));
+int linux_mpx __P((struct proc *, struct linux_mpx_args *, int []));
+int linux_ulimit __P((struct proc *, struct linux_ulimit_args *, int []));
+int linux_olduname __P((struct proc *, struct linux_olduname_args *, int []));
+int linux_ustat __P((struct proc *, struct linux_ustat_args *, int []));
+int linux_sigaction __P((struct proc *, struct linux_sigaction_args *, int []));
+int linux_siggetmask __P((struct proc *, struct linux_siggetmask_args *, int []));
+int linux_sigsetmask __P((struct proc *, struct linux_sigsetmask_args *, int []));
+int linux_sigsuspend __P((struct proc *, struct linux_sigsuspend_args *, int []));
+int linux_sigpending __P((struct proc *, struct linux_sigpending_args *, int []));
+int linux_select __P((struct proc *, struct linux_select_args *, int []));
+int linux_symlink __P((struct proc *, struct linux_symlink_args *, int []));
+int linux_readlink __P((struct proc *, struct linux_readlink_args *, int []));
+int linux_uselib __P((struct proc *, struct linux_uselib_args *, int []));
+int linux_readdir __P((struct proc *, struct linux_readdir_args *, int []));
+int linux_mmap __P((struct proc *, struct linux_mmap_args *, int []));
+int linux_truncate __P((struct proc *, struct linux_truncate_args *, int []));
+int linux_statfs __P((struct proc *, struct linux_statfs_args *, int []));
+int linux_fstatfs __P((struct proc *, struct linux_fstatfs_args *, int []));
+int linux_ioperm __P((struct proc *, struct linux_ioperm_args *, int []));
+int linux_socketcall __P((struct proc *, struct linux_socketcall_args *, int []));
+int linux_ksyslog __P((struct proc *, struct linux_ksyslog_args *, int []));
+int linux_setitimer __P((struct proc *, struct linux_setitimer_args *, int []));
+int linux_getitimer __P((struct proc *, struct linux_getitimer_args *, int []));
+int linux_newstat __P((struct proc *, struct linux_newstat_args *, int []));
+int linux_newlstat __P((struct proc *, struct linux_newlstat_args *, int []));
+int linux_newfstat __P((struct proc *, struct linux_newfstat_args *, int []));
+int linux_uname __P((struct proc *, struct linux_uname_args *, int []));
+int linux_iopl __P((struct proc *, struct linux_iopl_args *, int []));
+int linux_vhangup __P((struct proc *, struct linux_vhangup_args *, int []));
+int linux_idle __P((struct proc *, struct linux_idle_args *, int []));
+int linux_vm86 __P((struct proc *, struct linux_vm86_args *, int []));
+int linux_wait4 __P((struct proc *, struct linux_wait4_args *, int []));
+int linux_swapoff __P((struct proc *, struct linux_swapoff_args *, int []));
+int linux_sysinfo __P((struct proc *, struct linux_sysinfo_args *, int []));
+int linux_ipc __P((struct proc *, struct linux_ipc_args *, int []));
+int linux_sigreturn __P((struct proc *, struct linux_sigreturn_args *, int []));
+int linux_clone __P((struct proc *, struct linux_clone_args *, int []));
+int linux_newuname __P((struct proc *, struct linux_newuname_args *, int []));
+int linux_modify_ldt __P((struct proc *, struct linux_modify_ldt_args *, int []));
+int linux_adjtimex __P((struct proc *, struct linux_adjtimex_args *, int []));
+int linux_sigprocmask __P((struct proc *, struct linux_sigprocmask_args *, int []));
+int linux_create_module __P((struct proc *, struct linux_create_module_args *, int []));
+int linux_init_module __P((struct proc *, struct linux_init_module_args *, int []));
+int linux_delete_module __P((struct proc *, struct linux_delete_module_args *, int []));
+int linux_get_kernel_syms __P((struct proc *, struct linux_get_kernel_syms_args *, int []));
+int linux_quotactl __P((struct proc *, struct linux_quotactl_args *, int []));
+int linux_getpgid __P((struct proc *, struct linux_getpgid_args *, int []));
+int linux_bdflush __P((struct proc *, struct linux_bdflush_args *, int []));
+int linux_personality __P((struct proc *, struct linux_personality_args *, int []));
+int linux_llseek __P((struct proc *, struct linux_llseek_args *, int []));
+int linux_getdents __P((struct proc *, struct linux_getdents_args *, int []));
+int linux_newselect __P((struct proc *, struct linux_newselect_args *, int []));
+int linux_msync __P((struct proc *, struct linux_msync_args *, int []));
+
+#ifdef COMPAT_43
+
+
+#endif /* COMPAT_43 */
+
+#endif /* !_LINUX_SYSPROTO_H_ */
diff --git a/sys/i386/linux/linux_signal.c b/sys/i386/linux/linux_signal.c
index fc5c2cd..32648cb 100644
--- a/sys/i386/linux/linux_signal.c
+++ b/sys/i386/linux/linux_signal.c
@@ -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_signal.c,v 1.2 1995/11/22 07:43:50 bde Exp $
+ * $Id: linux_signal.c,v 1.3 1995/12/15 03:06:56 peter Exp $
*/
#include <sys/param.h>
@@ -37,69 +37,96 @@
#include <sys/signalvar.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
-
-#define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
static sigset_t
-linux_to_bsd_sigmask(linux_sigset_t mask) {
- int i;
+linux_to_bsd_sigset(linux_sigset_t mask) {
+ int b, l;
sigset_t new = 0;
- for (i = 1; i <= LINUX_NSIG; i++)
- if (mask & (1 << i-1))
- new |= (1 << (linux_to_bsd_signal[i]-1));
+ for (l = 1; l <= LINUX_NSIG; l++) {
+ if (mask & (1 << (l - 1))) {
+ if ((b = linux_to_bsd_signal[l]))
+ new |= (1 << (b - 1));
+ }
+ }
return new;
}
static linux_sigset_t
-bsd_to_linux_sigmask(sigset_t mask) {
- int i;
+bsd_to_linux_sigset(sigset_t mask) {
+ int b, l;
sigset_t new = 0;
- for (i = 1; i <= NSIG; i++)
- if (mask & (1 << i-1))
- new |= (1 << (bsd_to_linux_signal[i]-1));
+ for (b = 1; b <= NSIG; b++) {
+ if (mask & (1 << (b - 1))) {
+ if ((l = bsd_to_linux_signal[b]))
+ new |= (1 << (l - 1));
+ }
+ }
return new;
}
-struct linux_sigaction_args {
- int sig;
- linux_sigaction_t *nsa;
- linux_sigaction_t *osa;
-};
+void
+linux_to_bsd_sigaction(linux_sigaction_t *lsa, struct sigaction *bsa)
+{
+ bsa->sa_mask = linux_to_bsd_sigset(lsa->sa_mask);
+ bsa->sa_handler = lsa->sa_handler;
+ bsa->sa_flags = 0;
+ if (lsa->sa_flags & LINUX_SA_NOCLDSTOP)
+ bsa->sa_flags |= SA_NOCLDSTOP;
+ if (lsa->sa_flags & LINUX_SA_ONSTACK)
+ bsa->sa_flags |= SA_ONSTACK;
+ if (lsa->sa_flags & LINUX_SA_RESTART)
+ bsa->sa_flags |= SA_RESTART;
+ if (lsa->sa_flags & LINUX_SA_ONESHOT)
+ bsa->sa_flags |= SA_RESETHAND;
+ if (lsa->sa_flags & LINUX_SA_NOMASK)
+ bsa->sa_flags |= SA_NODEFER;
+}
+
+void
+bsd_to_linux_sigaction(struct sigaction *bsa, linux_sigaction_t *lsa)
+{
+ lsa->sa_handler = bsa->sa_handler;
+ lsa->sa_restorer = NULL; /* unsupported */
+ lsa->sa_mask = bsd_to_linux_sigset(bsa->sa_mask);
+ lsa->sa_flags = 0;
+ if (bsa->sa_flags & SA_NOCLDSTOP)
+ lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
+ if (bsa->sa_flags & SA_ONSTACK)
+ lsa->sa_flags |= LINUX_SA_ONSTACK;
+ if (bsa->sa_flags & SA_RESTART)
+ lsa->sa_flags |= LINUX_SA_RESTART;
+ if (bsa->sa_flags & SA_RESETHAND)
+ lsa->sa_flags |= LINUX_SA_ONESHOT;
+ if (bsa->sa_flags & SA_NODEFER)
+ lsa->sa_flags |= LINUX_SA_NOMASK;
+}
int
linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
{
linux_sigaction_t linux_sa;
struct sigaction *nsa = NULL, *osa = NULL, bsd_sa;
- struct sigaction_args /* {
- int signum;
- struct sigaction *nsa;
- struct sigaction *osa;
- } */ sa;
+ struct sigaction_args sa;
int error;
+ caddr_t sg = stackgap_init();
#ifdef DEBUG
- printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig);
+ printf("Linux-emul(%d): sigaction(%d, %08x, %08x)\n", p->p_pid, args->sig,
+ args->nsa, args->osa);
#endif
+
if (args->osa)
- osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction));
+ osa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction));
if (args->nsa) {
- nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction));
+ nsa = (struct sigaction *)stackgap_alloc(&sg, sizeof(struct sigaction));
if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t)))
return error;
- bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask);
- bsd_sa.sa_handler = linux_sa.sa_handler;
- bsd_sa.sa_flags = 0;
- if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP)
- bsd_sa.sa_flags |= SA_NOCLDSTOP;
- if (linux_sa.sa_flags & LINUX_SA_ONSTACK)
- bsd_sa.sa_flags |= SA_ONSTACK;
- if (linux_sa.sa_flags & LINUX_SA_RESTART)
- bsd_sa.sa_flags |= SA_RESTART;
+ linux_to_bsd_sigaction(&linux_sa, &bsd_sa);
if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction)))
return error;
}
@@ -112,27 +139,49 @@ linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval)
if (args->osa) {
if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction)))
return error;
- linux_sa.sa_handler = bsd_sa.sa_handler;
- linux_sa.sa_restorer = NULL;
- linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask);
- linux_sa.sa_flags = 0;
- if (bsd_sa.sa_flags & SA_NOCLDSTOP)
- linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP;
- if (bsd_sa.sa_flags & SA_ONSTACK)
- linux_sa.sa_flags |= LINUX_SA_ONSTACK;
- if (bsd_sa.sa_flags & SA_RESTART)
- linux_sa.sa_flags |= LINUX_SA_RESTART;
+ bsd_to_linux_sigaction(&bsd_sa, &linux_sa);
if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t)))
return error;
}
return 0;
}
-struct linux_sigprocmask_args {
- int how;
- linux_sigset_t *mask;
- linux_sigset_t *omask;
-};
+int
+linux_signal(struct proc *p, struct linux_signal_args *args, int *retval)
+{
+ caddr_t sg;
+ struct sigaction_args sa_args;
+ struct sigaction *osa, *nsa, tmpsa;
+ int error;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): signal(%d, %08x)\n", p->p_pid,
+ args->sig, args->handler);
+#endif
+ sg = stackgap_init();
+ nsa = stackgap_alloc(&sg, sizeof *nsa);
+ osa = stackgap_alloc(&sg, sizeof *osa);
+
+ tmpsa.sa_handler = args->handler;
+ tmpsa.sa_mask = (sigset_t) 0;
+ tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
+ if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
+ return error;
+
+ sa_args.signum = linux_to_bsd_signal[args->sig];
+ sa_args.osa = osa;
+ sa_args.nsa = nsa;
+ if ((error = sigaction(p, &sa_args, retval)))
+ return error;
+
+ if ((error = copyin(osa, &tmpsa, sizeof *osa)))
+ return error;
+
+ *retval = (int)tmpsa.sa_handler;
+
+ return 0;
+}
+
int
linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
@@ -145,8 +194,11 @@ linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
#ifdef DEBUG
printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how);
#endif
+
+ *retval = 0;
+
if (args->omask != NULL) {
- omask = bsd_to_linux_sigmask(p->p_sigmask);
+ omask = bsd_to_linux_sigset(p->p_sigmask);
if (error = copyout(&omask, args->omask, sizeof(sigset_t)))
return error;
}
@@ -155,17 +207,17 @@ linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t)))
return error;
- mask = linux_to_bsd_sigmask(mask);
+ mask = linux_to_bsd_sigset(mask);
s = splhigh();
switch (args->how) {
case LINUX_SIG_BLOCK:
- p->p_sigmask |= (mask & ~DONTMASK);
+ p->p_sigmask |= (mask & ~sigcantmask);
break;
case LINUX_SIG_UNBLOCK:
p->p_sigmask &= ~mask;
break;
case LINUX_SIG_SETMASK:
- p->p_sigmask = (mask & ~DONTMASK);
+ p->p_sigmask = (mask & ~sigcantmask);
break;
default:
error = EINVAL;
@@ -176,38 +228,33 @@ linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args,
}
int
-linux_siggetmask(struct proc *p, void *args, int *retval)
+linux_siggetmask(struct proc *p, struct linux_siggetmask_args *args, int *retval)
{
#ifdef DEBUG
printf("Linux-emul(%d): siggetmask()\n", p->p_pid);
#endif
- *retval = bsd_to_linux_sigmask(p->p_sigmask);
+ *retval = bsd_to_linux_sigset(p->p_sigmask);
return 0;
}
-struct linux_sigsetmask_args {
- linux_sigset_t mask;
-};
-
int
linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval)
{
int s;
+ sigset_t mask;
#ifdef DEBUG
printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask);
#endif
+ *retval = bsd_to_linux_sigset(p->p_sigmask);
+
+ mask = linux_to_bsd_sigset(args->mask);
s = splhigh();
- p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK);
+ p->p_sigmask = mask & ~sigcantmask;
splx(s);
- *retval = bsd_to_linux_sigmask(p->p_sigmask);
return 0;
}
-struct linux_sigpending_args {
- linux_sigset_t *mask;
-};
-
int
linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
{
@@ -216,32 +263,35 @@ linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval)
#ifdef DEBUG
printf("Linux-emul(%d): sigpending(*)\n", p->p_pid);
#endif
- linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask);
+ linux_sig = bsd_to_linux_sigset(p->p_siglist & p->p_sigmask);
return copyout(&linux_sig, args->mask, sizeof(linux_sig));
}
-struct linux_sigsuspend_args {
- linux_sigset_t mask;
-};
-
int
linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval)
{
- struct sigsuspend_args /* {
- int mask;
- } */ tmp;
+ struct sigsuspend_args tmp;
+ int error;
#ifdef DEBUG
printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask);
#endif
- tmp.mask = linux_to_bsd_sigmask(args->mask);
+ tmp.mask = linux_to_bsd_sigset(args->mask);
return sigsuspend(p, &tmp , retval);
}
-struct linux_kill_args {
- int pid;
- int signum;
-};
+int
+linux_pause(struct proc *p, struct linux_pause_args *args,int *retval)
+{
+ struct sigsuspend_args tmp;
+ int error;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): pause()\n", p->p_pid);
+#endif
+ tmp.mask = p->p_sigmask;
+ return sigsuspend(p, &tmp , retval);
+}
int
linux_kill(struct proc *p, struct linux_kill_args *args, int *retval)
diff --git a/sys/i386/linux/linux_socket.c b/sys/i386/linux/linux_socket.c
index da4668c..63b33d5 100644
--- a/sys/i386/linux/linux_socket.c
+++ b/sys/i386/linux/linux_socket.c
@@ -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_socket.c,v 1.2 1995/11/22 07:43:50 bde Exp $
+ * $Id: linux_socket.c,v 1.3 1995/12/15 03:06:57 peter Exp $
*/
/* XXX we use functions that might not exist. */
@@ -41,7 +41,7 @@
#include <netinet/in.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux_proto.h>
static int
linux_to_bsd_domain(int domain)
@@ -555,11 +555,6 @@ linux_getsockopt(struct proc *p, struct linux_getsockopt_args *args, int *retval
return getsockopt(p, &bsd_args, retval);
}
-struct linux_socketcall_args {
- int what;
- void *args;
-};
-
int
linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval)
{
diff --git a/sys/i386/linux/linux_stats.c b/sys/i386/linux/linux_stats.c
index 327343b..8d562e0 100644
--- a/sys/i386/linux/linux_stats.c
+++ b/sys/i386/linux/linux_stats.c
@@ -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_stats.c,v 1.3 1995/11/22 07:43:51 bde Exp $
+ * $Id: linux_stats.c,v 1.4 1996/01/30 12:23:17 peter Exp $
*/
#include <sys/param.h>
@@ -42,7 +42,8 @@
#include <sys/pipe.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_util.h>
struct linux_newstat {
unsigned short stat_dev;
@@ -67,10 +68,6 @@ struct linux_newstat {
unsigned long __unused5;
};
-struct linux_newstat_args {
- char *path;
- struct linux_newstat *buf;
-};
static int
newstat_copyout(struct stat *buf, void *ubuf)
@@ -97,9 +94,12 @@ int
linux_newstat(struct proc *p, struct linux_newstat_args *args, int *retval)
{
struct stat buf;
- struct linux_newstat tbuf;
struct nameidata nd;
int error;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
#ifdef DEBUG
printf("Linux-emul(%d): newstat(%s, *)\n", p->p_pid, args->path);
@@ -115,44 +115,78 @@ linux_newstat(struct proc *p, struct linux_newstat_args *args, int *retval)
return error;
}
+/*
+ * Get file status; this version does not follow links.
+ */
int
-linux_newlstat(struct proc *p, struct linux_newstat_args *args, int *retval)
+linux_newlstat(p, uap, retval)
+ struct proc *p;
+ struct linux_newlstat_args *uap;
+ int *retval;
{
- struct stat buf;
- struct linux_newstat tbuf;
- struct nameidata nd;
- int error;
+ int error;
+ struct vnode *vp, *dvp;
+ struct stat sb, sb1;
+ struct nameidata nd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
#ifdef DEBUG
- printf("Linux-emul(%d): newlstat(%s, *)\n", p->p_pid, args->path);
+ printf("Linux-emul(%d): newlstat(%s, *)\n", p->p_pid, uap->path);
#endif
- NDINIT(&nd, LOOKUP, LOCKLEAF|FOLLOW, UIO_USERSPACE, args->path, p);
- error = namei(&nd);
- if (!error) {
- error = vn_stat(nd.ni_vp, &buf, p);
- vput(nd.ni_vp);
- }
- if (!error)
- error = newstat_copyout(&buf, args->buf);
- return error;
+ NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
+ uap->path, p);
+ error = namei(&nd);
+ if (error)
+ return (error);
+ /*
+ * For symbolic links, always return the attributes of its
+ * containing directory, except for mode, size, and links.
+ */
+ vp = nd.ni_vp;
+ dvp = nd.ni_dvp;
+ if (vp->v_type != VLNK) {
+ if (dvp == vp)
+ vrele(dvp);
+ else
+ vput(dvp);
+ error = vn_stat(vp, &sb, p);
+ vput(vp);
+ if (error)
+ return (error);
+ } else {
+ error = vn_stat(dvp, &sb, p);
+ vput(dvp);
+ if (error) {
+ vput(vp);
+ return (error);
+ }
+ error = vn_stat(vp, &sb1, p);
+ vput(vp);
+ if (error)
+ return (error);
+ sb.st_mode &= ~S_IFDIR;
+ sb.st_mode |= S_IFLNK;
+ sb.st_nlink = sb1.st_nlink;
+ sb.st_size = sb1.st_size;
+ sb.st_blocks = sb1.st_blocks;
+ }
+ error = newstat_copyout(&sb, uap->buf);
+ return (error);
}
-struct linux_newfstat_args {
- int fd;
- struct linux_newstat *buf;
-};
-
int
linux_newfstat(struct proc *p, struct linux_newfstat_args *args, int *retval)
{
- struct linux_newstat tbuf;
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct stat buf;
int error;
#ifdef DEBUG
- printf("Linux-emul(%d): newlstat(%d, *)\n", p->p_pid, args->fd);
+ printf("Linux-emul(%d): newfstat(%d, *)\n", p->p_pid, args->fd);
#endif
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == NULL)
@@ -175,7 +209,7 @@ linux_newfstat(struct proc *p, struct linux_newfstat_args *args, int *retval)
return error;
}
-struct linux_statfs {
+struct linux_statfs_buf {
long ftype;
long fbsize;
long fblocks;
@@ -188,12 +222,6 @@ struct linux_statfs {
long fspare[6];
};
-
-struct linux_statfs_args {
- char *path;
- struct statfs *buf;
-};
-
int
linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
{
@@ -201,8 +229,12 @@ linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
struct nameidata *ndp;
struct statfs *bsd_statfs;
struct nameidata nd;
- struct linux_statfs linux_statfs;
+ struct linux_statfs_buf linux_statfs_buf;
int error;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, args->path);
#ifdef DEBUG
printf("Linux-emul(%d): statfs(%s, *)\n", p->p_pid, args->path);
@@ -217,32 +249,27 @@ linux_statfs(struct proc *p, struct linux_statfs_args *args, int *retval)
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- linux_statfs.ftype = bsd_statfs->f_type;
- linux_statfs.fbsize = bsd_statfs->f_bsize;
- linux_statfs.fblocks = bsd_statfs->f_blocks;
- linux_statfs.fbfree = bsd_statfs->f_bfree;
- linux_statfs.fbavail = bsd_statfs->f_bavail;
- linux_statfs.fffree = bsd_statfs->f_ffree;
- linux_statfs.ffiles = bsd_statfs->f_files;
- linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
- linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
- linux_statfs.fnamelen = MAXNAMLEN;
- return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
- sizeof(struct linux_statfs));
+ linux_statfs_buf.ftype = bsd_statfs->f_type;
+ linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
+ linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
+ linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
+ linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
+ linux_statfs_buf.fffree = bsd_statfs->f_ffree;
+ linux_statfs_buf.ffiles = bsd_statfs->f_files;
+ linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
+ linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
+ linux_statfs_buf.fnamelen = MAXNAMLEN;
+ return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
+ sizeof(struct linux_statfs_buf));
}
-struct linux_fstatfs_args {
- int fd;
- struct statfs *buf;
-};
-
int
linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args, int *retval)
{
struct file *fp;
struct mount *mp;
struct statfs *bsd_statfs;
- struct linux_statfs linux_statfs;
+ struct linux_statfs_buf linux_statfs_buf;
int error;
#ifdef DEBUG
@@ -255,16 +282,16 @@ linux_fstatfs(struct proc *p, struct linux_fstatfs_args *args, int *retval)
if (error = VFS_STATFS(mp, bsd_statfs, p))
return error;
bsd_statfs->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
- linux_statfs.ftype = bsd_statfs->f_type;
- linux_statfs.fbsize = bsd_statfs->f_bsize;
- linux_statfs.fblocks = bsd_statfs->f_blocks;
- linux_statfs.fbfree = bsd_statfs->f_bfree;
- linux_statfs.fbavail = bsd_statfs->f_bavail;
- linux_statfs.fffree = bsd_statfs->f_ffree;
- linux_statfs.ffiles = bsd_statfs->f_files;
- linux_statfs.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
- linux_statfs.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
- linux_statfs.fnamelen = MAXNAMLEN;
- return copyout((caddr_t)&linux_statfs, (caddr_t)args->buf,
- sizeof(struct linux_statfs));
+ linux_statfs_buf.ftype = bsd_statfs->f_type;
+ linux_statfs_buf.fbsize = bsd_statfs->f_bsize;
+ linux_statfs_buf.fblocks = bsd_statfs->f_blocks;
+ linux_statfs_buf.fbfree = bsd_statfs->f_bfree;
+ linux_statfs_buf.fbavail = bsd_statfs->f_bavail;
+ linux_statfs_buf.fffree = bsd_statfs->f_ffree;
+ linux_statfs_buf.ffiles = bsd_statfs->f_files;
+ linux_statfs_buf.ffsid.val[0] = bsd_statfs->f_fsid.val[0];
+ linux_statfs_buf.ffsid.val[1] = bsd_statfs->f_fsid.val[1];
+ linux_statfs_buf.fnamelen = MAXNAMLEN;
+ return copyout((caddr_t)&linux_statfs_buf, (caddr_t)args->buf,
+ sizeof(struct linux_statfs_buf));
}
diff --git a/sys/i386/linux/linux_syscall.h b/sys/i386/linux/linux_syscall.h
new file mode 100644
index 0000000..6e0c5fd
--- /dev/null
+++ b/sys/i386/linux/linux_syscall.h
@@ -0,0 +1,151 @@
+/*
+ * System call numbers.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * created from Id: syscalls.master,v 1.1 1996/03/02 19:04:15 peter Exp
+ */
+
+#define LINUX_SYS_linux_setup 0
+#define LINUX_SYS_exit 1
+#define LINUX_SYS_linux_fork 2
+#define LINUX_SYS_read 3
+#define LINUX_SYS_write 4
+#define LINUX_SYS_linux_open 5
+#define LINUX_SYS_close 6
+#define LINUX_SYS_linux_waitpid 7
+#define LINUX_SYS_linux_creat 8
+#define LINUX_SYS_link 9
+#define LINUX_SYS_linux_unlink 10
+#define LINUX_SYS_linux_execve 11
+#define LINUX_SYS_linux_chdir 12
+#define LINUX_SYS_linux_time 13
+#define LINUX_SYS_linux_mknod 14
+#define LINUX_SYS_linux_chmod 15
+#define LINUX_SYS_linux_chown 16
+#define LINUX_SYS_linux_break 17
+#define LINUX_SYS_linux_stat 18
+#define LINUX_SYS_linux_lseek 19
+#define LINUX_SYS_getpid 20
+#define LINUX_SYS_linux_mount 21
+#define LINUX_SYS_linux_umount 22
+#define LINUX_SYS_setuid 23
+#define LINUX_SYS_getuid 24
+#define LINUX_SYS_linux_stime 25
+#define LINUX_SYS_linux_ptrace 26
+#define LINUX_SYS_linux_alarm 27
+#define LINUX_SYS_linux_fstat 28
+#define LINUX_SYS_linux_pause 29
+#define LINUX_SYS_linux_utime 30
+#define LINUX_SYS_linux_stty 31
+#define LINUX_SYS_linux_gtty 32
+#define LINUX_SYS_linux_access 33
+#define LINUX_SYS_linux_nice 34
+#define LINUX_SYS_linux_ftime 35
+#define LINUX_SYS_sync 36
+#define LINUX_SYS_linux_kill 37
+#define LINUX_SYS_linux_rename 38
+#define LINUX_SYS_linux_mkdir 39
+#define LINUX_SYS_linux_rmdir 40
+#define LINUX_SYS_dup 41
+#define LINUX_SYS_linux_pipe 42
+#define LINUX_SYS_linux_times 43
+#define LINUX_SYS_linux_prof 44
+#define LINUX_SYS_linux_brk 45
+#define LINUX_SYS_setgid 46
+#define LINUX_SYS_getgid 47
+#define LINUX_SYS_linux_signal 48
+#define LINUX_SYS_geteuid 49
+#define LINUX_SYS_getegid 50
+#define LINUX_SYS_acct 51
+#define LINUX_SYS_linux_phys 52
+#define LINUX_SYS_linux_lock 53
+#define LINUX_SYS_linux_ioctl 54
+#define LINUX_SYS_linux_fcntl 55
+#define LINUX_SYS_linux_mpx 56
+#define LINUX_SYS_setpgid 57
+#define LINUX_SYS_linux_ulimit 58
+#define LINUX_SYS_linux_olduname 59
+#define LINUX_SYS_umask 60
+#define LINUX_SYS_chroot 61
+#define LINUX_SYS_linux_ustat 62
+#define LINUX_SYS_dup2 63
+#define LINUX_SYS_getppid 64
+#define LINUX_SYS_getpgrp 65
+#define LINUX_SYS_setsid 66
+#define LINUX_SYS_linux_sigaction 67
+#define LINUX_SYS_linux_siggetmask 68
+#define LINUX_SYS_linux_sigsetmask 69
+#define LINUX_SYS_setreuid 70
+#define LINUX_SYS_setregid 71
+#define LINUX_SYS_linux_sigsuspend 72
+#define LINUX_SYS_linux_sigpending 73
+#define LINUX_SYS_osethostname 74
+#define LINUX_SYS_osetrlimit 75
+#define LINUX_SYS_ogetrlimit 76
+#define LINUX_SYS_getrusage 77
+#define LINUX_SYS_gettimeofday 78
+#define LINUX_SYS_settimeofday 79
+#define LINUX_SYS_getgroups 80
+#define LINUX_SYS_setgroups 81
+#define LINUX_SYS_linux_select 82
+#define LINUX_SYS_linux_symlink 83
+#define LINUX_SYS_ostat 84
+#define LINUX_SYS_linux_readlink 85
+#define LINUX_SYS_linux_uselib 86
+#define LINUX_SYS_swapon 87
+#define LINUX_SYS_reboot 88
+#define LINUX_SYS_linux_readdir 89
+#define LINUX_SYS_linux_mmap 90
+#define LINUX_SYS_munmap 91
+#define LINUX_SYS_linux_truncate 92
+#define LINUX_SYS_oftruncate 93
+#define LINUX_SYS_fchmod 94
+#define LINUX_SYS_fchown 95
+#define LINUX_SYS_getpriority 96
+#define LINUX_SYS_setpriority 97
+#define LINUX_SYS_profil 98
+#define LINUX_SYS_linux_statfs 99
+#define LINUX_SYS_linux_fstatfs 100
+#define LINUX_SYS_linux_ioperm 101
+#define LINUX_SYS_linux_socketcall 102
+#define LINUX_SYS_linux_ksyslog 103
+#define LINUX_SYS_linux_setitimer 104
+#define LINUX_SYS_linux_getitimer 105
+#define LINUX_SYS_linux_newstat 106
+#define LINUX_SYS_linux_newlstat 107
+#define LINUX_SYS_linux_newfstat 108
+#define LINUX_SYS_linux_uname 109
+#define LINUX_SYS_linux_iopl 110
+#define LINUX_SYS_linux_vhangup 111
+#define LINUX_SYS_linux_idle 112
+#define LINUX_SYS_linux_vm86 113
+#define LINUX_SYS_linux_wait4 114
+#define LINUX_SYS_linux_swapoff 115
+#define LINUX_SYS_linux_sysinfo 116
+#define LINUX_SYS_linux_ipc 117
+#define LINUX_SYS_fsync 118
+#define LINUX_SYS_linux_sigreturn 119
+#define LINUX_SYS_linux_clone 120
+#define LINUX_SYS_setdomainname 121
+#define LINUX_SYS_linux_newuname 122
+#define LINUX_SYS_linux_modify_ldt 123
+#define LINUX_SYS_linux_adjtimex 124
+#define LINUX_SYS_mprotect 125
+#define LINUX_SYS_linux_sigprocmask 126
+#define LINUX_SYS_linux_create_module 127
+#define LINUX_SYS_linux_init_module 128
+#define LINUX_SYS_linux_delete_module 129
+#define LINUX_SYS_linux_get_kernel_syms 130
+#define LINUX_SYS_linux_quotactl 131
+#define LINUX_SYS_linux_getpgid 132
+#define LINUX_SYS_fchdir 133
+#define LINUX_SYS_linux_bdflush 134
+#define LINUX_SYS_linux_personality 136
+#define LINUX_SYS_linux_llseek 140
+#define LINUX_SYS_linux_getdents 141
+#define LINUX_SYS_linux_newselect 142
+#define LINUX_SYS_flock 143
+#define LINUX_SYS_linux_msync 144
+#define LINUX_SYS_readv 145
+#define LINUX_SYS_writev 146
+#define LINUX_SYS_MAXSYSCALL 147
diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c
index 0813e9b..4e32271 100644
--- a/sys/i386/linux/linux_sysent.c
+++ b/sys/i386/linux/linux_sysent.c
@@ -1,235 +1,171 @@
-/*-
- * Copyright (c) 1994-1995 Søren Schmidt
- * All rights reserved.
+/*
+ * System call switch table.
*
- * 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
- * in this position and unchanged.
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
- * $Id: linux_sysent.c,v 1.3 1995/11/22 07:43:52 bde Exp $
+ * DO NOT EDIT-- this file is automatically generated.
+ * created from Id: syscalls.master,v 1.1 1996/03/02 19:04:15 peter Exp
*/
-/* XXX we use functions that might not exist. */
-#define COMPAT_43 1
-
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/sysproto.h>
#include <sys/sysent.h>
-#include <sys/imgact.h>
-
+#include <sys/sysproto.h>
#include <i386/linux/linux.h>
-#include <i386/linux/sysproto.h>
-
-static struct sysent linux_sysent[] = {
- 0, (sy_call_t *)linux_setup, /* 0 */
- 1, (sy_call_t *)exit, /* 1 */
- 0, (sy_call_t *)linux_fork, /* 2 */
- 3, (sy_call_t *)read, /* 3 */
- 3, (sy_call_t *)write, /* 4 */
- 3, (sy_call_t *)linux_open, /* 5 */
- 1, (sy_call_t *)close, /* 6 */
- 3, (sy_call_t *)linux_waitpid, /* 7 */
- 2, (sy_call_t *)linux_creat, /* 8 */
- 2, (sy_call_t *)link, /* 9 */
- 1, (sy_call_t *)unlink, /* 10 */
- 3, (sy_call_t *)execve, /* 11 */
- 1, (sy_call_t *)chdir, /* 12 */
- 1, (sy_call_t *)linux_time, /* 13 */
- 3, (sy_call_t *)linux_mknod, /* 14 */
- 2, (sy_call_t *)chmod, /* 15 */
- 3, (sy_call_t *)chown, /* 16 */
- 1, (sy_call_t *)linux_break, /* 17 */
- 2, (sy_call_t *)linux_stat, /* 18 */
- 3, (sy_call_t *)linux_lseek, /* 19 */
- 0, (sy_call_t *)getpid, /* 20 */
- 5, (sy_call_t *)linux_mount, /* 21 */
- 1, (sy_call_t *)linux_umount, /* 22 */
- 1, (sy_call_t *)setuid, /* 23 */
- 0, (sy_call_t *)getuid, /* 24 */
- 1, (sy_call_t *)linux_stime, /* 25 */
- 4, (sy_call_t *)linux_ptrace, /* 26 */
- 1, (sy_call_t *)linux_alarm, /* 27 */
- 2, (sy_call_t *)linux_fstat, /* 28 */
- 0, (sy_call_t *)linux_pause, /* 29 */
- 2, (sy_call_t *)linux_utime, /* 30 */
- 0, (sy_call_t *)linux_stty, /* 31 */
- 0, (sy_call_t *)linux_gtty, /* 32 */
- 2, (sy_call_t *)access, /* 33 */
- 1, (sy_call_t *)linux_nice, /* 34 */
- 0, (sy_call_t *)linux_ftime, /* 35 */
- 0, (sy_call_t *)sync, /* 36 */
- 2, (sy_call_t *)linux_kill, /* 37 */
- 2, (sy_call_t *)rename, /* 38 */
- 2, (sy_call_t *)mkdir, /* 39 */
- 1, (sy_call_t *)rmdir, /* 40 */
- 1, (sy_call_t *)dup, /* 41 */
- 1, (sy_call_t *)linux_pipe, /* 42 */
- 1, (sy_call_t *)linux_times, /* 43 */
- 0, (sy_call_t *)linux_prof, /* 44 */
- 1, (sy_call_t *)linux_brk, /* 45 */
- 1, (sy_call_t *)setgid, /* 46 */
- 0, (sy_call_t *)getgid, /* 47 */
- 2, (sy_call_t *)linux_signal, /* 48 */
- 0, (sy_call_t *)geteuid, /* 49 */
- 0, (sy_call_t *)getegid, /* 50 */
- 0, (sy_call_t *)acct, /* 51 */
- 0, (sy_call_t *)linux_phys, /* 52 */
- 0, (sy_call_t *)linux_lock, /* 53 */
- 3, (sy_call_t *)linux_ioctl, /* 54 */
- 3, (sy_call_t *)linux_fcntl, /* 55 */
- 0, (sy_call_t *)linux_mpx, /* 56 */
- 2, (sy_call_t *)setpgid, /* 57 */
- 0, (sy_call_t *)linux_ulimit, /* 58 */
- 1, (sy_call_t *)linux_olduname, /* 59 */
- 1, (sy_call_t *)umask, /* 60 */
- 1, (sy_call_t *)chroot, /* 61 */
- 2, (sy_call_t *)linux_ustat, /* 62 */
- 2, (sy_call_t *)dup2, /* 63 */
- 0, (sy_call_t *)getppid, /* 64 */
- 0, (sy_call_t *)getpgrp, /* 65 */
- 0, (sy_call_t *)setsid, /* 66 */
- 3, (sy_call_t *)linux_sigaction, /* 67 */
- 0, (sy_call_t *)linux_siggetmask, /* 68 */
- 1, (sy_call_t *)linux_sigsetmask, /* 69 */
- 2, (sy_call_t *)setreuid, /* 70 */
- 2, (sy_call_t *)setregid, /* 71 */
- 1, (sy_call_t *)linux_sigsuspend, /* 72 */
- 1, (sy_call_t *)linux_sigpending, /* 73 */
- 2, (sy_call_t *)osethostname, /* 74 */
- 2, (sy_call_t *)osetrlimit, /* 75 */
- 2, (sy_call_t *)ogetrlimit, /* 76 */
- 2, (sy_call_t *)getrusage, /* 77 */
- 2, (sy_call_t *)gettimeofday, /* 78 */
- 2, (sy_call_t *)settimeofday, /* 79 */
- 2, (sy_call_t *)getgroups, /* 80 */
- 2, (sy_call_t *)setgroups, /* 81 */
- 1, (sy_call_t *)linux_select, /* 82 */
- 2, (sy_call_t *)symlink, /* 83 */
- 2, (sy_call_t *)ostat, /* 84 */
- 3, (sy_call_t *)readlink, /* 85 */
- 1, (sy_call_t *)linux_uselib, /* 86 */
- 1, (sy_call_t *)swapon, /* 87 */
- 3, (sy_call_t *)reboot, /* 88 */
- 3, (sy_call_t *)linux_readdir, /* 89 */
- 1, (sy_call_t *)linux_mmap, /* 90 */
- 2, (sy_call_t *)munmap, /* 91 */
- 2, (sy_call_t *)otruncate, /* 92 */
- 2, (sy_call_t *)oftruncate, /* 93 */
- 2, (sy_call_t *)fchmod, /* 94 */
- 3, (sy_call_t *)fchown, /* 95 */
- 2, (sy_call_t *)getpriority, /* 96 */
- 3, (sy_call_t *)setpriority, /* 97 */
- 0, (sy_call_t *)profil, /* 98 */
- 2, (sy_call_t *)linux_statfs, /* 99 */
- 2, (sy_call_t *)linux_fstatfs, /* 100 */
- 3, (sy_call_t *)linux_ioperm, /* 101 */
- 2, (sy_call_t *)linux_socketcall, /* 102 */
- 3, (sy_call_t *)linux_syslog, /* 103 */
- 3, (sy_call_t *)setitimer, /* 104 */
- 2, (sy_call_t *)getitimer, /* 105 */
- 2, (sy_call_t *)linux_newstat, /* 106 */
- 2, (sy_call_t *)linux_newlstat, /* 107 */
- 2, (sy_call_t *)linux_newfstat, /* 108 */
- 2, (sy_call_t *)linux_uname, /* 109 */
- 1, (sy_call_t *)linux_iopl, /* 110 */
- 0, (sy_call_t *)linux_vhangup, /* 111 */
- 0, (sy_call_t *)linux_idle, /* 112 */
- 1, (sy_call_t *)linux_vm86, /* 113 */
- 4, (sy_call_t *)linux_wait4, /* 114 */
- 1, (sy_call_t *)linux_swapoff, /* 115 */
- 1, (sy_call_t *)linux_sysinfo, /* 116 */
- 4, (sy_call_t *)linux_ipc, /* 117 */
- 1, (sy_call_t *)fsync, /* 118 */
- 1, (sy_call_t *)linux_sigreturn, /* 119 */
- 0, (sy_call_t *)linux_clone, /* 120 */
- 2, (sy_call_t *)setdomainname, /* 121 */
- 1, (sy_call_t *)linux_newuname, /* 122 */
- 3, (sy_call_t *)linux_modify_ldt, /* 123 */
- 1, (sy_call_t *)linux_adjtimex, /* 124 */
- 3, (sy_call_t *)mprotect, /* 125 */
- 3, (sy_call_t *)linux_sigprocmask, /* 126 */
- 2, (sy_call_t *)linux_create_module, /* 127 */
- 4, (sy_call_t *)linux_init_module, /* 128 */
- 1, (sy_call_t *)linux_delete_module, /* 129 */
- 1, (sy_call_t *)linux_get_kernel_syms, /* 130 */
- 0, (sy_call_t *)linux_quotactl, /* 131 */
- 1, (sy_call_t *)linux_getpgid, /* 132 */
- 1, (sy_call_t *)fchdir, /* 133 */
- 0, (sy_call_t *)linux_bdflush, /* 134 */
-};
-
-int bsd_to_linux_errno[ELAST] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 35, 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 11,115,114, 88, 89,
- 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
- 100,101,102,103,104,105,106,107,108,109,
- 110,111, 40, 36,112,113, 39, 11, 87,122,
- 116, 66, 6, 6, 6, 6, 6, 37, 38, 9,
- 6,
-};
-
-int bsd_to_linux_signal[NSIG] = {
- 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT,
- LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0,
- LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV,
- 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM,
- LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT,
- LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO,
- LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF,
- LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2
-};
-
-int linux_to_bsd_signal[LINUX_NSIG] = {
- 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT,
- SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM,
- SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGIO,
- SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGURG, SIGURG, 0
-};
-
-int linux_fixup(int **stack_base, struct image_params *imgp)
-{
- int *argv, *envp;
+#include <i386/linux/linux_proto.h>
- argv = *stack_base;
- envp = *stack_base + (imgp->argc + 1);
- (*stack_base)--;
- **stack_base = (int)envp;
- (*stack_base)--;
- **stack_base = (int)argv;
- (*stack_base)--;
- **stack_base = (int)imgp->argc;
- return 0; /* XXX */
-}
+#ifdef COMPAT_43
+#define compat(n, name) n, (sy_call_t *)__CONCAT(o,name)
+#else
+#define compat(n, name) 0, (sy_call_t *)nosys
+#endif
-struct sysentvec linux_sysvec = {
- sizeof (linux_sysent) / sizeof(linux_sysent[0]),
- linux_sysent,
- 0xff,
- NSIG,
- bsd_to_linux_signal,
- ELAST,
- bsd_to_linux_errno,
- linux_fixup
+/* The casts are bogus but will do for now. */
+struct sysent linux_sysent[] = {
+ { 0, (sy_call_t *)linux_setup }, /* 0 = linux_setup */
+ { 1, (sy_call_t *)exit }, /* 1 = exit */
+ { 0, (sy_call_t *)linux_fork }, /* 2 = linux_fork */
+ { 3, (sy_call_t *)read }, /* 3 = read */
+ { 3, (sy_call_t *)write }, /* 4 = write */
+ { 3, (sy_call_t *)linux_open }, /* 5 = linux_open */
+ { 1, (sy_call_t *)close }, /* 6 = close */
+ { 3, (sy_call_t *)linux_waitpid }, /* 7 = linux_waitpid */
+ { 2, (sy_call_t *)linux_creat }, /* 8 = linux_creat */
+ { 2, (sy_call_t *)link }, /* 9 = link */
+ { 1, (sy_call_t *)linux_unlink }, /* 10 = linux_unlink */
+ { 3, (sy_call_t *)linux_execve }, /* 11 = linux_execve */
+ { 1, (sy_call_t *)linux_chdir }, /* 12 = linux_chdir */
+ { 1, (sy_call_t *)linux_time }, /* 13 = linux_time */
+ { 3, (sy_call_t *)linux_mknod }, /* 14 = linux_mknod */
+ { 2, (sy_call_t *)linux_chmod }, /* 15 = linux_chmod */
+ { 3, (sy_call_t *)linux_chown }, /* 16 = linux_chown */
+ { 1, (sy_call_t *)linux_break }, /* 17 = linux_break */
+ { 2, (sy_call_t *)linux_stat }, /* 18 = linux_stat */
+ { 3, (sy_call_t *)linux_lseek }, /* 19 = linux_lseek */
+ { 0, (sy_call_t *)getpid }, /* 20 = getpid */
+ { 0, (sy_call_t *)linux_mount }, /* 21 = linux_mount */
+ { 0, (sy_call_t *)linux_umount }, /* 22 = linux_umount */
+ { 1, (sy_call_t *)setuid }, /* 23 = setuid */
+ { 0, (sy_call_t *)getuid }, /* 24 = getuid */
+ { 0, (sy_call_t *)linux_stime }, /* 25 = linux_stime */
+ { 0, (sy_call_t *)linux_ptrace }, /* 26 = linux_ptrace */
+ { 1, (sy_call_t *)linux_alarm }, /* 27 = linux_alarm */
+ { 2, (sy_call_t *)linux_fstat }, /* 28 = linux_fstat */
+ { 0, (sy_call_t *)linux_pause }, /* 29 = linux_pause */
+ { 2, (sy_call_t *)linux_utime }, /* 30 = linux_utime */
+ { 0, (sy_call_t *)linux_stty }, /* 31 = linux_stty */
+ { 0, (sy_call_t *)linux_gtty }, /* 32 = linux_gtty */
+ { 2, (sy_call_t *)linux_access }, /* 33 = linux_access */
+ { 0, (sy_call_t *)linux_nice }, /* 34 = linux_nice */
+ { 0, (sy_call_t *)linux_ftime }, /* 35 = linux_ftime */
+ { 0, (sy_call_t *)sync }, /* 36 = sync */
+ { 2, (sy_call_t *)linux_kill }, /* 37 = linux_kill */
+ { 2, (sy_call_t *)linux_rename }, /* 38 = linux_rename */
+ { 2, (sy_call_t *)linux_mkdir }, /* 39 = linux_mkdir */
+ { 1, (sy_call_t *)linux_rmdir }, /* 40 = linux_rmdir */
+ { 1, (sy_call_t *)dup }, /* 41 = dup */
+ { 1, (sy_call_t *)linux_pipe }, /* 42 = linux_pipe */
+ { 1, (sy_call_t *)linux_times }, /* 43 = linux_times */
+ { 0, (sy_call_t *)linux_prof }, /* 44 = linux_prof */
+ { 1, (sy_call_t *)linux_brk }, /* 45 = linux_brk */
+ { 1, (sy_call_t *)setgid }, /* 46 = setgid */
+ { 0, (sy_call_t *)getgid }, /* 47 = getgid */
+ { 2, (sy_call_t *)linux_signal }, /* 48 = linux_signal */
+ { 0, (sy_call_t *)geteuid }, /* 49 = geteuid */
+ { 0, (sy_call_t *)getegid }, /* 50 = getegid */
+ { 1, (sy_call_t *)acct }, /* 51 = acct */
+ { 0, (sy_call_t *)linux_phys }, /* 52 = linux_phys */
+ { 0, (sy_call_t *)linux_lock }, /* 53 = linux_lock */
+ { 3, (sy_call_t *)linux_ioctl }, /* 54 = linux_ioctl */
+ { 3, (sy_call_t *)linux_fcntl }, /* 55 = linux_fcntl */
+ { 0, (sy_call_t *)linux_mpx }, /* 56 = linux_mpx */
+ { 2, (sy_call_t *)setpgid }, /* 57 = setpgid */
+ { 0, (sy_call_t *)linux_ulimit }, /* 58 = linux_ulimit */
+ { 1, (sy_call_t *)linux_olduname }, /* 59 = linux_olduname */
+ { 1, (sy_call_t *)umask }, /* 60 = umask */
+ { 1, (sy_call_t *)chroot }, /* 61 = chroot */
+ { 0, (sy_call_t *)linux_ustat }, /* 62 = linux_ustat */
+ { 2, (sy_call_t *)dup2 }, /* 63 = dup2 */
+ { 0, (sy_call_t *)getppid }, /* 64 = getppid */
+ { 0, (sy_call_t *)getpgrp }, /* 65 = getpgrp */
+ { 0, (sy_call_t *)setsid }, /* 66 = setsid */
+ { 3, (sy_call_t *)linux_sigaction }, /* 67 = linux_sigaction */
+ { 0, (sy_call_t *)linux_siggetmask }, /* 68 = linux_siggetmask */
+ { 1, (sy_call_t *)linux_sigsetmask }, /* 69 = linux_sigsetmask */
+ { 2, (sy_call_t *)setreuid }, /* 70 = setreuid */
+ { 2, (sy_call_t *)setregid }, /* 71 = setregid */
+ { 1, (sy_call_t *)linux_sigsuspend }, /* 72 = linux_sigsuspend */
+ { 1, (sy_call_t *)linux_sigpending }, /* 73 = linux_sigpending */
+ { 2, (sy_call_t *)osethostname }, /* 74 = osethostname */
+ { 2, (sy_call_t *)osetrlimit }, /* 75 = osetrlimit */
+ { 2, (sy_call_t *)ogetrlimit }, /* 76 = ogetrlimit */
+ { 2, (sy_call_t *)getrusage }, /* 77 = getrusage */
+ { 2, (sy_call_t *)gettimeofday }, /* 78 = gettimeofday */
+ { 2, (sy_call_t *)settimeofday }, /* 79 = settimeofday */
+ { 2, (sy_call_t *)getgroups }, /* 80 = getgroups */
+ { 2, (sy_call_t *)setgroups }, /* 81 = setgroups */
+ { 1, (sy_call_t *)linux_select }, /* 82 = linux_select */
+ { 2, (sy_call_t *)linux_symlink }, /* 83 = linux_symlink */
+ { 2, (sy_call_t *)ostat }, /* 84 = ostat */
+ { 3, (sy_call_t *)linux_readlink }, /* 85 = linux_readlink */
+ { 1, (sy_call_t *)linux_uselib }, /* 86 = linux_uselib */
+ { 1, (sy_call_t *)swapon }, /* 87 = swapon */
+ { 1, (sy_call_t *)reboot }, /* 88 = reboot */
+ { 3, (sy_call_t *)linux_readdir }, /* 89 = linux_readdir */
+ { 1, (sy_call_t *)linux_mmap }, /* 90 = linux_mmap */
+ { 2, (sy_call_t *)munmap }, /* 91 = munmap */
+ { 2, (sy_call_t *)linux_truncate }, /* 92 = linux_truncate */
+ { 2, (sy_call_t *)oftruncate }, /* 93 = oftruncate */
+ { 2, (sy_call_t *)fchmod }, /* 94 = fchmod */
+ { 3, (sy_call_t *)fchown }, /* 95 = fchown */
+ { 2, (sy_call_t *)getpriority }, /* 96 = getpriority */
+ { 3, (sy_call_t *)setpriority }, /* 97 = setpriority */
+ { 4, (sy_call_t *)profil }, /* 98 = profil */
+ { 2, (sy_call_t *)linux_statfs }, /* 99 = linux_statfs */
+ { 2, (sy_call_t *)linux_fstatfs }, /* 100 = linux_fstatfs */
+ { 3, (sy_call_t *)linux_ioperm }, /* 101 = linux_ioperm */
+ { 2, (sy_call_t *)linux_socketcall }, /* 102 = linux_socketcall */
+ { 1, (sy_call_t *)linux_ksyslog }, /* 103 = linux_ksyslog */
+ { 3, (sy_call_t *)linux_setitimer }, /* 104 = linux_setitimer */
+ { 2, (sy_call_t *)linux_getitimer }, /* 105 = linux_getitimer */
+ { 2, (sy_call_t *)linux_newstat }, /* 106 = linux_newstat */
+ { 2, (sy_call_t *)linux_newlstat }, /* 107 = linux_newlstat */
+ { 2, (sy_call_t *)linux_newfstat }, /* 108 = linux_newfstat */
+ { 1, (sy_call_t *)linux_uname }, /* 109 = linux_uname */
+ { 1, (sy_call_t *)linux_iopl }, /* 110 = linux_iopl */
+ { 0, (sy_call_t *)linux_vhangup }, /* 111 = linux_vhangup */
+ { 0, (sy_call_t *)linux_idle }, /* 112 = linux_idle */
+ { 0, (sy_call_t *)linux_vm86 }, /* 113 = linux_vm86 */
+ { 4, (sy_call_t *)linux_wait4 }, /* 114 = linux_wait4 */
+ { 0, (sy_call_t *)linux_swapoff }, /* 115 = linux_swapoff */
+ { 0, (sy_call_t *)linux_sysinfo }, /* 116 = linux_sysinfo */
+ { 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 *)setdomainname }, /* 121 = setdomainname */
+ { 1, (sy_call_t *)linux_newuname }, /* 122 = linux_newuname */
+ { 3, (sy_call_t *)linux_modify_ldt }, /* 123 = linux_modify_ldt */
+ { 0, (sy_call_t *)linux_adjtimex }, /* 124 = linux_adjtimex */
+ { 3, (sy_call_t *)mprotect }, /* 125 = mprotect */
+ { 3, (sy_call_t *)linux_sigprocmask }, /* 126 = linux_sigprocmask */
+ { 0, (sy_call_t *)linux_create_module }, /* 127 = linux_create_module */
+ { 0, (sy_call_t *)linux_init_module }, /* 128 = linux_init_module */
+ { 0, (sy_call_t *)linux_delete_module }, /* 129 = linux_delete_module */
+ { 0, (sy_call_t *)linux_get_kernel_syms }, /* 130 = linux_get_kernel_syms */
+ { 0, (sy_call_t *)linux_quotactl }, /* 131 = linux_quotactl */
+ { 1, (sy_call_t *)linux_getpgid }, /* 132 = linux_getpgid */
+ { 1, (sy_call_t *)fchdir }, /* 133 = fchdir */
+ { 0, (sy_call_t *)linux_bdflush }, /* 134 = linux_bdflush */
+ { 0, (sy_call_t *)nosys }, /* 135 = sysfs */
+ { 1, (sy_call_t *)linux_personality }, /* 136 = linux_personality */
+ { 0, (sy_call_t *)nosys }, /* 137 = afs_syscall */
+ { 0, (sy_call_t *)nosys }, /* 138 = setfsuid */
+ { 0, (sy_call_t *)nosys }, /* 139 = getfsuid */
+ { 5, (sy_call_t *)linux_llseek }, /* 140 = linux_llseek */
+ { 3, (sy_call_t *)linux_getdents }, /* 141 = linux_getdents */
+ { 5, (sy_call_t *)linux_newselect }, /* 142 = linux_newselect */
+ { 2, (sy_call_t *)flock }, /* 143 = flock */
+ { 3, (sy_call_t *)linux_msync }, /* 144 = linux_msync */
+ { 3, (sy_call_t *)readv }, /* 145 = readv */
+ { 3, (sy_call_t *)writev }, /* 146 = writev */
};
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
new file mode 100644
index 0000000..9278102
--- /dev/null
+++ b/sys/i386/linux/linux_sysvec.c
@@ -0,0 +1,358 @@
+/*-
+ * Copyright (c) 1994-1995 Søren Schmidt
+ * All rights reserved.
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $Id: linux_sysent.c,v 1.4 1996/01/14 10:59:57 sos Exp $
+ */
+
+/* XXX we use functions that might not exist. */
+#define COMPAT_43 1
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/sysent.h>
+#include <sys/imgact.h>
+#include <sys/signalvar.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_prot.h>
+#include <vm/lock.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_extern.h>
+#include <sys/user.h>
+#include <sys/exec.h>
+#include <machine/cpu.h>
+#include <machine/frame.h>
+#include <machine/reg.h>
+#include <machine/specialreg.h>
+#include <machine/psl.h>
+#include <machine/sysarch.h>
+#include <machine/md_var.h>
+
+#include <i386/linux/linux.h>
+#include <i386/linux/linux_proto.h>
+#include <i386/linux/linux_syscall.h>
+
+/*
+ * Linux syscalls return negative errno's, we do positive and map them
+ */
+int bsd_to_linux_errno[ELAST] = {
+ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
+ -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+ -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+ -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+ -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+ -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
+ -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
+ -116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
+ -6,
+};
+
+int bsd_to_linux_signal[NSIG] = {
+ 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT,
+ LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0,
+ LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV,
+ 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM,
+ LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT,
+ LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO,
+ LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF,
+ LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2
+};
+
+int linux_to_bsd_signal[LINUX_NSIG] = {
+ 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT,
+ SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM,
+ SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGIO,
+ SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGURG, SIGURG, 0
+};
+
+int linux_fixup(int **stack_base, struct image_params *imgp)
+{
+ int *argv, *envp;
+
+ argv = *stack_base;
+ envp = *stack_base + (imgp->argc + 1);
+ (*stack_base)--;
+ **stack_base = (int)envp;
+ (*stack_base)--;
+ **stack_base = (int)argv;
+ (*stack_base)--;
+ **stack_base = (int)imgp->argc;
+ return 0; /* XXX */
+}
+
+extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
+
+static void linux_sendsig(sig_t action,
+ int sig,
+ int returnmask,
+ unsigned code);
+
+extern int _ucodesel, _udatasel;
+
+/*
+ * Send an interrupt to process.
+ *
+ * Stack is set up to allow sigcode stored
+ * in u. to call routine, followed by kcall
+ * to sigreturn routine below. After sigreturn
+ * resets the signal mask, the stack, and the
+ * frame pointer, it returns to the user
+ * specified pc, psl.
+ */
+
+static void
+linux_sendsig(catcher, sig, mask, code)
+ sig_t catcher;
+ int sig;
+ int mask;
+ unsigned code;
+{
+ register struct proc *p = curproc;
+ register int *regs;
+ struct linux_sigframe *fp, frame;
+ struct sigacts *psp = p->p_sigacts;
+ int oonstack;
+
+ regs = p->p_md.md_regs;
+ oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): linux_sendsig(%8x, %d, %d, %d)\n",
+ p->p_pid, catcher, sig, mask, code);
+#endif
+ /*
+ * Allocate space for the signal handler context.
+ */
+ if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
+ (psp->ps_sigonstack & sigmask(sig))) {
+ fp = (struct linux_sigframe *)(psp->ps_sigstk.ss_sp +
+ psp->ps_sigstk.ss_size - sizeof(struct linux_sigframe));
+ psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+ } else {
+ fp = (struct linux_sigframe *)regs[tESP] - 1;
+ }
+
+ /*
+ * grow() will return FALSE if the fp will not fit inside the stack
+ * and the stack can not be grown. useracc will return FALSE
+ * if access is denied.
+ */
+ if ((grow(p, (int)fp) == FALSE) ||
+ (useracc((caddr_t)fp, sizeof (struct linux_sigframe), B_WRITE) == FALSE)) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ SIGACTION(p, SIGILL) = SIG_DFL;
+ sig = sigmask(SIGILL);
+ p->p_sigignore &= ~sig;
+ p->p_sigcatch &= ~sig;
+ p->p_sigmask &= ~sig;
+ psignal(p, SIGILL);
+ return;
+ }
+
+ /*
+ * Build the argument list for the signal handler.
+ */
+ if (p->p_sysent->sv_sigtbl) {
+ if (sig < p->p_sysent->sv_sigsize)
+ sig = p->p_sysent->sv_sigtbl[sig];
+ else
+ sig = p->p_sysent->sv_sigsize + 1;
+ }
+
+ frame.sf_handler = catcher;
+ frame.sf_sig = sig;
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ frame.sf_sc.sc_mask = mask;
+ __asm("movl %%gs,%w0" : "=r" (frame.sf_sc.sc_gs));
+ __asm("movl %%fs,%w0" : "=r" (frame.sf_sc.sc_fs));
+ frame.sf_sc.sc_es = regs[tES];
+ frame.sf_sc.sc_ds = regs[tDS];
+ frame.sf_sc.sc_edi = regs[tEDI];
+ frame.sf_sc.sc_esi = regs[tESI];
+ frame.sf_sc.sc_ebp = regs[tEBP];
+ frame.sf_sc.sc_ebx = regs[tEBX];
+ frame.sf_sc.sc_edx = regs[tEDX];
+ frame.sf_sc.sc_ecx = regs[tECX];
+ frame.sf_sc.sc_eax = regs[tEAX];
+ frame.sf_sc.sc_eip = regs[tEIP];
+ frame.sf_sc.sc_cs = regs[tCS];
+ frame.sf_sc.sc_eflags = regs[tEFLAGS];
+ frame.sf_sc.sc_esp_at_signal = regs[tESP];
+ frame.sf_sc.sc_ss = regs[tSS];
+ frame.sf_sc.sc_err = regs[tERR];
+ frame.sf_sc.sc_trapno = code; /* XXX ???? */
+
+ if (copyout(&frame, fp, sizeof(frame)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ sigexit(p, SIGILL);
+ /* NOTREACHED */
+ }
+
+ /*
+ * Build context to run handler in.
+ */
+ regs[tESP] = (int)fp;
+ regs[tEIP] = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode));
+ regs[tEFLAGS] &= ~PSL_VM;
+ regs[tCS] = _ucodesel;
+ regs[tDS] = _udatasel;
+ regs[tES] = _udatasel;
+ regs[tSS] = _udatasel;
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper privileges or to cause
+ * a machine fault.
+ */
+int
+linux_sigreturn(p, args, retval)
+ struct proc *p;
+ struct linux_sigreturn_args *args;
+ int *retval;
+{
+ struct linux_sigcontext *scp, context;
+ register int *regs;
+ int eflags;
+
+ regs = p->p_md.md_regs;
+
+#ifdef DEBUG
+ printf("Linux-emul(%d): linux_sigreturn(%8x)\n", p->p_pid, args->scp);
+#endif
+ /*
+ * The trampoline code hands us the context.
+ * It is unsafe to keep track of it ourselves, in the event that a
+ * program jumps out of a signal handler.
+ */
+ scp = args->scp;
+ if (copyin((caddr_t)scp, &context, sizeof(*scp)) != 0)
+ return (EFAULT);
+
+ /*
+ * Check for security violations.
+ */
+#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
+ eflags = context.sc_eflags;
+ /*
+ * XXX do allow users to change the privileged flag PSL_RF. The
+ * cpu sets PSL_RF in tf_eflags for faults. Debuggers should
+ * sometimes set it there too. tf_eflags is kept in the signal
+ * context during signal handling and there is no other place
+ * to remember it, so the PSL_RF bit may be corrupted by the
+ * signal handler without us knowing. Corruption of the PSL_RF
+ * bit at worst causes one more or one less debugger trap, so
+ * allowing it is fairly harmless.
+ */
+ if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs[tEFLAGS] & ~PSL_RF)) {
+ return(EINVAL);
+ }
+
+ /*
+ * Don't allow users to load a valid privileged %cs. Let the
+ * hardware check for invalid selectors, excess privilege in
+ * other selectors, invalid %eip's and invalid %esp's.
+ */
+#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
+ if (!CS_SECURE(context.sc_cs)) {
+ trapsignal(p, SIGBUS, T_PROTFLT);
+ return(EINVAL);
+ }
+
+ p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+ p->p_sigmask = context.sc_mask &~
+ (sigmask(SIGKILL)|sigmask(SIGCONT)|sigmask(SIGSTOP));
+ /*
+ * Restore signal context.
+ */
+ /* %fs and %gs were restored by the trampoline. */
+ regs[tES] = context.sc_es;
+ regs[tDS] = context.sc_ds;
+ regs[tEDI] = context.sc_edi;
+ regs[tESI] = context.sc_esi;
+ regs[tEBP] = context.sc_ebp;
+ regs[tEBX] = context.sc_ebx;
+ regs[tEDX] = context.sc_edx;
+ regs[tECX] = context.sc_ecx;
+ regs[tEAX] = context.sc_eax;
+ regs[tEIP] = context.sc_eip;
+ regs[tCS] = context.sc_cs;
+ regs[tEFLAGS] = eflags;
+ regs[tESP] = context.sc_esp_at_signal;
+ regs[tSS] = context.sc_ss;
+
+ return (EJUSTRETURN);
+}
+
+static void
+linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
+{
+ int i;
+ args[0] = tf->tf_ebx;
+ args[1] = tf->tf_ecx;
+ args[2] = tf->tf_edx;
+ args[3] = tf->tf_esi;
+ args[4] = tf->tf_edi;
+ *params = NULL; /* no copyin */
+}
+
+extern char linux_sigcode[];
+extern int linux_szsigcode;
+
+struct sysentvec linux_sysvec = {
+ sizeof (linux_sysent) / sizeof(linux_sysent[0]),
+ linux_sysent,
+ 0xff,
+ NSIG,
+ bsd_to_linux_signal,
+ ELAST,
+ bsd_to_linux_errno,
+ linux_fixup,
+ linux_sendsig,
+ linux_sigcode,
+ &linux_szsigcode,
+ linux_prepsyscall,
+};
diff --git a/sys/i386/linux/linux_util.c b/sys/i386/linux/linux_util.c
new file mode 100644
index 0000000..1785fd3
--- /dev/null
+++ b/sys/i386/linux/linux_util.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * Copyright (c) 1995 Frank van der Linden
+ * Copyright (c) 1995 Scott Bartram
+ * All rights reserved.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * from: svr4_util.c,v 1.5 1995/01/22 23:44:50 christos Exp
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+
+#include <i386/linux/linux_util.h>
+
+const char linux_emul_path[] = "/compat/linux";
+
+/*
+ * Search an alternate path before passing pathname arguments on
+ * to system calls. Useful for keeping a seperate 'emulation tree'.
+ *
+ * If cflag is set, we check if an attempt can be made to create
+ * the named file, i.e. we check if the directory it should
+ * be in exists.
+ */
+int
+linux_emul_find(p, sgp, prefix, path, pbuf, cflag)
+ struct proc *p;
+ caddr_t *sgp; /* Pointer to stackgap memory */
+ const char *prefix;
+ char *path;
+ char **pbuf;
+ int cflag;
+{
+ struct nameidata nd;
+ struct nameidata ndroot;
+ struct vattr vat;
+ struct vattr vatroot;
+ int error;
+ char *ptr, *buf, *cp;
+ size_t sz, len;
+
+ buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ *pbuf = path;
+
+ for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
+ continue;
+
+ sz = MAXPATHLEN - (ptr - buf);
+
+ /*
+ * If sgp is not given then the path is already in kernel space
+ */
+ if (sgp == NULL)
+ error = copystr(path, ptr, sz, &len);
+ else
+ error = copyinstr(path, ptr, sz, &len);
+
+ if (error) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ if (*ptr != '/') {
+ free(buf, M_TEMP);
+ return EINVAL;
+ }
+
+ /*
+ * We know that there is a / somewhere in this pathname.
+ * Search backwards for it, to find the file's parent dir
+ * to see if it exists in the alternate tree. If it does,
+ * and we want to create a file (cflag is set). We don't
+ * need to worry about the root comparison in this case.
+ */
+
+ if (cflag) {
+ for (cp = &ptr[len] - 1; *cp != '/'; cp--);
+ *cp = '\0';
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
+
+ if ((error = namei(&nd)) != 0) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ *cp = '/';
+ }
+ else {
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
+
+ if ((error = namei(&nd)) != 0) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ /*
+ * We now compare the vnode of the linux_root to the one
+ * vnode asked. If they resolve to be the same, then we
+ * ignore the match so that the real root gets used.
+ * This avoids the problem of traversing "../.." to find the
+ * root directory and never finding it, because "/" resolves
+ * to the emulation root directory. This is expensive :-(
+ */
+ /* XXX: prototype should have const here for NDINIT */
+ NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE,
+ (char *) linux_emul_path, p);
+
+ if ((error = namei(&ndroot)) != 0) {
+ /* Cannot happen! */
+ free(buf, M_TEMP);
+ vrele(nd.ni_vp);
+ return error;
+ }
+
+ if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
+ goto done;
+ }
+
+ if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
+ != 0) {
+ goto done;
+ }
+
+ if (vat.va_fsid == vatroot.va_fsid &&
+ vat.va_fileid == vatroot.va_fileid) {
+ error = ENOENT;
+ goto done;
+ }
+
+ }
+ if (sgp == NULL)
+ *pbuf = buf;
+ else {
+ sz = &ptr[len] - buf;
+ *pbuf = stackgap_alloc(sgp, sz + 1);
+ error = copyout(buf, *pbuf, sz);
+ free(buf, M_TEMP);
+ }
+
+
+done:
+ vrele(nd.ni_vp);
+ if (!cflag)
+ vrele(ndroot.ni_vp);
+ return error;
+}
diff --git a/sys/i386/linux/linux_generic.c b/sys/i386/linux/linux_util.h
index da528c1..46edfc5 100644
--- a/sys/i386/linux/linux_generic.c
+++ b/sys/i386/linux/linux_util.h
@@ -1,18 +1,19 @@
-/*-
- * Copyright (c) 1995 Søren Schmidt
+/*
+ * Copyright (c) 1994 Christos Zoulas
+ * Copyright (c) 1995 Frank van der Linden
+ * Copyright (c) 1995 Scott Bartram
* All rights reserved.
*
* 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
- * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,37 +26,67 @@
* (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_generic.c,v 1.3 1995/12/09 04:31:47 peter Exp $
+ * from: svr4_util.h,v 1.5 1994/11/18 02:54:31 christos Exp
+ * from: linux_util.h,v 1.2 1995/03/05 23:23:50 fvdl Exp
+ * $Id$
*/
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/exec.h>
+/*
+ * This file is pretty much the same as Christos' svr4_util.h
+ * (for now).
+ */
-#include <vm/vm.h> /* XXX for a macro in exec.h */
+#ifndef _LINUX_UTIL_H_
+#define _LINUX_UTIL_H_
+
+#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/vmparam.h>
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/cdefs.h>
-#include <i386/linux/linux.h>
+#ifndef SCARG
+#define SCARG(p, x) (p)->x
+#endif
-static caddr_t ua_ptr = NULL;
+static __inline caddr_t stackgap_init(void);
+static __inline void *stackgap_alloc(caddr_t *, size_t);
-caddr_t ua_alloc_init(int len)
+static __inline caddr_t
+stackgap_init()
{
- caddr_t ptr;
-
- ptr = (caddr_t)ALIGN((PS_STRINGS));
- ptr -= SPARE_USRSPACE;
- ua_ptr = (caddr_t)(ptr + ALIGN(len));
- return ptr;
+#define szsigcode (*(curproc->p_sysent->sv_szsigcode), sizeof(char *))
+ return (caddr_t)(((caddr_t)PS_STRINGS) - szsigcode - SPARE_USRSPACE);
}
-caddr_t ua_alloc(int len)
-{
- caddr_t ptr;
- ptr = ua_ptr;
- ua_ptr += ALIGN(len);
- return ptr;
+static __inline void *
+stackgap_alloc(sgp, sz)
+ caddr_t *sgp;
+ size_t sz;
+{
+ void *p = (void *) *sgp;
+ *sgp += ALIGN(sz);
+ return p;
}
+
+#ifdef DEBUG_LINUX
+#define DPRINTF(a) printf a;
+#else
+#define DPRINTF(a)
+#endif
+
+extern const char linux_emul_path[];
+
+int linux_emul_find __P((struct proc *, caddr_t *, const char *, char *,
+ char **, int));
+
+#define CHECKALTEXIST(p, sgp, path) \
+ linux_emul_find(p, sgp, linux_emul_path, path, &(path), 0)
+
+#define CHECKALTCREAT(p, sgp, path) \
+ linux_emul_find(p, sgp, linux_emul_path, path, &(path), 1)
+
+#endif /* !_LINUX_UTIL_H_ */
diff --git a/sys/i386/linux/sysproto.h b/sys/i386/linux/sysproto.h
deleted file mode 100644
index ea6ab57..0000000
--- a/sys/i386/linux/sysproto.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*-
- * Prototypes for linux system call functions.
- * Bruce Evans, November 1995.
- * This file is in the public domain.
- */
-
-#ifndef _I386_LINUX_SYSPROTO_H_
-#define _I386_LINUX_SYSPROTO_H_
-
-struct linux_accept_args;
-struct linux_alarm_args;
-struct linux_bind_args;
-struct linux_brk_args;
-struct linux_connect_args;
-struct linux_creat_args;
-struct linux_fcntl_args;
-struct linux_fstatfs_args;
-struct linux_getpeername_args;
-struct linux_getpgid_args;
-struct linux_getsockname_args;
-struct linux_getsockopt_args;
-struct linux_ioctl_args;
-struct linux_ipc_args;
-struct linux_kill_args;
-struct linux_listen_args;
-struct linux_lseek_args;
-struct linux_mmap_args;
-struct linux_mknod_args;
-struct linux_newfstat_args;
-struct linux_newstat_args;
-struct linux_newuname_args;
-struct linux_open_args;
-struct linux_pipe_args;
-struct linux_readdir_args;
-struct linux_recv_args;
-struct linux_recvfrom_args;
-struct linux_select_args;
-struct linux_send_args;
-struct linux_sendto_args;
-struct linux_setsockopt_args;
-struct linux_shutdown_args;
-struct linux_sigaction_args;
-struct linux_sigpending_args;
-struct linux_sigprocmask_args;
-struct linux_sigsetmask_args;
-struct linux_sigsuspend_args;
-struct linux_socket_args;
-struct linux_socketcall_args;
-struct linux_socketpair_args;
-struct linux_statfs_args;
-struct linux_time_args;
-struct linux_tms_args;
-struct linux_uselib_args;
-struct linux_utime_args;
-struct linux_wait4_args;
-struct linux_waitpid_args;
-
-/* linux_dummy.c */
-int linux_adjtimex __P((struct proc *p, void *args, int *retval));
-int linux_bdflush __P((struct proc *p, void *args, int *retval));
-int linux_break __P((struct proc *p, void *args, int *retval));
-int linux_clone __P((struct proc *p, void *args, int *retval));
-int linux_create_module __P((struct proc *p, void *args, int *retval));
-int linux_delete_module __P((struct proc *p, void *args, int *retval));
-int linux_fstat __P((struct proc *p, void *args, int *retval));
-int linux_ftime __P((struct proc *p, void *args, int *retval));
-int linux_get_kernel_syms __P((struct proc *p, void *args, int *retval));
-int linux_gtty __P((struct proc *p, void *args, int *retval));
-int linux_idle __P((struct proc *p, void *args, int *retval));
-int linux_init_module __P((struct proc *p, void *args, int *retval));
-int linux_ioperm __P((struct proc *p, void *args, int *retval));
-int linux_iopl __P((struct proc *p, void *args, int *retval));
-int linux_lock __P((struct proc *p, void *args, int *retval));
-int linux_modify_ldt __P((struct proc *p, void *args, int *retval));
-int linux_mount __P((struct proc *p, void *args, int *retval));
-int linux_mpx __P((struct proc *p, void *args, int *retval));
-int linux_nice __P((struct proc *p, void *args, int *retval));
-int linux_olduname __P((struct proc *p, void *args, int *retval));
-int linux_pause __P((struct proc *p, void *args, int *retval));
-int linux_phys __P((struct proc *p, void *args, int *retval));
-int linux_prof __P((struct proc *p, void *args, int *retval));
-int linux_ptrace __P((struct proc *p, void *args, int *retval));
-int linux_quotactl __P((struct proc *p, void *args, int *retval));
-int linux_setup __P((struct proc *p, void *args, int *retval));
-int linux_signal __P((struct proc *p, void *args, int *retval));
-int linux_sigreturn __P((struct proc *p, void *args, int *retval));
-int linux_stat __P((struct proc *p, void *args, int *retval));
-int linux_stime __P((struct proc *p, void *args, int *retval));
-int linux_stty __P((struct proc *p, void *args, int *retval));
-int linux_swapoff __P((struct proc *p, void *args, int *retval));
-int linux_sysinfo __P((struct proc *p, void *args, int *retval));
-int linux_syslog __P((struct proc *p, void *args, int *retval));
-int linux_ulimit __P((struct proc *p, void *args, int *retval));
-int linux_umount __P((struct proc *p, void *args, int *retval));
-int linux_uname __P((struct proc *p, void *args, int *retval));
-int linux_ustat __P((struct proc *p, void *args, int *retval));
-int linux_vhangup __P((struct proc *p, void *args, int *retval));
-int linux_vm86 __P((struct proc *p, void *args, int *retval));
-
-/* linux_file.c */
-int linux_creat __P((struct proc *p, struct linux_creat_args *args,
- int *retval));
-int linux_fcntl __P((struct proc *p, struct linux_fcntl_args *args,
- int *retval));
-int linux_lseek __P((struct proc *p, struct linux_lseek_args *args,
- int *retval));
-int linux_open __P((struct proc *p, struct linux_open_args *args,
- int *retval));
-int linux_readdir __P((struct proc *p, struct linux_readdir_args *args,
- int *retval));
-
-/* linux_ioctl.c */
-int linux_ioctl __P((struct proc *p, struct linux_ioctl_args *args,
- int *retval));
-
-/* linux_ipc.c */
-int linux_ipc __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_msgctl __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_msgget __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_msgrcv __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_msgsnd __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_semctl __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_semget __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_semop __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_shmat __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_shmctl __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_shmdt __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-int linux_shmget __P((struct proc *p, struct linux_ipc_args *args,
- int *retval));
-
-/* linux_misc.c */
-int linux_alarm __P((struct proc *p, struct linux_alarm_args *args,
- int *retval));
-int linux_brk __P((struct proc *p, struct linux_brk_args *args,
- int *retval));
-int linux_fork __P((struct proc *p, void *args, int *retval));
-int linux_getpgid __P((struct proc *p, struct linux_getpgid_args *args,
- int *retval));
-int linux_mknod __P((struct proc *p, struct linux_mknod_args *args,
- int *retval));
-int linux_mmap __P((struct proc *p, struct linux_mmap_args *args,
- int *retval));
-int linux_newuname __P((struct proc *p, struct linux_newuname_args *args,
- int *retval));
-int linux_pipe __P((struct proc *p, struct linux_pipe_args *args,
- int *retval));
-int linux_select __P((struct proc *p, struct linux_select_args *args,
- int *retval));
-int linux_time __P((struct proc *p, struct linux_time_args *args,
- int *retval));
-int linux_times __P((struct proc *p, struct linux_tms_args *args,
- int *retval));
-int linux_uselib __P((struct proc *p, struct linux_uselib_args *args,
- int *retval));
-int linux_utime __P((struct proc *p, struct linux_utime_args *args,
- int *retval));
-int linux_wait4 __P((struct proc *p, struct linux_wait4_args *args,
- int *retval));
-int linux_waitpid __P((struct proc *p, struct linux_waitpid_args *args,
- int *retval));
-
-/* linux_signal.c */
-int linux_kill __P((struct proc *p, struct linux_kill_args *args,
- int *retval));
-int linux_sigaction __P((struct proc *p, struct linux_sigaction_args *args,
- int *retval));
-int linux_siggetmask __P((struct proc *p, void *args, int *retval));
-int linux_sigpending __P((struct proc *p,
- struct linux_sigpending_args *args, int *retval));
-int linux_sigprocmask __P((struct proc *p,
- struct linux_sigprocmask_args *args,
- int *retval));
-int linux_sigsetmask __P((struct proc *p,
- struct linux_sigsetmask_args *args, int *retval));
-int linux_sigsuspend __P((struct proc *p,
- struct linux_sigsuspend_args *args, int *retval));
-
-/* linux_socket.c */
-int linux_socketcall __P((struct proc *p,
- struct linux_socketcall_args *args, int *retval));
-
-/* linux_stats.c */
-int linux_fstatfs __P((struct proc *p, struct linux_fstatfs_args *args,
- int *retval));
-int linux_newfstat __P((struct proc *p, struct linux_newfstat_args *args,
- int *retval));
-int linux_newlstat __P((struct proc *p, struct linux_newstat_args *args,
- int *retval));
-int linux_newstat __P((struct proc *p, struct linux_newstat_args *args,
- int *retval));
-int linux_statfs __P((struct proc *p, struct linux_statfs_args *args,
- int *retval));
-
-struct image_params;
-int linux_fixup __P((int **stack_base, struct image_params *iparams));
-
-extern struct sysentvec linux_sysvec;
-
-#endif /* !_I386_LINUX_SYSPROTO_H_ */
OpenPOWER on IntegriCloud