aboutsummaryrefslogtreecommitdiff
path: root/sys/i386
diff options
context:
space:
mode:
authorSøren Schmidt <sos@FreeBSD.org>1994-10-14 08:53:16 +0000
committerSøren Schmidt <sos@FreeBSD.org>1994-10-14 08:53:16 +0000
commit69b770e2387017634aa821acca3145a34274c606 (patch)
tree03e7e36f42559e1855d7488025f88b38a06ded17 /sys/i386
parent29b9e87cdd7f34aa1fbd411a7c9c840b637ba662 (diff)
downloadsrc-69b770e2387017634aa821acca3145a34274c606.tar.gz
src-69b770e2387017634aa821acca3145a34274c606.zip
iBCS2 emulator core files.
This is the main files for the iBCS2 emulator. It can be use compiled into the kernel by using: options IBCS2 options COMPAT_IBCS2 or as a lkm module using: options COMPAT_IBCS2 and then loading it via the ibcs2 script in /usr/bin REMEMBER: this code is still experimental ! NO WARRENTY ! Submitted by: sef@kithrup.com, mostyn@mrl.com, sos@kmd-ac.dk
Notes
Notes: svn path=/head/; revision=3584
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/ibcs2/coff.h106
-rw-r--r--sys/i386/ibcs2/ibcs2.h42
-rw-r--r--sys/i386/ibcs2/ibcs2_dummy.c169
-rw-r--r--sys/i386/ibcs2/ibcs2_file.c525
-rw-r--r--sys/i386/ibcs2/ibcs2_ioctl.c913
-rw-r--r--sys/i386/ibcs2/ibcs2_ipc.c75
-rw-r--r--sys/i386/ibcs2/ibcs2_isc.c191
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c968
-rw-r--r--sys/i386/ibcs2/ibcs2_signal.c462
-rw-r--r--sys/i386/ibcs2/ibcs2_socksys.c1450
-rw-r--r--sys/i386/ibcs2/ibcs2_socksys.h398
-rw-r--r--sys/i386/ibcs2/ibcs2_stats.c285
-rw-r--r--sys/i386/ibcs2/ibcs2_sysent.c500
-rw-r--r--sys/i386/ibcs2/ibcs2_sysi86.c68
-rw-r--r--sys/i386/ibcs2/ibcs2_xenix.c367
-rw-r--r--sys/i386/ibcs2/imgact_coff.c457
16 files changed, 6962 insertions, 14 deletions
diff --git a/sys/i386/ibcs2/coff.h b/sys/i386/ibcs2/coff.h
new file mode 100644
index 000000000000..0a25b84ee584
--- /dev/null
+++ b/sys/i386/ibcs2/coff.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1994 Sean Eric Fagan
+ * Copyright (c) 1994 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: coff.h,v 1.1 1994/10/12 19:37:16 sos Exp $
+ */
+
+#ifndef _COFF_H
+#define _COFF_H
+
+struct filehdr {
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* # of sections */
+ long f_timdat; /* time stamp */
+ long f_symptr; /* symbol table offset */
+ long f_nsyms; /* # of symbols */
+ unsigned short f_opthdr; /* size of system header */
+ unsigned short f_flags; /* flags, see below */
+};
+
+enum filehdr_flags {
+ F_RELFLG = 0x01, /* relocs have been stripped */
+ F_EXEC = 0x02, /* executable file (or shlib) */
+ F_LNNO = 0x04, /* line numbers have been stripped */
+ F_LSYMS = 0x08, /* symbols have been stripped */
+ F_SWABD = 0x40, /* swabbed byte names */
+ F_AR16WR = 0x80, /* 16-bit, byte reversed words */
+ F_AR32WR = 0x100 /* 32-bit, byte reversed words */
+};
+
+struct aouthdr {
+ short magic; /* magic number -- see below */
+ short vstamp; /* artifacts from a by-gone day */
+ long tsize; /* */
+ long dsize; /* */
+ long bsize; /* */
+ long entry; /* Entry point -- offset into file */
+ long tstart; /* artifacts from a by-gone day */
+ long dstart; /* */
+};
+
+#define I386_COFF 0x14c
+
+#define COFF_OMAGIC 0407 /* impure format */
+#define COFF_NMAGIC 0410 /* read-only text */
+#define COFF_ZMAGIC 0413 /* pagable from disk */
+#define COFF_SHLIB 0443 /* a shared library */
+
+struct scnhdr {
+ char s_name[8]; /* name of section (e.g., ".text") */
+ long s_paddr; /* physical addr, used for standalone */
+ long s_vaddr; /* virtual address */
+ long s_size; /* size of section */
+ long s_scnptr; /* file offset of section */
+ long s_relptr; /* points to relocs for section */
+ long s_lnnoptr; /* points to line numbers for section */
+ unsigned short s_nreloc; /* # of relocs */
+ unsigned short s_nlnno; /* # of line no's */
+ long s_flags; /* section flags -- see below */
+};
+
+enum scnhdr_flags {
+ STYP_REG = 0x00, /* regular (alloc'ed, reloc'ed, loaded) */
+ STYP_DSECT = 0x01, /* dummy (reloc'd) */
+ STYP_NOLOAD = 0x02, /* no-load (reloc'd) */
+ STYP_GROUP = 0x04, /* grouped */
+ STYP_PAD = 0x08, /* padding (loaded) */
+ STYP_COPY = 0x10, /* ??? */
+ STYP_TEXT = 0x20, /* text */
+ STYP_DATA = 0x40, /* data */
+ STYP_BSS = 0x80, /* bss */
+ STYP_INFO = 0x200, /* comment (!loaded, !alloc'ed, !reloc'd) */
+ STYP_OVER = 0x400, /* overlay (!allocated, reloc'd, !loaded) */
+ STYP_LIB = 0x800 /* lists shared library files */
+};
+
+struct slhdr {
+ long entry_length;
+ long path_index;
+ char *shlib_name;
+};
+#endif /* _COFF_H */
diff --git a/sys/i386/ibcs2/ibcs2.h b/sys/i386/ibcs2/ibcs2.h
index 35b1a7d9524a..85f1cbdece29 100644
--- a/sys/i386/ibcs2/ibcs2.h
+++ b/sys/i386/ibcs2/ibcs2.h
@@ -26,18 +26,18 @@
* (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: ibcs2.h,v 1.10 1994/10/13 12:13:00 sos Exp $
+ * $Id: ibcs2.h,v 1.11 1994/10/13 23:10:58 sos Exp $
*/
-/* trace all ibcs2 system calls */
+/* trace all iBCS2 system calls */
extern int ibcs2_trace;
-/* convert signals between bsd & ibcs2 */
+/* convert signals between bsd & iBCS2 */
extern int bsd_to_ibcs2_signal[];
extern int ibcs2_to_bsd_signal[];
char *ibcs2_sig_to_str(int);
-/* ibcs2 type definitions */
+/* iBCS2 type definitions */
typedef char * ibcs2_caddr_t;
typedef long ibcs2_daddr_t;
typedef long ibcs2_off_t;
@@ -74,7 +74,7 @@ typedef void (*ibcs2_sig_t) (int);
*(((int *)arg) - 1) = retval[1]; \
return(0);
-/* ibcs signal numbers */
+/* iBCS2 signal numbers */
#define IBCS2_SIGHUP 1
#define IBCS2_SIGINT 2
#define IBCS2_SIGQUIT 3
@@ -117,7 +117,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_SIG_IGN (void (*)())1
#define IBCS2_SIG_HOLD (void (*)())2
-/* ibcs open & fcntl file modes */
+/* iBCS2 open & fcntl file modes */
#define IBCS2_RDONLY 0x000
#define IBCS2_WRONLY 0x001
#define IBCS2_RDWR 0x002
@@ -131,7 +131,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_NOCTTY 0x800
#define IBCS2_PRIV 0x1000
-/* ibcs fcntl commands */
+/* iBCS2 fcntl commands */
#define IBCS2_F_DUPFD 0
#define IBCS2_F_GETFD 1
#define IBCS2_F_SETFD 2
@@ -145,7 +145,21 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_F_WRLCK 2
#define IBCS2_F_UNLCK 3
-/* ibcs termio input modes */
+/* iBCS2 poll commands */
+#define IBCS2_POLLIN 0x0001
+#define IBCS2_POLLPRI 0x0002
+#define IBCS2_POLLOUT 0x0004
+#define IBCS2_POLLERR 0x0008
+#define IBCS2_POLLHUP 0x0010
+#define IBCS2_POLLNVAL 0x0020
+#define IBCS2_POLLRDNORM 0x0040
+#define IBCS2_POLLWRNORM 0x0004
+#define IBCS2_POLLRDBAND 0x0080
+#define IBCS2_POLLWRBAND 0x0100
+#define IBCS2_READPOLL (IBCS2_POLLIN|IBCS2_POLLRDNORM|IBCS2_POLLRDBAND)
+#define IBCS2_WRITEPOLL (IBCS2_POLLOUT|IBCS2_POLLWRNORM|IBCS2_POLLWRBAND)
+
+/* iBCS2 termio input modes */
#define IBCS2_IGNBRK 0x0001
#define IBCS2_BRKINT 0x0002
#define IBCS2_IGNPAR 0x0004
@@ -161,7 +175,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_IXOFF 0x1000
#define IBCS2_DOSMODE 0x8000
-/* ibcs termio output modes */
+/* iBCS2 termio output modes */
#define IBCS2_OPOST 0x0001
#define IBCS2_OLCUC 0x0002
#define IBCS2_ONLCR 0x0004
@@ -179,7 +193,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_VT1 0x4000
#define IBCS2_FF1 0x8000
-/* ibcs termio control modes */
+/* iBCS2 termio control modes */
#define IBCS2_CBAUD 0x000F
#define IBCS2_B0 0x0
#define IBCS2_B50 0x0001
@@ -213,7 +227,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_LOBLK 0x4000
#define IBCS2_XCLUDE 0x8000
-/* ibcs termio line discipline 0 modes */
+/* iBCS2 termio line discipline 0 modes */
#define IBCS2_ISIG 0x0001
#define IBCS2_ICANON 0x0002
#define IBCS2_XCASE 0x0004
@@ -223,7 +237,7 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_ECHONL 0x0040
#define IBCS2_NOFLSH 0x0080
-/* ibcs control characters */
+/* iBCS2 control characters */
#define IBCS2_VINTR 0
#define IBCS2_VQUIT 1
#define IBCS2_VERASE 2
@@ -240,13 +254,13 @@ typedef void (*ibcs2_sig_t) (int);
#define IBCS2_NCC 8 /* termio */
#define IBCS2_NCCS 13 /* termios */
-/* ibcs ulimit commands */
+/* iBCS2 ulimit commands */
#define IBCS2_GETFSIZE 1
#define IBCS2_SETFSIZE 2
#define IBCS2_GETPSIZE 3
#define IBCS2_GETMOPEN 4
-/* ibcs emulator trace control */
+/* iBCS2 emulator trace control */
#define IBCS2_TRACE_FILE 0x00000001
#define IBCS2_TRACE_IOCTL 0x00000002
#define IBCS2_TRACE_ISC 0x00000004
diff --git a/sys/i386/ibcs2/ibcs2_dummy.c b/sys/i386/ibcs2/ibcs2_dummy.c
new file mode 100644
index 000000000000..f267e4c98aec
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_dummy.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * 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: ibcs2_dummy.c,v 1.14 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/sysent.h>
+#include <sys/errno.h>
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+int
+ibcs2_nosys(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: no such syscall eax = %d(0x%x)\n",
+ ((struct trapframe*)p->p_md.md_regs)->tf_eax,
+ ((struct trapframe*)p->p_md.md_regs)->tf_eax);
+ return ENOSYS;
+}
+
+int
+ibcs2_clocal(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'clocal' not implemented yet\n");
+ return EINVAL;
+}
+
+int
+ibcs2_sysfs(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'sysfs' not implemented yet\n");
+ return EINVAL;
+}
+
+int
+ibcs2_uadmin(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'uadmin' not implemented yet\n");
+ return EINVAL;
+}
+
+int
+ibcs2_advfs(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'advfs' not implemented yet\n");
+ return EINVAL;
+}
+
+int
+ibcs2_unadvfs(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'unadvfs' not implemented yet\n");
+ return EINVAL;
+}
+
+int
+ibcs2_libattach(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'libattach' obsolete\n");
+ return EINVAL;
+}
+
+int
+ibcs2_libdetach(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'libdetach' obsolete\n");
+ return EINVAL;
+}
+
+int
+ibcs2_plock(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'plock' not supported\n");
+ return 0;
+}
+
+
+/*
+ * getmsg/putmsg are STREAMS related system calls
+ * We don't have STREAMS (yet??) but fake it anyways
+ */
+int
+ibcs2_getmsg(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'getmsg' not supported\n");
+ return 0;
+}
+
+int
+ibcs2_putmsg(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'putmsg' not supported\n");
+ return 0;
+}
+
+/*
+ * The following are RFS system calls
+ * We don't have RFS.
+ */
+int
+ibcs2_rfdebug(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rdebug' not supported\n");
+ return EINVAL;
+}
+
+int
+ibcs2_rfstart(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rfstart' not supported\n");
+ return EINVAL;
+}
+
+int
+ibcs2_rfstop(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rfstop' not supported\n");
+ return EINVAL;
+}
+
+int
+ibcs2_rfsys(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rfsys' not supported\n");
+ return EINVAL;
+}
+
+int
+ibcs2_rmount(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rmount' not supported\n");
+ return EINVAL;
+}
+
+int
+ibcs2_rumount(struct proc *p, void *args, int *retval)
+{
+ printf("IBCS2: 'rumount' not supported\n");
+ return EINVAL;
+}
diff --git a/sys/i386/ibcs2/ibcs2_file.c b/sys/i386/ibcs2/ibcs2_file.c
new file mode 100644
index 000000000000..c39684b1e72b
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_file.c
@@ -0,0 +1,525 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * All rights reserved.
+ *
+ * Copyright (c) 1989 The Regents of the University of California.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ibcs2_file.c,v 1.8 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/exec.h>
+#include <vm/vm.h>
+#include <ufs/ufs/dir.h>
+
+
+struct ibcs2_close_args {
+ int fd;
+};
+
+int
+ibcs2_close(struct proc *p, struct ibcs2_close_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'close' fd=%d\n", args->fd);
+ return close(p, args, retval);
+}
+
+struct ibcs2_creat_args {
+ char *fname;
+ int fmode;
+};
+
+int
+ibcs2_creat(struct proc *p, struct ibcs2_creat_args *args, int *retval)
+{
+ struct args {
+ char *fname;
+ int mode;
+ int crtmode;
+ } bsd_open_args;
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'creat' name=%s, mode=%x\n",
+ args->fname, args->fmode);
+ bsd_open_args.fname = args->fname;
+ bsd_open_args.crtmode = args->fmode;
+ bsd_open_args.mode = O_WRONLY | O_CREAT | O_TRUNC;
+ return open(p, &bsd_open_args, retval);
+}
+
+int
+ibcs2_dup(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'dup'\n");
+ return dup(p, args, retval);
+}
+
+struct ibcs2_flock {
+ short l_type;
+ short l_whence;
+ ibcs2_off_t l_start;
+ ibcs2_off_t l_len;
+ short l_sysid;
+ ibcs2_pid_t l_pid;
+};
+
+static void
+ibcs2_to_bsd_flock(struct ibcs2_flock *ibcs2_flock, struct flock *bsd_flock)
+{
+ switch (ibcs2_flock->l_type) {
+ case IBCS2_F_RDLCK:
+ bsd_flock->l_type = F_RDLCK;
+ break;
+ case IBCS2_F_WRLCK:
+ bsd_flock->l_type = F_WRLCK;
+ break;
+ case IBCS2_F_UNLCK:
+ bsd_flock->l_type = F_UNLCK;
+ break;
+ }
+ bsd_flock->l_whence = ibcs2_flock->l_whence;
+ bsd_flock->l_start = (off_t)ibcs2_flock->l_start;
+ bsd_flock->l_len = (off_t)ibcs2_flock->l_len;
+ bsd_flock->l_pid = (pid_t)ibcs2_flock->l_pid;
+}
+
+static void
+bsd_to_ibcs2_flock(struct flock *bsd_flock, struct ibcs2_flock *ibcs2_flock)
+{
+ switch (bsd_flock->l_type) {
+ case F_RDLCK:
+ ibcs2_flock->l_type = IBCS2_F_RDLCK;
+ break;
+ case F_WRLCK:
+ ibcs2_flock->l_type = IBCS2_F_WRLCK;
+ break;
+ case F_UNLCK:
+ ibcs2_flock->l_type = IBCS2_F_UNLCK;
+ break;
+ }
+ ibcs2_flock->l_whence = bsd_flock->l_whence;
+ ibcs2_flock->l_start = (ibcs2_off_t)bsd_flock->l_start;
+ ibcs2_flock->l_len = (ibcs2_off_t)bsd_flock->l_len;
+ ibcs2_flock->l_sysid = 0;
+ ibcs2_flock->l_pid = (ibcs2_pid_t)bsd_flock->l_pid;
+}
+
+struct ibcs2_fcntl_args {
+ int fd;
+ int cmd;
+ int arg;
+};
+
+int
+ibcs2_fcntl(struct proc *p, struct ibcs2_fcntl_args *args, int *retval)
+{
+ int error, result;
+ struct fcntl_args {
+ int fd;
+ int cmd;
+ int arg;
+ } fcntl_args;
+ struct ibcs2_flock ibcs2_flock;
+ struct flock *bsd_flock = (struct flock *)UA_ALLOC();
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'fcntl' fd=%d, cmd=%d arg=%d\n",
+ args->fd, args->cmd, args->arg);
+
+ fcntl_args.fd = args->fd;
+ fcntl_args.arg = 0;
+
+ switch (args->cmd) {
+ case IBCS2_F_DUPFD:
+ fcntl_args.cmd = F_DUPFD;
+ return fcntl(p, &fcntl_args, retval);
+
+ case IBCS2_F_GETFD:
+ fcntl_args.cmd = F_GETFD;
+ return fcntl(p, &fcntl_args, retval);
+
+ case IBCS2_F_SETFD:
+ fcntl_args.cmd = F_SETFD;
+ return fcntl(p, &fcntl_args, retval);
+
+ case IBCS2_F_GETFL:
+ fcntl_args.cmd = F_GETFL;
+ error = fcntl(p, &fcntl_args, &result);
+ *retval = 0;
+ if (result & O_RDONLY) *retval |= IBCS2_RDONLY;
+ if (result & O_WRONLY) *retval |= IBCS2_WRONLY;
+ if (result & O_RDWR) *retval |= IBCS2_RDWR;
+ if (result & O_NDELAY) *retval |= IBCS2_NONBLOCK;
+ if (result & O_APPEND) *retval |= IBCS2_APPEND;
+ if (result & O_FSYNC) *retval |= IBCS2_SYNC;
+ return error;
+
+ case IBCS2_F_SETFL:
+ if (args->arg & IBCS2_NDELAY) fcntl_args.arg |= O_NONBLOCK;
+ if (args->arg & IBCS2_APPEND) fcntl_args.arg |= O_APPEND;
+ if (args->arg & IBCS2_SYNC) fcntl_args.arg |= O_FSYNC;
+ fcntl_args.cmd = F_SETFL;
+ return fcntl(p, &fcntl_args, retval);
+
+ case IBCS2_F_GETLK:
+ if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
+ sizeof(struct ibcs2_flock))))
+ return error;
+ ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
+ fcntl_args.cmd = F_GETLK;
+ fcntl_args.arg = (int)bsd_flock;
+ if (error = fcntl(p, &fcntl_args, retval))
+ return error;
+ bsd_to_ibcs2_flock(bsd_flock, &ibcs2_flock);
+ return copyout((caddr_t)&ibcs2_flock, (caddr_t)args->arg,
+ sizeof(struct ibcs2_flock));
+
+ case IBCS2_F_SETLK:
+ if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
+ sizeof(struct ibcs2_flock))))
+ return error;
+ ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
+ fcntl_args.cmd = F_SETLK;
+ fcntl_args.arg = (int)bsd_flock;
+ return fcntl(p, &fcntl_args, retval);
+
+ case IBCS2_F_SETLKW:
+ if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
+ sizeof(struct ibcs2_flock))))
+ return error;
+ ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
+ fcntl_args.cmd = F_SETLKW;
+ fcntl_args.arg = (int)bsd_flock;
+ return fcntl(p, &fcntl_args, retval);
+ }
+ return EINVAL;
+}
+
+struct ibcs2_dirent {
+ ibcs2_ino_t d_ino;
+ ibcs2_off_t d_off;
+ unsigned short d_reclen;
+ char d_name[256];
+};
+
+struct ibcs2_getdents_args {
+ int fd;
+ char *buf;
+ int nbytes;
+};
+
+#define BSD_DIRENT(cp) ((struct direct *)(cp))
+#define IBCS2_RECLEN(p) \
+ (((2*sizeof(long)+sizeof(short)+BSD_DIRENT(p)->d_namlen+1)+3)&~3)
+
+int
+ibcs2_getdents(struct proc *p, struct ibcs2_getdents_args *args, int *retval)
+{
+ struct vnode *vp;
+ struct ibcs2_dirent dir;
+ struct file *fp;
+ struct uio auio;
+ struct iovec aiov;
+ off_t off;
+ caddr_t inp, buf, outp;
+ int len, reclen, resid;
+ int buflen, error, eofflag;
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'getdents' fd = %d, size = %d\n",
+ args->fd, args->nbytes);
+ if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
+ return error;
+ if ((fp->f_flag & FREAD) == 0)
+ return EBADF;
+ vp = (struct vnode *)fp->f_data;
+ if (vp->v_type != VDIR)
+ return EINVAL;
+ buflen = min(MAXBSIZE, max(DIRBLKSIZ, args->nbytes));
+ buf = malloc(buflen, M_TEMP, M_WAITOK);
+ VOP_LOCK(vp);
+ off = fp->f_offset;
+again:
+ aiov.iov_base = buf;
+ aiov.iov_len = buflen;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_procp = p;
+ auio.uio_resid = buflen;
+ auio.uio_offset = off & ~(DIRBLKSIZ-1);
+ if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag))
+ goto out;
+ inp = buf + (off & (DIRBLKSIZ-1));
+ buflen -= off & (DIRBLKSIZ-1);
+ outp = args->buf;
+ resid = args->nbytes;
+ if ((len = buflen - auio.uio_resid) <= 0)
+ goto eof;
+ for (; len > 0 && resid > 0; len -= reclen) {
+ reclen = BSD_DIRENT(inp)->d_reclen;
+ if (reclen & 3)
+ panic("ibcs2_getdents");
+ if (BSD_DIRENT(inp)->d_ino == 0) {
+ off += reclen;
+ inp += reclen;
+ continue;
+ }
+ if (IBCS2_RECLEN(inp) > len || resid < IBCS2_RECLEN(inp)) {
+ outp++;
+ break;
+ }
+ bzero(&dir, sizeof(struct ibcs2_dirent));
+ dir.d_ino = BSD_DIRENT(inp)->d_ino;
+ dir.d_off = (ibcs2_off_t)off;
+ dir.d_reclen = IBCS2_RECLEN(inp);
+ bcopy(BSD_DIRENT(inp)->d_name, &dir.d_name,
+ BSD_DIRENT(inp)->d_namlen);
+ if (error = copyout(&dir, outp, dir.d_reclen))
+ goto out;
+ outp += IBCS2_RECLEN(inp);
+ resid -= IBCS2_RECLEN(inp);
+ off += reclen;
+ inp += reclen;
+ }
+ if (outp == args->buf)
+ goto again;
+ fp->f_offset = off;
+eof:
+ *retval = args->nbytes - resid;
+out:
+ VOP_UNLOCK(vp);
+ free(buf, M_TEMP);
+ return error;
+}
+
+struct ibcs2_open_args {
+ char *fname;
+ int fmode;
+ int crtmode;
+};
+
+int
+ibcs2_open(struct proc *p, struct ibcs2_open_args *args, int *retval)
+{
+ int bsd_mode = 0;
+ int noctty = args->fmode & 0x8000;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'open' name=%s, flags=%x, mode=%x\n",
+ args->fname, args->fmode, args->crtmode);
+ if (args->fmode & IBCS2_RDONLY) bsd_mode |= O_RDONLY;
+ if (args->fmode & IBCS2_WRONLY) bsd_mode |= O_WRONLY;
+ if (args->fmode & IBCS2_RDWR) bsd_mode |= O_RDWR;
+ if (args->fmode & IBCS2_NDELAY) bsd_mode |= O_NONBLOCK;
+ if (args->fmode & IBCS2_APPEND) bsd_mode |= O_APPEND;
+ if (args->fmode & IBCS2_SYNC) bsd_mode |= O_FSYNC;
+ if (args->fmode & IBCS2_NONBLOCK) bsd_mode |= O_NONBLOCK;
+ if (args->fmode & IBCS2_PRIV) bsd_mode |= O_EXLOCK;
+ if (args->fmode & IBCS2_CREAT) bsd_mode |= O_CREAT;
+ if (args->fmode & IBCS2_TRUNC) bsd_mode |= O_TRUNC | O_CREAT;
+ if (args->fmode & IBCS2_EXCL) bsd_mode |= O_EXCL;
+ if (args->fmode & IBCS2_NOCTTY) bsd_mode |= O_NOCTTY;
+ args->fmode = bsd_mode;
+ error = open(p, args, retval);
+ if (!error && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
+ struct filedesc *fdp = p->p_fd;
+ struct file *fp = fdp->fd_ofiles[*retval];
+
+ if (fp->f_type == DTYPE_VNODE)
+ (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
+ }
+ return error;
+}
+
+struct ibcs2_read_args {
+ int fd;
+ char *buffer;
+ unsigned int count;
+};
+
+int
+ibcs2_read(struct proc *p, struct ibcs2_read_args *args, int *retval)
+{
+ struct ibcs2_dir {
+ ibcs2_ino_t inode;
+ char fname[14];
+ } dirbuf;
+ struct vnode *vp;
+ struct file *fp;
+ struct uio auio;
+ struct iovec aiov;
+ caddr_t inp, buf, outp;
+ off_t off;
+ int buflen, error, eofflag;
+ int len, reclen, resid;
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'read' fd=%d, count=%d\n",
+ args->fd, args->count);
+
+ if (error = getvnode(p->p_fd, args->fd, &fp))
+ if (error == EINVAL)
+ return read(p, args, retval);
+ else
+ return error;
+ if ((fp->f_flag & FREAD) == 0)
+ return EBADF;
+ vp = (struct vnode *)fp->f_data;
+ if (vp->v_type != VDIR) {
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("normal read\n");
+ return read(p, args, retval);
+ }
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("read directory\n");
+ buflen = max(MAXBSIZE, args->count);
+ buf = malloc(buflen, M_TEMP, M_WAITOK);
+ VOP_LOCK(vp);
+ off = fp->f_offset;
+again:
+ aiov.iov_base = buf;
+ aiov.iov_len = buflen;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_procp = p;
+ auio.uio_resid = buflen;
+ auio.uio_offset = off & ~(DIRBLKSIZ-1);
+ if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag))
+ goto out;
+ inp = buf + (off & (DIRBLKSIZ-1));
+ buflen -= off & (DIRBLKSIZ-1);
+ outp = args->buffer;
+ resid = args->count;
+ if ((len = buflen - auio.uio_resid) == 0)
+ goto eof;
+ for (; len > 0 && resid > 0; len -= reclen) {
+ reclen = BSD_DIRENT(inp)->d_reclen;
+ if (reclen & 3)
+ panic("ibcs2_read");
+ if (BSD_DIRENT(inp)->d_ino == 0) {
+ inp += reclen;
+ off += reclen;
+ continue;
+ }
+ if (reclen > len || resid < sizeof(struct ibcs2_dir)) {
+ outp++;
+ break;
+ }
+ /*
+ * TODO: break up name if > 14 chars
+ * put 14 chars in each dir entry wtih d_ino = 0xffff
+ * and set the last dir entry's d_ino = inode
+ */
+ dirbuf.inode = (BSD_DIRENT(inp)->d_ino > 0x0000fffe) ?
+ 0xfffe : BSD_DIRENT(inp)->d_ino;
+ bcopy(BSD_DIRENT(inp)->d_name, &dirbuf.fname, 14); /* XXX */
+ if (error = copyout(&dirbuf, outp, sizeof(dirbuf)))
+ goto out;
+ off += reclen;
+ inp += reclen;
+ outp += sizeof(struct ibcs2_dir);
+ resid -= sizeof(struct ibcs2_dir);
+ }
+ if (outp == args->buffer)
+ goto again;
+ fp->f_offset = off;
+eof:
+ *retval = args->count - resid;
+out:
+ VOP_UNLOCK(vp);
+ free(buf, M_TEMP);
+ return error;
+}
+
+struct ibcs2_seek_args {
+ int fdes;
+ ibcs2_off_t off;
+ int whence;
+};
+
+int
+ibcs2_seek(struct proc *p, struct ibcs2_seek_args *args, int *retval)
+{
+
+ struct seek_args {
+ int fdes;
+ int pad;
+ off_t off;
+ int whence;
+ } tmp_args;
+ off_t tmp_retval;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'seek' fd=%d, offset=%d, how=%d\n",
+ args->fdes, args->off, args->whence);
+ tmp_args.fdes = args->fdes;
+ tmp_args.off = (off_t)args->off;
+ tmp_args.whence = args->whence;
+ error = lseek(p, &tmp_args, &tmp_retval);
+ *retval = (int)tmp_retval;
+ return error;
+}
+
+struct ibcs2_write_args {
+ int fd;
+ char *buffer;
+ unsigned int count;
+};
+
+int
+ibcs2_write(struct proc *p, struct ibcs2_write_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_FILE)
+ printf("IBCS2: 'write' fd=%d, count=%d\n",
+ args->fd, args->count);
+ return write(p, args, retval);
+}
diff --git a/sys/i386/ibcs2/ibcs2_ioctl.c b/sys/i386/ibcs2/ibcs2_ioctl.c
new file mode 100644
index 000000000000..ecb9725756ac
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_ioctl.c
@@ -0,0 +1,913 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * 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: ibcs2_ioctl.c,v 1.13 1994/10/12 20:28:06 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/ioctl_compat.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/tty.h>
+#include <sys/termios.h>
+#include <machine/console.h>
+
+struct ibcs2_termio {
+ unsigned short c_iflag;
+ unsigned short c_oflag;
+ unsigned short c_cflag;
+ unsigned short c_lflag;
+ char c_line;
+ unsigned char c_cc[IBCS2_NCC];
+};
+
+struct ibcs2_termios {
+ unsigned short c_iflag;
+ unsigned short c_oflag;
+ unsigned short c_cflag;
+ unsigned short c_lflag;
+ char c_line;
+ unsigned char c_cc[IBCS2_NCCS];
+ char c_ispeed;
+ char c_ospeed;
+};
+
+struct ibcs2_winsize {
+ char bytex, bytey;
+ short bitx, bity;
+};
+
+static struct speedtab sptab[] = {
+ { 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
+ { 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
+ { 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
+ { 2400, 11 }, { 4800, 12 }, { 9600, 13 },
+ { 19200, 14 }, { 38400, 15 },
+ { 57600, 15 }, { 115200, 15 }, {-1, -1 }
+};
+
+static int
+ibcs2_to_bsd_speed(int code, struct speedtab *table)
+{
+ for ( ; table->sp_code != -1; table++)
+ if (table->sp_code == code)
+ return (table->sp_speed);
+ return -1;
+}
+
+static int
+bsd_to_ibcs2_speed(int speed, struct speedtab *table)
+{
+ for ( ; table->sp_speed != -1; table++)
+ if (table->sp_speed == speed)
+ return (table->sp_code);
+ return -1;
+}
+
+static void
+bsd_termios_to_ibcs2_termio(struct termios *bsd_termios,
+ struct ibcs2_termio *ibcs2_termio)
+{
+ int speed;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: BSD termios structure (input):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
+ bsd_termios->c_iflag, bsd_termios->c_oflag,
+ bsd_termios->c_cflag, bsd_termios->c_lflag,
+ bsd_termios->c_ispeed, bsd_termios->c_ospeed);
+ printf("c_cc ");
+ for (i=0; i<NCCS; i++)
+ printf("%02x ", bsd_termios->c_cc[i]);
+ printf("\n");
+ }
+
+ ibcs2_termio->c_iflag = bsd_termios->c_iflag &
+ (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK
+ |ISTRIP|INLCR|IGNCR|ICRNL|IXANY);
+ if (bsd_termios->c_iflag & IXON)
+ ibcs2_termio->c_iflag |= IBCS2_IXON;
+ if (bsd_termios->c_iflag & IXOFF)
+ ibcs2_termio->c_iflag |= IBCS2_IXOFF;
+
+ ibcs2_termio->c_oflag = 0;
+ if (bsd_termios->c_oflag & OPOST)
+ ibcs2_termio->c_oflag |= IBCS2_OPOST;
+ if (bsd_termios->c_oflag & ONLCR)
+ ibcs2_termio->c_oflag |= IBCS2_ONLCR;
+ if (bsd_termios->c_oflag & OXTABS)
+ ibcs2_termio->c_oflag |= (IBCS2_TAB1|IBCS2_TAB2);
+
+ speed = bsd_to_ibcs2_speed(bsd_termios->c_ospeed, sptab);
+
+ ibcs2_termio->c_cflag = speed >= 0 ? speed : 0;
+ ibcs2_termio->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; /* XXX */
+ if (bsd_termios->c_cflag & CSTOPB)
+ ibcs2_termio->c_cflag |= IBCS2_CSTOPB;
+ if (bsd_termios->c_cflag & PARENB)
+ ibcs2_termio->c_cflag |= IBCS2_PARENB;
+ if (bsd_termios->c_cflag & PARODD)
+ ibcs2_termio->c_cflag |= IBCS2_PARODD;
+ if (bsd_termios->c_cflag & HUPCL)
+ ibcs2_termio->c_cflag |= IBCS2_HUPCL;
+ if (bsd_termios->c_cflag & CLOCAL)
+ ibcs2_termio->c_cflag |= IBCS2_CLOCAL;
+
+ ibcs2_termio->c_lflag = 0;
+ if (bsd_termios->c_lflag & ISIG)
+ ibcs2_termio->c_lflag |= IBCS2_ISIG;
+ if (bsd_termios->c_lflag & ICANON)
+ ibcs2_termio->c_lflag |= IBCS2_ICANON;
+ if (bsd_termios->c_lflag & ECHO)
+ ibcs2_termio->c_lflag |= IBCS2_ECHO;
+ if (bsd_termios->c_lflag & ECHOE)
+ ibcs2_termio->c_lflag |= IBCS2_ECHOE;
+ if (bsd_termios->c_lflag & ECHOK)
+ ibcs2_termio->c_lflag |= IBCS2_ECHOK;
+ if (bsd_termios->c_lflag & ECHONL)
+ ibcs2_termio->c_lflag |= IBCS2_ECHONL;
+ if (bsd_termios->c_lflag & NOFLSH)
+ ibcs2_termio->c_lflag |= IBCS2_NOFLSH;
+ if (bsd_termios->c_lflag & ECHOCTL)
+ ibcs2_termio->c_lflag |= 0x0200; /* XXX */
+ if (bsd_termios->c_lflag & ECHOPRT)
+ ibcs2_termio->c_lflag |= 0x0400; /* XXX */
+ if (bsd_termios->c_lflag & ECHOKE)
+ ibcs2_termio->c_lflag |= 0x0800; /* XXX */
+ if (bsd_termios->c_lflag & IEXTEN)
+ ibcs2_termio->c_lflag |= 0x8000; /* XXX */
+
+ ibcs2_termio->c_cc[IBCS2_VINTR] = bsd_termios->c_cc[VINTR];
+ ibcs2_termio->c_cc[IBCS2_VQUIT] = bsd_termios->c_cc[VQUIT];
+ ibcs2_termio->c_cc[IBCS2_VERASE] = bsd_termios->c_cc[VERASE];
+ ibcs2_termio->c_cc[IBCS2_VKILL] = bsd_termios->c_cc[VKILL];
+ if (bsd_termios->c_lflag & ICANON) {
+ ibcs2_termio->c_cc[IBCS2_VEOF] = bsd_termios->c_cc[VEOF];
+ ibcs2_termio->c_cc[IBCS2_VEOL] = bsd_termios->c_cc[VEOL];
+ } else {
+ ibcs2_termio->c_cc[IBCS2_VMIN] = bsd_termios->c_cc[VMIN];
+ ibcs2_termio->c_cc[IBCS2_VTIME] = bsd_termios->c_cc[VTIME];
+ }
+ ibcs2_termio->c_cc[IBCS2_VEOL2] = bsd_termios->c_cc[VEOL2];
+ ibcs2_termio->c_cc[IBCS2_VSWTCH] = 0xff;
+ ibcs2_termio->c_line = 0;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: IBCS2 termio structure (output):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x speed=%d line=%d\n",
+ ibcs2_termio->c_iflag, ibcs2_termio->c_oflag,
+ ibcs2_termio->c_cflag, ibcs2_termio->c_lflag,
+ ibcs2_to_bsd_speed(
+ ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab),
+ ibcs2_termio->c_line);
+ printf("c_cc ");
+ for (i=0; i<IBCS2_NCC; i++)
+ printf("%02x ", ibcs2_termio->c_cc[i]);
+ printf("\n");
+ }
+}
+
+static void
+ibcs2_termio_to_bsd_termios(struct ibcs2_termio *ibcs2_termio,
+ struct termios *bsd_termios)
+{
+ int i, speed;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: IBCS2 termio structure (input):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x speed=%d line=%d\n",
+ ibcs2_termio->c_iflag, ibcs2_termio->c_oflag,
+ ibcs2_termio->c_cflag, ibcs2_termio->c_lflag,
+ ibcs2_to_bsd_speed(
+ ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab),
+ ibcs2_termio->c_line);
+ printf("c_cc ");
+ for (i=0; i<IBCS2_NCC; i++)
+ printf("%02x ", ibcs2_termio->c_cc[i]);
+ printf("\n");
+ }
+
+ bsd_termios->c_iflag = ibcs2_termio->c_iflag &
+ (IBCS2_IGNBRK|IBCS2_BRKINT|IBCS2_IGNPAR|IBCS2_PARMRK|IBCS2_INPCK
+ |IBCS2_ISTRIP|IBCS2_INLCR|IBCS2_IGNCR|IBCS2_ICRNL|IBCS2_IXANY);
+ if (ibcs2_termio->c_iflag & IBCS2_IXON)
+ bsd_termios->c_iflag |= IXON;
+ if (ibcs2_termio->c_iflag & IBCS2_IXOFF)
+ bsd_termios->c_iflag |= IXOFF;
+
+ bsd_termios->c_oflag = 0;
+ if (ibcs2_termio->c_oflag & IBCS2_OPOST)
+ bsd_termios->c_oflag |= OPOST;
+ if (ibcs2_termio->c_oflag & IBCS2_ONLCR)
+ bsd_termios->c_oflag |= ONLCR;
+ if (ibcs2_termio->c_oflag & (IBCS2_TAB1|IBCS2_TAB2))
+ bsd_termios->c_oflag |= OXTABS;
+
+ speed = ibcs2_to_bsd_speed(ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab);
+ bsd_termios->c_ospeed = bsd_termios->c_ispeed = speed >= 0 ? speed : 0;
+
+ bsd_termios->c_cflag = (ibcs2_termio->c_cflag & IBCS2_CSIZE) << 4;
+ if (ibcs2_termio->c_cflag & IBCS2_CSTOPB)
+ bsd_termios->c_cflag |= CSTOPB;
+ if (ibcs2_termio->c_cflag & IBCS2_PARENB)
+ bsd_termios->c_cflag |= PARENB;
+ if (ibcs2_termio->c_cflag & IBCS2_PARODD)
+ bsd_termios->c_cflag |= PARODD;
+ if (ibcs2_termio->c_cflag & IBCS2_HUPCL)
+ bsd_termios->c_cflag |= HUPCL;
+ if (ibcs2_termio->c_cflag & IBCS2_CLOCAL)
+ bsd_termios->c_cflag |= CLOCAL;
+
+ bsd_termios->c_lflag = 0;
+ if (ibcs2_termio->c_lflag & IBCS2_ISIG)
+ bsd_termios->c_lflag |= ISIG;
+ if (ibcs2_termio->c_lflag & IBCS2_ICANON)
+ bsd_termios->c_lflag |= ICANON;
+ if (ibcs2_termio->c_lflag & IBCS2_ECHO)
+ bsd_termios->c_lflag |= ECHO;
+ if (ibcs2_termio->c_lflag & IBCS2_ECHOE)
+ bsd_termios->c_lflag |= ECHOE;
+ if (ibcs2_termio->c_lflag & IBCS2_ECHOK)
+ bsd_termios->c_lflag |= ECHOK;
+ if (ibcs2_termio->c_lflag & IBCS2_ECHONL)
+ bsd_termios->c_lflag |= ECHONL;
+ if (ibcs2_termio->c_lflag & IBCS2_NOFLSH)
+ bsd_termios->c_lflag |= NOFLSH;
+ if (ibcs2_termio->c_lflag & 0x0200) /* XXX */
+ bsd_termios->c_lflag |= ECHOCTL;
+ if (ibcs2_termio->c_lflag & 0x0400) /* XXX */
+ bsd_termios->c_lflag |= ECHOPRT;
+ if (ibcs2_termio->c_lflag & 0x0800) /* XXX */
+ bsd_termios->c_lflag |= ECHOKE;
+ if (ibcs2_termio->c_lflag & 0x8000) /* XXX */
+ bsd_termios->c_lflag |= IEXTEN;
+
+ for (i=0; i<NCCS; bsd_termios->c_cc[i++] = 0) ;
+ bsd_termios->c_cc[VINTR] = ibcs2_termio->c_cc[IBCS2_VINTR];
+ bsd_termios->c_cc[VQUIT] = ibcs2_termio->c_cc[IBCS2_VQUIT];
+ bsd_termios->c_cc[VERASE] = ibcs2_termio->c_cc[IBCS2_VERASE];
+ bsd_termios->c_cc[VKILL] = ibcs2_termio->c_cc[IBCS2_VKILL];
+ if (ibcs2_termio->c_lflag & IBCS2_ICANON) {
+ bsd_termios->c_cc[VEOF] = ibcs2_termio->c_cc[IBCS2_VEOF];
+ bsd_termios->c_cc[VEOL] = ibcs2_termio->c_cc[IBCS2_VEOL];
+ } else {
+ bsd_termios->c_cc[VMIN] = ibcs2_termio->c_cc[IBCS2_VMIN];
+ bsd_termios->c_cc[VTIME] = ibcs2_termio->c_cc[IBCS2_VTIME];
+ }
+ bsd_termios->c_cc[VEOL2] = ibcs2_termio->c_cc[IBCS2_VEOL2];
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: BSD termios structure (output):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
+ bsd_termios->c_iflag, bsd_termios->c_oflag,
+ bsd_termios->c_cflag, bsd_termios->c_lflag,
+ bsd_termios->c_ispeed, bsd_termios->c_ospeed);
+ printf("c_cc ");
+ for (i=0; i<NCCS; i++)
+ printf("%02x ", bsd_termios->c_cc[i]);
+ printf("\n");
+ }
+}
+
+static void
+bsd_to_ibcs2_termios(struct termios *bsd_termios,
+ struct ibcs2_termios *ibcs2_termios)
+{
+ int speed;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: BSD termios structure (input):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
+ bsd_termios->c_iflag, bsd_termios->c_oflag,
+ bsd_termios->c_cflag, bsd_termios->c_lflag,
+ bsd_termios->c_ispeed, bsd_termios->c_ospeed);
+ printf("c_cc ");
+ for (i=0; i<NCCS; i++)
+ printf("%02x ", bsd_termios->c_cc[i]);
+ printf("\n");
+ }
+
+ ibcs2_termios->c_iflag = bsd_termios->c_iflag &
+ (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK
+ |ISTRIP|INLCR|IGNCR|ICRNL|IXANY);
+ if (bsd_termios->c_iflag & IXON)
+ ibcs2_termios->c_iflag |= IBCS2_IXON;
+ if (bsd_termios->c_iflag & IXOFF)
+ ibcs2_termios->c_iflag |= IBCS2_IXOFF;
+
+ ibcs2_termios->c_oflag = 0;
+ if (bsd_termios->c_oflag & OPOST)
+ ibcs2_termios->c_oflag |= IBCS2_OPOST;
+ if (bsd_termios->c_oflag & ONLCR)
+ ibcs2_termios->c_oflag |= IBCS2_ONLCR;
+ if (bsd_termios->c_oflag & OXTABS)
+ ibcs2_termios->c_oflag |= (IBCS2_TAB1|IBCS2_TAB2);
+
+ ibcs2_termios->c_cflag = (bsd_termios->c_cflag & CSIZE) >> 4; /* XXX */
+ if (bsd_termios->c_cflag & CSTOPB)
+ ibcs2_termios->c_cflag |= IBCS2_CSTOPB;
+ if (bsd_termios->c_cflag & PARENB)
+ ibcs2_termios->c_cflag |= IBCS2_PARENB;
+ if (bsd_termios->c_cflag & PARODD)
+ ibcs2_termios->c_cflag |= IBCS2_PARODD;
+ if (bsd_termios->c_cflag & HUPCL)
+ ibcs2_termios->c_cflag |= IBCS2_HUPCL;
+ if (bsd_termios->c_cflag & CLOCAL)
+ ibcs2_termios->c_cflag |= IBCS2_CLOCAL;
+ if (bsd_termios->c_cflag & CRTSCTS)
+ ibcs2_termios->c_cflag |= 0x8000; /* XXX */
+
+ ibcs2_termios->c_lflag = 0;
+ if (bsd_termios->c_lflag & ISIG)
+ ibcs2_termios->c_lflag |= IBCS2_ISIG;
+ if (bsd_termios->c_lflag & ICANON)
+ ibcs2_termios->c_lflag |= IBCS2_ICANON;
+ if (bsd_termios->c_lflag & ECHO)
+ ibcs2_termios->c_lflag |= IBCS2_ECHO;
+ if (bsd_termios->c_lflag & ECHOE)
+ ibcs2_termios->c_lflag |= IBCS2_ECHOE;
+ if (bsd_termios->c_lflag & ECHOK)
+ ibcs2_termios->c_lflag |= IBCS2_ECHOK;
+ if (bsd_termios->c_lflag & ECHONL)
+ ibcs2_termios->c_lflag |= IBCS2_ECHONL;
+ if (bsd_termios->c_lflag & NOFLSH)
+ ibcs2_termios->c_lflag |= IBCS2_NOFLSH;
+ if (bsd_termios->c_lflag & ECHOCTL)
+ ibcs2_termios->c_lflag |= 0x0200; /* XXX */
+ if (bsd_termios->c_lflag & ECHOPRT)
+ ibcs2_termios->c_lflag |= 0x0400; /* XXX */
+ if (bsd_termios->c_lflag & ECHOKE)
+ ibcs2_termios->c_lflag |= 0x0800; /* XXX */
+ if (bsd_termios->c_lflag & IEXTEN)
+ ibcs2_termios->c_lflag |= 0x8000; /* XXX */
+
+ ibcs2_termios->c_cc[IBCS2_VINTR] = bsd_termios->c_cc[VINTR];
+ ibcs2_termios->c_cc[IBCS2_VQUIT] = bsd_termios->c_cc[VQUIT];
+ ibcs2_termios->c_cc[IBCS2_VERASE] = bsd_termios->c_cc[VERASE];
+ ibcs2_termios->c_cc[IBCS2_VKILL] = bsd_termios->c_cc[VKILL];
+ if (bsd_termios->c_lflag & ICANON) {
+ ibcs2_termios->c_cc[IBCS2_VEOF] = bsd_termios->c_cc[VEOF];
+ ibcs2_termios->c_cc[IBCS2_VEOL] = bsd_termios->c_cc[VEOL];
+ } else {
+ ibcs2_termios->c_cc[IBCS2_VMIN] = bsd_termios->c_cc[VMIN];
+ ibcs2_termios->c_cc[IBCS2_VTIME] = bsd_termios->c_cc[VTIME];
+ }
+ ibcs2_termios->c_cc[IBCS2_VEOL2] = bsd_termios->c_cc[VEOL2];
+ ibcs2_termios->c_cc[IBCS2_VSWTCH] = 0xff;
+ ibcs2_termios->c_cc[IBCS2_VSUSP] = bsd_termios->c_cc[VSUSP];
+ ibcs2_termios->c_cc[IBCS2_VSTART] = bsd_termios->c_cc[VSTART];
+ ibcs2_termios->c_cc[IBCS2_VSTOP] = bsd_termios->c_cc[VSTOP];
+
+ ibcs2_termios->c_ispeed =
+ bsd_to_ibcs2_speed(bsd_termios->c_ispeed, sptab);
+ ibcs2_termios->c_ospeed =
+ bsd_to_ibcs2_speed(bsd_termios->c_ospeed, sptab);
+ ibcs2_termios->c_line = 0;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: IBCS2 termios structure (output):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d "
+ "line=%d\n",
+ ibcs2_termios->c_iflag, ibcs2_termios->c_oflag,
+ ibcs2_termios->c_cflag, ibcs2_termios->c_lflag,
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab),
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab),
+ ibcs2_termios->c_line);
+ printf("c_cc ");
+ for (i=0; i<IBCS2_NCCS; i++)
+ printf("%02x ", ibcs2_termios->c_cc[i]);
+ printf("\n");
+ }
+}
+
+static void
+ibcs2_to_bsd_termios(struct ibcs2_termios *ibcs2_termios,
+ struct termios *bsd_termios)
+{
+ int i, speed;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: IBCS2 termios structure (input):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d "
+ "line=%d\n",
+ ibcs2_termios->c_iflag, ibcs2_termios->c_oflag,
+ ibcs2_termios->c_cflag, ibcs2_termios->c_lflag,
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab),
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab),
+ ibcs2_termios->c_line);
+ printf("c_cc ");
+ for (i=0; i<IBCS2_NCCS; i++)
+ printf("%02x ", ibcs2_termios->c_cc[i]);
+ printf("\n");
+ }
+
+ bsd_termios->c_iflag = ibcs2_termios->c_iflag &
+ (IBCS2_IGNBRK|IBCS2_BRKINT|IBCS2_IGNPAR|IBCS2_PARMRK|IBCS2_INPCK
+ |IBCS2_ISTRIP|IBCS2_INLCR|IBCS2_IGNCR|IBCS2_ICRNL|IBCS2_IXANY);
+ if (ibcs2_termios->c_iflag & IBCS2_IXON)
+ bsd_termios->c_iflag |= IXON;
+ if (ibcs2_termios->c_iflag & IBCS2_IXOFF)
+ bsd_termios->c_iflag |= IXOFF;
+
+ bsd_termios->c_oflag = 0;
+ if (ibcs2_termios->c_oflag & IBCS2_OPOST)
+ bsd_termios->c_oflag |= OPOST;
+ if (ibcs2_termios->c_oflag & IBCS2_ONLCR)
+ bsd_termios->c_oflag |= ONLCR;
+ if (ibcs2_termios->c_oflag & (IBCS2_TAB1|IBCS2_TAB2))
+ bsd_termios->c_oflag |= OXTABS;
+
+ bsd_termios->c_cflag = (ibcs2_termios->c_cflag & IBCS2_CSIZE) << 4;
+ if (ibcs2_termios->c_cflag & IBCS2_CSTOPB)
+ bsd_termios->c_cflag |= CSTOPB;
+ if (ibcs2_termios->c_cflag & IBCS2_PARENB)
+ bsd_termios->c_cflag |= PARENB;
+ if (ibcs2_termios->c_cflag & IBCS2_PARODD)
+ bsd_termios->c_cflag |= PARODD;
+ if (ibcs2_termios->c_cflag & IBCS2_HUPCL)
+ bsd_termios->c_cflag |= HUPCL;
+ if (ibcs2_termios->c_cflag & IBCS2_CLOCAL)
+ bsd_termios->c_cflag |= CLOCAL;
+ if (ibcs2_termios->c_cflag & 0x8000)
+ bsd_termios->c_cflag |= CRTSCTS; /* XXX */
+
+ bsd_termios->c_lflag = 0;
+ if (ibcs2_termios->c_lflag & IBCS2_ISIG)
+ bsd_termios->c_lflag |= ISIG;
+ if (ibcs2_termios->c_lflag & IBCS2_ICANON)
+ bsd_termios->c_lflag |= ICANON;
+ if (ibcs2_termios->c_lflag & IBCS2_ECHO)
+ bsd_termios->c_lflag |= ECHO;
+ if (ibcs2_termios->c_lflag & IBCS2_ECHOE)
+ bsd_termios->c_lflag |= ECHOE;
+ if (ibcs2_termios->c_lflag & IBCS2_ECHOK)
+ bsd_termios->c_lflag |= ECHOK;
+ if (ibcs2_termios->c_lflag & IBCS2_ECHONL)
+ bsd_termios->c_lflag |= ECHONL;
+ if (ibcs2_termios->c_lflag & IBCS2_NOFLSH)
+ bsd_termios->c_lflag |= NOFLSH;
+ if (ibcs2_termios->c_lflag & 0x0200) /* XXX */
+ bsd_termios->c_lflag |= ECHOCTL;
+ if (ibcs2_termios->c_lflag & 0x0400) /* XXX */
+ bsd_termios->c_lflag |= ECHOPRT;
+ if (ibcs2_termios->c_lflag & 0x0800) /* XXX */
+ bsd_termios->c_lflag |= ECHOKE;
+ if (ibcs2_termios->c_lflag & 0x8000) /* XXX */
+ bsd_termios->c_lflag |= IEXTEN;
+
+ for (i=0; i<NCCS; bsd_termios->c_cc[i++] = 0) ;
+ bsd_termios->c_cc[VINTR] = ibcs2_termios->c_cc[IBCS2_VINTR];
+ bsd_termios->c_cc[VQUIT] = ibcs2_termios->c_cc[IBCS2_VQUIT];
+ bsd_termios->c_cc[VERASE] = ibcs2_termios->c_cc[IBCS2_VERASE];
+ bsd_termios->c_cc[VKILL] = ibcs2_termios->c_cc[IBCS2_VKILL];
+ if (ibcs2_termios->c_lflag & IBCS2_ICANON) {
+ bsd_termios->c_cc[VEOF] = ibcs2_termios->c_cc[IBCS2_VEOF];
+ bsd_termios->c_cc[VEOL] = ibcs2_termios->c_cc[IBCS2_VEOL];
+ } else {
+ bsd_termios->c_cc[VMIN] = ibcs2_termios->c_cc[IBCS2_VMIN];
+ bsd_termios->c_cc[VTIME] = ibcs2_termios->c_cc[IBCS2_VTIME];
+ }
+ bsd_termios->c_cc[VEOL2] = ibcs2_termios->c_cc[IBCS2_VEOL2];
+ bsd_termios->c_cc[VSUSP] = ibcs2_termios->c_cc[IBCS2_VSUSP];
+ bsd_termios->c_cc[VSTART] = ibcs2_termios->c_cc[IBCS2_VSTART];
+ bsd_termios->c_cc[VSTOP] = ibcs2_termios->c_cc[IBCS2_VSTOP];
+
+ bsd_termios->c_ispeed =
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab);
+ bsd_termios->c_ospeed =
+ ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab);
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
+ int i;
+ printf("IBCS2: BSD termios structure (output):\n");
+ printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
+ bsd_termios->c_iflag, bsd_termios->c_oflag,
+ bsd_termios->c_cflag, bsd_termios->c_lflag,
+ bsd_termios->c_ispeed, bsd_termios->c_ospeed);
+ printf("c_cc ");
+ for (i=0; i<NCCS; i++)
+ printf("%02x ", bsd_termios->c_cc[i]);
+ printf("\n");
+ }
+}
+
+
+struct ibcs2_ioctl_args {
+ int fd;
+ int cmd;
+ int arg;
+};
+
+int
+ibcs2_ioctl(struct proc *p, struct ibcs2_ioctl_args *args, int *retval)
+{
+ struct termios bsd_termios;
+ struct winsize bsd_winsize;
+ struct ibcs2_termio ibcs2_termio;
+ struct ibcs2_termios ibcs2_termios;
+ struct ibcs2_winsize ibcs2_winsize;
+ struct filedesc *fdp = p->p_fd;
+ struct file *fp;
+ int (*func)();
+ int type = (args->cmd&0xffff00)>>8;
+ int num = args->cmd&0xff;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTL)
+ printf("IBCS2: 'ioctl' fd=%d, typ=%d(%c), num=%d\n",
+ args->fd, type, type, num);
+
+ if ((unsigned)args->fd >= fdp->fd_nfiles
+ || (fp = fdp->fd_ofiles[args->fd]) == 0)
+ return EBADF;
+
+ if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
+ return EBADF;
+ }
+
+ func = fp->f_ops->fo_ioctl;
+
+ switch (type) {
+ case 'f':
+ switch (num) {
+ case 1:
+ args->cmd = FIOCLEX;
+ return ioctl(p, args, retval);
+ case 2:
+ args->cmd = FIONCLEX;
+ return ioctl(p, args, retval);
+ case 3:
+ args->cmd = FIONREAD;
+ return ioctl(p, args, retval);
+ }
+ break;
+#if 0
+ case 'j':
+ switch (num) {
+ case 5: /* jerq winsize ?? */
+ ibcs2_winsize.bytex = 80;
+ /* p->p_session->s_ttyp->t_winsize.ws_col; XXX */
+ ibcs2_winsize.bytey = 25;
+ /* p->p_session->s_ttyp->t_winsize.ws_row; XXX */
+ ibcs2_winsize.bitx =
+ p->p_session->s_ttyp->t_winsize.ws_xpixel;
+ ibcs2_winsize.bity =
+ p->p_session->s_ttyp->t_winsize.ws_ypixel;
+ return copyout((caddr_t)&ibcs2_winsize,
+ (caddr_t)args->arg,
+ sizeof(ibcs2_winsize));
+ }
+#endif
+ case 't':
+ switch (num) {
+ case 0:
+ args->cmd = TIOCGETD;
+ return ioctl(p, args, retval);
+ case 1:
+ args->cmd = TIOCSETD;
+ return ioctl(p, args, retval);
+ case 2:
+ args->cmd = TIOCHPCL;
+ return ioctl(p, args, retval);
+ case 8:
+ args->cmd = TIOCGETP;
+ return ioctl(p, args, retval);
+ case 9:
+ args->cmd = TIOCSETP;
+ return ioctl(p, args, retval);
+ case 10:
+ args->cmd = TIOCSETN;
+ return ioctl(p, args, retval);
+ case 13:
+ args->cmd = TIOCEXCL;
+ return ioctl(p, args, retval);
+ case 14:
+ args->cmd = TIOCNXCL;
+ return ioctl(p, args, retval);
+ case 16:
+ args->cmd = TIOCFLUSH;
+ return ioctl(p, args, retval);
+ case 17:
+ args->cmd = TIOCSETC;
+ return ioctl(p, args, retval);
+ case 18:
+ args->cmd = TIOCGETC;
+ return ioctl(p, args, retval);
+ }
+ break;
+
+ case 'T':
+ switch (num) {
+ case 1: /* TCGETA */
+ if ((error = (*func)(fp, TIOCGETA,
+ (caddr_t)&bsd_termios, p)) != 0)
+ return error;
+ bsd_termios_to_ibcs2_termio(&bsd_termios,&ibcs2_termio);
+ return copyout((caddr_t)&ibcs2_termio,
+ (caddr_t)args->arg,
+ sizeof(ibcs2_termio));
+
+ case 2: /* TCSETA */
+ ibcs2_termio_to_bsd_termios(
+ (struct ibcs2_termio *)args->arg, &bsd_termios);
+ return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
+
+ case 3: /* TCSETAW */
+ ibcs2_termio_to_bsd_termios(
+ (struct ibcs2_termio *)args->arg, &bsd_termios);
+ return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
+
+ case 4: /* TCSETAF */
+ ibcs2_termio_to_bsd_termios(
+ (struct ibcs2_termio *)args->arg, &bsd_termios);
+ return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
+
+ case 5: /* TCSBRK */
+ args->cmd = TIOCDRAIN;
+ if (error = ioctl(p, args, retval))
+ return error;
+ args->cmd = TIOCSBRK;
+ ioctl(p, args, retval);
+ args->cmd = TIOCCBRK;
+ error = ioctl(p, args, retval);
+ return error;
+
+ case 6: /* TCONC */
+ if (args->arg == 0) args->cmd = TIOCSTOP;
+ else args->cmd = TIOCSTART;
+ return ioctl(p, args, retval);
+
+ case 7: /* TCFLSH */
+ args->cmd = TIOCFLUSH;
+ if ((int)args->arg == 0) (int)args->arg = FREAD;
+ if ((int)args->arg == 1) (int)args->arg = FWRITE;
+ if ((int)args->arg == 2) (int)args->arg = FREAD|FWRITE;
+ return ioctl(p, args, retval);
+
+ case 103: /* TIOCSWINSZ */
+ bsd_winsize.ws_row =
+ ((struct ibcs2_winsize *)(args->arg))->bytex;
+ bsd_winsize.ws_col =
+ ((struct ibcs2_winsize *)(args->arg))->bytey;
+ bsd_winsize.ws_xpixel =
+ ((struct ibcs2_winsize *)(args->arg))->bitx;
+ bsd_winsize.ws_ypixel =
+ ((struct ibcs2_winsize *)(args->arg))->bity;
+ return (*func)(fp, TIOCSWINSZ,
+ (caddr_t)&bsd_winsize, p);
+
+ case 104: /* TIOCGWINSZ */
+ if ((error = (*func)(fp, TIOCGWINSZ,
+ (caddr_t)&bsd_winsize, p)) != 0)
+ return error;
+ ibcs2_winsize.bytex = bsd_winsize.ws_col;
+ ibcs2_winsize.bytey = bsd_winsize.ws_row;
+ ibcs2_winsize.bitx = bsd_winsize.ws_xpixel;
+ ibcs2_winsize.bity = bsd_winsize.ws_ypixel;
+ return copyout((caddr_t)&ibcs2_winsize,
+ (caddr_t)args->arg,
+ sizeof(ibcs2_winsize));
+
+ case 20: /* TCSETPGRP */
+ case 118: /* TIOCSPGRP */
+ args->cmd = TIOCSPGRP;
+ return ioctl(p, args, retval);
+
+ case 21: /* TCGETPGRP */
+ case 119: /* TIOCGPGRP */
+ args->cmd = TIOCGPGRP;
+ return ioctl(p, args, retval);
+ }
+ break;
+
+ case ('x'):
+ switch (num) {
+ case 1:
+ if ((error = (*func)(fp, TIOCGETA,
+ (caddr_t)&bsd_termios, p)) != 0)
+ return error;
+ bsd_to_ibcs2_termios(&bsd_termios, &ibcs2_termios);
+ return copyout((caddr_t)&ibcs2_termios,
+ (caddr_t)args->arg,
+ sizeof(ibcs2_termios));
+ case 2:
+ ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
+ &bsd_termios);
+ return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
+ case 3:
+ ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
+ &bsd_termios);
+ return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
+ case 4:
+ ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
+ &bsd_termios);
+ return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
+
+ }
+ break;
+
+ /* below is console ioctl's, we have syscons so no problem here */
+ case 'c':
+ switch (num) {
+ case 4:
+ args->cmd = CONS_BLANKTIME;
+ return ioctl(p, args, retval);
+ case 64:
+ args->cmd = PIO_FONT8x8;
+ return ioctl(p, args, retval);
+ case 65:
+ args->cmd = GIO_FONT8x8;
+ return ioctl(p, args, retval);
+ case 66:
+ args->cmd = PIO_FONT8x14;
+ return ioctl(p, args, retval);
+ case 67:
+ args->cmd = GIO_FONT8x14;
+ return ioctl(p, args, retval);
+ case 68:
+ args->cmd = PIO_FONT8x16;
+ return ioctl(p, args, retval);
+ case 69:
+ args->cmd = GIO_FONT8x16;
+ return ioctl(p, args, retval);
+ case 73:
+ args->cmd = CONS_GETINFO;
+ return ioctl(p, args, retval);
+ }
+ break;
+
+ case 'k':
+ switch (num) {
+ case 0:
+ args->cmd = GETFKEY;
+ return ioctl(p, args, retval);
+ case 1:
+ args->cmd = SETFKEY;
+ return ioctl(p, args, retval);
+ case 2:
+ args->cmd = GIO_SCRNMAP;
+ return ioctl(p, args, retval);
+ case 3:
+ args->cmd = PIO_SCRNMAP;
+ return ioctl(p, args, retval);
+ case 6:
+ args->cmd = GIO_KEYMAP;
+ return ioctl(p, args, retval);
+ case 7:
+ args->cmd = PIO_KEYMAP;
+ return ioctl(p, args, retval);
+ }
+ break;
+
+ case 'K':
+ switch (num) {
+ case 6:
+ args->cmd = KDGKBMODE;
+ return ioctl(p, args, retval);
+ case 7:
+ args->cmd = KDSKBMODE;
+ return ioctl(p, args, retval);
+ case 8:
+ args->cmd = KDMKTONE;
+ return ioctl(p, args, retval);
+ case 9:
+ args->cmd = KDGETMODE;
+ return ioctl(p, args, retval);
+ case 10:
+ args->cmd = KDSETMODE;
+ return ioctl(p, args, retval);
+ case 13:
+ args->cmd = KDSBORDER;
+ return ioctl(p, args, retval);
+ case 19:
+ args->cmd = KDGKBSTATE;
+ return ioctl(p, args, retval);
+ case 20:
+ args->cmd = KDSETRAD;
+ return ioctl(p, args, retval);
+ case 60:
+ args->cmd = KDENABIO;
+ return ioctl(p, args, retval);
+ case 61:
+ args->cmd = KDDISABIO;
+ return ioctl(p, args, retval);
+ case 63:
+ args->cmd = KIOCSOUND;
+ return ioctl(p, args, retval);
+ case 64:
+ args->cmd = KDGKBTYPE;
+ return ioctl(p, args, retval);
+ case 65:
+ args->cmd = KDGETLED;
+ return ioctl(p, args, retval);
+ case 66:
+ args->cmd = KDSETLED;
+ return ioctl(p, args, retval);
+ }
+ break;
+
+ case 'S':
+ args->cmd = _IO('S', num);
+ return ioctl(p, args, retval);
+
+ case 'v':
+ switch (num) {
+ case 1:
+ args->cmd = VT_OPENQRY;
+ return ioctl(p, args, retval);
+ case 2:
+ args->cmd = VT_SETMODE;
+ return ioctl(p, args, retval);
+ case 3:
+ args->cmd = VT_GETMODE;
+ return ioctl(p, args, retval);
+ case 4:
+ args->cmd = VT_RELDISP;
+ return ioctl(p, args, retval);
+ case 5:
+ args->cmd = VT_ACTIVATE;
+ return ioctl(p, args, retval);
+ case 6:
+ args->cmd = VT_WAITACTIVE;
+ return ioctl(p, args, retval);
+ }
+ break;
+ }
+ uprintf("IBCS2: 'ioctl' fd=%d, typ=%d(%c), num=%d not implemented\n",
+ args->fd, type, type, num);
+ return EINVAL;
+}
+
+struct ibcs2_sgtty_args {
+ int fd;
+ struct sgttyb *buf;
+};
+
+struct ioctl_args {
+ int fd;
+ int cmd;
+ caddr_t arg;
+};
+
+int
+ibcs2_gtty(struct proc *p, struct ibcs2_sgtty_args *args, int *retval)
+{
+ struct ioctl_args ioctl_arg;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTL)
+ printf("IBCS2: 'gtty' fd=%d\n", args->fd);
+ ioctl_arg.fd = args->fd;
+ ioctl_arg.cmd = TIOCGETC;
+ ioctl_arg.arg = (caddr_t)args->buf;
+
+ return ioctl(p, &ioctl_arg, retval);
+}
+
+int
+ibcs2_stty(struct proc *p, struct ibcs2_sgtty_args *args, int *retval)
+{
+ struct ioctl_args ioctl_arg;
+
+ if (ibcs2_trace & IBCS2_TRACE_IOCTL)
+ printf("IBCS2: 'stty' fd=%d\n", args->fd);
+ ioctl_arg.fd = args->fd;
+ ioctl_arg.cmd = TIOCSETC;
+ ioctl_arg.arg = (caddr_t)args->buf;
+ return ioctl(p, &ioctl_arg, retval);
+}
diff --git a/sys/i386/ibcs2/ibcs2_ipc.c b/sys/i386/ibcs2/ibcs2_ipc.c
new file mode 100644
index 000000000000..f760e2ee7872
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_ipc.c
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 1994 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: ibcs2_ipc.c,v 1.3 1994/10/12 19:38:03 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/proc.h>
+
+int
+ibcs2_msgsys(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'msgsys'\n");
+#ifdef SYSVMSG
+ return msgsys(p, args, retval);
+#else
+ printf("IBCS2: 'msgsys' not implemented yet\n");
+ return EINVAL;
+#endif
+}
+
+int
+ibcs2_semsys(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'semsys'\n");
+#ifdef SYSVSEM
+ return semsys(p, args, retval);
+#else
+ printf("IBCS2: 'semsys' not implemented yet\n");
+ return EINVAL;
+#endif
+}
+
+int
+ibcs2_shmsys(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'shmsys'\n");
+#ifdef SYSVSHM
+ return shmsys(p, args, retval);
+#else
+ printf("IBCS2: 'shmsys' not implemented yet\n");
+ return EINVAL;
+#endif
+}
+
diff --git a/sys/i386/ibcs2/ibcs2_isc.c b/sys/i386/ibcs2/ibcs2_isc.c
new file mode 100644
index 000000000000..83f6be8c2573
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_isc.c
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * 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: ibcs2_isc.c,v 1.5 1994/10/12 19:38:03 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/sysent.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/signal.h>
+#include <sys/syslimits.h>
+#include <sys/timeb.h>
+#include <sys/unistd.h>
+#include <sys/utsname.h>
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+int
+ibcs2_cisc(struct proc *p, void *args, int *retval)
+{
+ struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
+
+ switch ((tf->tf_eax & 0xffffff00) >> 8) {
+
+ case 0x00:
+ printf("IBCS2: 'cisc #0' what is this ??\n");
+ return 0;
+
+ case 0x02:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc rename'\n");
+ return rename(p, args, retval);
+
+ case 0x03:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc sigaction'\n");
+ return ibcs2_sigaction(p, args, retval);
+
+ case 0x04:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc sigprocmask'\n");
+ return ibcs2_sigprocmask(p, args, retval);
+
+ case 0x05:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc sigpending'\n");
+ return ibcs2_sigpending(p, args, retval);
+
+ case 0x06:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc getgroups'\n");
+ return getgroups(p, args, retval);
+
+ case 0x07:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc setgroups'\n");
+ return setgroups(p, args, retval);
+
+ case 0x08: /* pathconf */
+ case 0x09: /* fpathconf */
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc (f)pathconf'");
+ return ibcs2_pathconf(p, args, retval);
+
+ case 0x10: { /* sysconf */
+ struct ibcs2_sysconf_args {
+ int num;
+ } *sysconf_args = args;
+
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc sysconf'");
+ switch (sysconf_args->num) {
+ case 0: /* _SC_ARG_MAX */
+ *retval = (ARG_MAX);
+ break;
+ case 1: /* _SC_CHILD_MAX */
+ *retval = (CHILD_MAX);
+ break;
+ case 2: /* _SC_CLK_TCK */
+ *retval = (CLK_TCK);
+ break;
+ case 3: /* _SC_NGROUPS_MAX */
+ *retval = (NGROUPS_MAX);
+ break;
+ case 4: /* _SC_OPEN_MAX */
+ *retval = (OPEN_MAX);
+ break;
+ case 5: /* _SC_JOB_CONTROL */
+#ifdef _POSIX_JOB_CONTORL
+ *retval = _POSIX_JOB_CONTORL;
+#else
+ *retval = (0);
+#endif
+ break;
+ case 6: /* _SC_SAVED_IDS */
+#ifdef _POSIX_SAVED_IDS
+ *retval = (_POSIX_SAVED_IDS);
+#else
+ *retval = (0);
+#endif
+ break;
+ case 7: /* _SC_VERSION */
+ *retval = (_POSIX_VERSION);
+ break;
+ default:
+ *retval = -1;
+ return EINVAL;
+ }
+ return 0;
+ }
+
+ case 0x0b:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc waitpid'\n");
+ return ibcs2_wait(p, args, retval);
+
+ case 0x0c:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc setsid'\n");
+ return setsid(p, args, retval);
+
+ case 0x0d:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc setpgid'\n");
+ return setpgid(p, args, retval);
+
+ case 0x11:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc sigsuspend'\n");
+ return ibcs2_sigsuspend(p, args, retval);
+
+ case 0x12:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc symlink'\n");
+ return symlink(p, args, retval);
+
+ case 0x13:
+ if (ibcs2_trace & IBCS2_TRACE_ISC)
+ printf("IBCS2: 'cisc readlink'\n");
+ return readlink(p, args, retval);
+
+ /* Here needs more work to be done */
+ case 0x01:
+ printf("IBCS2: 'cisc setostype'");
+ break;
+ case 0x0e:
+ printf("IBCS2: 'cisc adduser'");
+ break;
+ case 0x0f:
+ printf("IBCS2: 'cisc setuser'");
+ break;
+ case 0x14:
+ printf("IBCS2: 'cisc getmajor'");
+ break;
+ default:
+ printf("IBCS2: 'cisc' function %d(0x%x)",
+ tf->tf_eax>>8, tf->tf_eax>>8);
+ break;
+ }
+ printf(" not implemented yet\n");
+ return EINVAL;
+}
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
new file mode 100644
index 000000000000..c4dfe6cabbae
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -0,0 +1,968 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * All rights reserved.
+ *
+ * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ibcs2_misc.c,v 1.16 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/unistd.h>
+#include <sys/wait.h>
+#include <vm/vm.h>
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+int ibcs2_trace = 0;
+
+struct ibcs2_traceemu_args {
+ int options;
+};
+
+int
+ibcs2_traceemu(struct proc *p, struct ibcs2_traceemu_args *args, int *retval)
+{
+ *retval = ibcs2_trace;
+ ibcs2_trace = args->options;
+ return 0;
+}
+
+int
+ibcs2_access(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'access'\n");
+ return access(p, args, retval);
+}
+
+struct ibcs2_alarm_args {
+ unsigned int secs;
+};
+
+int
+ibcs2_alarm(struct proc *p, struct ibcs2_alarm_args *args, int *retval)
+{
+ extern struct timeval time;
+ struct itimerval it, oit;
+ int s;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'alarm' secs=%d\n", args->secs);
+ it.it_value.tv_sec = (long)args->secs;
+ it.it_value.tv_usec = 0;
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+ s = splclock();
+ oit = p->p_realtimer;
+ if (timerisset(&oit.it_value))
+ if (timercmp(&oit.it_value, &time, <))
+ timerclear(&oit.it_value);
+ else
+ timevalsub(&oit.it_value, &time);
+ splx(s);
+ if (itimerfix(&it.it_value) || itimerfix(&it.it_interval))
+ return EINVAL;
+ s = splclock();
+ untimeout(realitexpire, (caddr_t)p);
+ if (timerisset(&it.it_value)) {
+ timevaladd(&it.it_value, &time);
+ timeout(realitexpire, (caddr_t)p, hzto(&it.it_value));
+ }
+ p->p_realtimer = it;
+ splx(s);
+ if (oit.it_value.tv_usec)
+ oit.it_value.tv_sec++;
+ *retval = oit.it_value.tv_sec;
+ return 0;
+}
+
+struct ibcs2_break_args {
+ char *dsend;
+};
+
+int
+ibcs2_break(struct proc *p, struct ibcs2_break_args *args, int *retval)
+{
+ struct vmspace *vm = p->p_vmspace;
+ vm_offset_t new, old;
+ int rv, diff;
+ extern int swap_pager_full;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'break' dsend=%x\n",
+ (unsigned int)args->dsend);
+
+ if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr)
+ return EINVAL;
+ if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr)
+ > p->p_rlimit[RLIMIT_DATA].rlim_cur)
+ return ENOMEM;
+
+ old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize);
+ new = round_page((vm_offset_t)args->dsend);
+
+ diff = new - old;
+ if (diff > 0) {
+ if (swap_pager_full) {
+ return ENOMEM;
+ }
+ rv = vm_allocate(&vm->vm_map, &old, diff, FALSE);
+ if (rv != KERN_SUCCESS) {
+ return ENOMEM;
+ }
+ vm->vm_dsize += btoc(diff);
+ }
+ else if (diff < 0) {
+ diff = -diff;
+ rv = vm_deallocate(&vm->vm_map, new, diff);
+ if (rv != KERN_SUCCESS)
+ return ENOMEM;
+ vm->vm_dsize -= btoc(diff);
+ }
+ return 0;
+}
+
+int
+ibcs2_chdir(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'chdir'\n");
+ return chdir(p, args, retval);
+}
+
+int
+ibcs2_chmod(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'chmod'\n");
+ return chmod(p, args, retval);
+}
+
+int
+ibcs2_chown(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'chown'\n");
+ return chown(p, args, retval);
+}
+
+int
+ibcs2_chroot(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'chroot'\n");
+ return chroot(p, args, retval);
+}
+
+struct ibcs2_close_args {
+ int fd;
+};
+
+int
+ibcs2_close(struct proc *p, struct ibcs2_close_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'close' fd=%d\n", args->fd);
+ return close(p, args, retval);
+}
+
+struct exec_args {
+ char *name;
+ char **argv;
+};
+
+int
+ibcs2_exec(struct proc *p, struct exec_args *args, int *retval)
+{
+ struct execve_args {
+ char *name;
+ char **argv;
+ char **envp;
+ } execve_args;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'exec' name=%s\n", args->name);
+ execve_args.name = args->name;
+ execve_args.argv = args->argv;
+ execve_args.envp = 0;
+ return execve(p, &execve_args, retval);
+}
+
+struct ibcs2_exece_args {
+ char *name;
+ char **argv;
+ char **envp;
+};
+
+int
+ibcs2_exece(struct proc *p, struct ibcs2_exece_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'exece' name=%s\n", args->name);
+ return execve(p, args, retval);
+}
+
+int
+ibcs2_exit(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'exit'\n");
+ return exit(p, args, retval);
+}
+
+int
+ibcs2_fork(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'fork'\n");
+ return fork(p, args, retval);
+}
+
+int
+ibcs2_fsync(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'fsync'\n");
+ return fsync(p, args, retval);
+}
+
+int
+ibcs2_getgid(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'getgid'\n");
+ return getgid(p, args, retval);
+}
+
+struct ibcs2_getgroups_args {
+ int gidsetsize;
+ ibcs2_gid_t *gidset;
+};
+
+int
+ibcs2_getgroups(struct proc *p, struct ibcs2_getgroups_args *args, int *retval)
+{
+ struct getgroups_args {
+ u_int gidsetsize;
+ gid_t *gidset;
+ } tmp;
+ ibcs2_gid_t *ibcs2_gidset;
+ int i, error;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'getgroups'\n");
+
+ tmp.gidsetsize = args->gidsetsize;
+ tmp.gidset = (gid_t *)UA_ALLOC();
+ ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX];
+ if (error = getgroups(p, &tmp, retval))
+ return error;
+ for (i = 0; i < retval[0]; i++)
+ ibcs2_gidset[i] = (ibcs2_gid_t)tmp.gidset[i];
+ return copyout((caddr_t)ibcs2_gidset, (caddr_t)args->gidset,
+ sizeof(ibcs2_gid_t) * retval[0]);
+}
+
+int
+ibcs2_getpid(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'getpid'\n");
+ return getpid(p, args, retval);
+}
+
+int
+ibcs2_getuid(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'getuid'\n");
+ return getuid(p, args, retval);
+}
+
+struct gtime_args {
+ long *timeptr;
+};
+
+int
+ibcs2_gtime(struct proc *p, struct gtime_args *args, int *retval)
+{
+ int error = 0;
+ struct timeval tv;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'gtime'\n");
+ microtime(&tv);
+ *retval = tv.tv_sec;
+ if (args)
+ (long)args->timeptr = tv.tv_sec;
+ return error;
+}
+
+int
+ibcs2_link(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'link'\n");
+ return link(p, args, retval);
+}
+
+int
+ibcs2_mkdir(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'mkdir'\n");
+ return mkdir(p, args, retval);
+}
+
+struct ibcs2_mknod_args {
+ char *fname;
+ int fmode;
+ ibcs2_dev_t dev;
+};
+
+int
+ibcs2_mknod(struct proc *p, struct ibcs2_mknod_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'mknod'\n");
+ if (S_ISFIFO(args->fmode))
+ return mkfifo(p, args, retval);
+ return mknod(p, args, retval);
+}
+
+struct ibcs2_nice_args {
+ int niceval;
+};
+
+int
+ibcs2_nice(struct proc *p, struct ibcs2_nice_args *args, int *retval)
+{
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'nice'\n");
+ error = donice(p, p, args->niceval);
+ *retval = p->p_nice;
+ return error;
+}
+
+struct ibcs2_pathconf_args {
+ long unused;
+ int cmd;
+};
+int
+ibcs2_pathconf(struct proc *p, struct ibcs2_pathconf_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: '(f)pathconf'\n");
+ switch (args->cmd) {
+ case 0: /* _PC_LINK_MAX */
+ *retval = (LINK_MAX);
+ break;
+ case 1: /* _PC_MAX_CANON */
+ *retval = (MAX_CANON);
+ break;
+ case 2: /* _PC_MAX_INPUT */
+ *retval = (MAX_INPUT);
+ break;
+ case 5: /* _PC_PATH_MAX */
+ *retval = (PATH_MAX);
+ break;
+ case 8: /* _PC_VDISABLE */
+ *retval = (_POSIX_VDISABLE);
+ break;
+ case 3: /* _PC_NAME_MAX */
+ *retval = (NAME_MAX);
+ break;
+ case 4: /* _PC_PATH_MAX */
+ *retval = (PATH_MAX);
+ break;
+ case 6: /* _PC_CHOWN_RESTRICTED */
+#ifdef _POSIX_CHOWN_RESTRICTED
+ *retval = _POSIX_CHOWN_RESTRICTED;
+#else
+ *retval = (0);
+#endif
+ break;
+ case 7: /* _PC_NO_TRUNC */
+#ifdef _POSIX_NO_TRUNC
+ *retval = _POSIX_NO_TRUNC;
+#else
+ *retval = (1);
+#endif
+ break;
+ default:
+ *retval = -1;
+ return EINVAL;
+ }
+ return 0;
+}
+
+int
+ibcs2_pause(struct proc *p, void *args, int *retval)
+{
+ int mask = 0;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'pause'\n");
+ return sigsuspend(p, &mask, retval);
+}
+
+int
+ibcs2_pipe(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'pipe'\n");
+ return pipe(p, args, retval);
+}
+
+struct ibcs2_poll {
+ int fd;
+ short events;
+ short revents;
+};
+
+struct ibcs2_poll_args {
+ struct ibcs2_poll *fds;
+ unsigned long nfds;
+ int timeout;
+};
+
+int
+ibcs2_poll(struct proc *p, struct ibcs2_poll_args *args, int *retval)
+{
+ struct ibcs2_poll conv;
+ fd_set *readfds, *writefds, *exceptfds;
+ struct timeval *timeout;
+ struct select_args {
+ u_int nd;
+ fd_set *in, *ou, *ex;
+ struct timeval *tv;
+ } tmp_select;
+ int i, error;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'poll'\n");
+ if (args->nfds > FD_SETSIZE)
+ return EINVAL;
+ readfds = (fd_set *)UA_ALLOC();
+ FD_ZERO(readfds);
+ writefds = (fd_set *)UA_ALLOC() + sizeof(fd_set *);
+ FD_ZERO(writefds);
+ exceptfds = (fd_set *)UA_ALLOC() + 2*sizeof(fd_set *);
+ FD_ZERO(exceptfds);
+ timeout = (struct timeval *)UA_ALLOC() + 3*sizeof(fd_set *);
+ if (args->timeout == -1)
+ timeout = NULL;
+ else {
+ timeout->tv_usec = (args->timeout % 1000)*1000;
+ timeout->tv_sec = args->timeout / 1000;
+ }
+ tmp_select.nd = 0;
+ tmp_select.in = readfds;
+ tmp_select.ou = writefds;
+ tmp_select.ex = exceptfds;
+ tmp_select.tv = timeout;
+ for (i = 0; i < args->nfds; i++) {
+ if (error = copyin(args->fds + i*sizeof(struct ibcs2_poll),
+ &conv, sizeof(conv)))
+ return error;
+ conv.revents = 0;
+ if (conv.fd < 0 || conv.fd > FD_SETSIZE)
+ continue;
+ if (conv.fd >= tmp_select.nd)
+ tmp_select.nd = conv.fd + 1;
+ if (conv.events & IBCS2_READPOLL)
+ FD_SET(conv.fd, readfds);
+ if (conv.events & IBCS2_WRITEPOLL)
+ FD_SET(conv.fd, writefds);
+ FD_SET(conv.fd, exceptfds);
+ }
+ if (error = select(p, &tmp_select, retval))
+ return error;
+ if (*retval == 0)
+ return 0;
+ *retval = 0;
+ for (*retval = 0, i = 0; i < args->nfds; i++) {
+ copyin(args->fds + i*sizeof(struct ibcs2_poll),
+ &conv, sizeof(conv));
+ conv.revents = 0;
+ if (conv.fd < 0 || conv.fd > FD_SETSIZE)
+ /* should check for open as well */
+ conv.revents |= IBCS2_POLLNVAL;
+ else {
+ if (FD_ISSET(conv.fd, readfds))
+ conv.revents |= IBCS2_POLLIN;
+ if (FD_ISSET(conv.fd, writefds))
+ conv.revents |= IBCS2_POLLOUT;
+ if (FD_ISSET(conv.fd, exceptfds))
+ conv.revents |= IBCS2_POLLERR;
+ if (conv.revents)
+ ++*retval;
+ }
+ if (error = copyout(&conv,
+ args->fds + i*sizeof(struct ibcs2_poll),
+ sizeof(conv)))
+ return error;
+ }
+ return 0;
+}
+
+struct ibcs2_procids_args {
+ int req;
+ int eax;
+};
+
+int
+ibcs2_procids(struct proc *p, struct ibcs2_procids_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'procids' request=%d, eax=%x\n",
+ args->req, args->eax);
+ switch (args->req) {
+ case 0: /* getpgrp */
+ return getpgrp(p, args, retval);
+ case 1: /* setpgrp */
+ {
+ struct setpgid_args {
+ int pid;
+ int pgid;
+ } tmp;
+ tmp.pid = tmp.pgid = 0;
+ return setpgid(p, &tmp, retval);
+ }
+ case 2: /* setpgid */
+ return setpgid(p, args, retval);
+ case 3: /* setsid */
+ return setsid(p, args, retval);
+ default:
+ return EINVAL;
+ }
+}
+
+int
+ibcs2_profil(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'profil'\n");
+ return profil(p, args, retval);
+}
+
+int
+ibcs2_ptrace(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'ptrace'\n");
+ return ptrace(p, args, retval);
+}
+
+int
+ibcs2_readlink(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'readlink'\n");
+ return readlink(p, args, retval);
+}
+
+int
+ibcs2_rename(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'rename'\n");
+ return rename(p, args, retval);
+}
+
+int
+ibcs2_rmdir(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'rmdir'\n");
+ return rmdir(p, args, retval);
+}
+
+struct ibcs2_secure_args {
+ int cmd;
+ int arg1;
+ int arg2;
+ int arg3;
+ int arg4;
+ int arg5;
+};
+
+int
+ibcs2_secure(struct proc *p, struct ibcs2_secure_args *args, int *retval)
+{
+ struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'secure'\n");
+
+ switch (args->cmd) {
+
+ case 1: /* get login uid */
+ *retval = p->p_ucred->cr_uid;
+ return EPERM;
+
+ case 2: /* set login uid */
+
+ default:
+ printf("IBCS2: 'secure' cmd=%d not implemented\n",args->cmd);
+ }
+ return EINVAL;
+}
+
+struct ibcs2_setgid_args {
+ ibcs2_gid_t gid;
+};
+
+int
+ibcs2_setgid(struct proc *p, struct ibcs2_setgid_args *args, int *retval)
+{
+ struct setgid_args {
+ gid_t gid;
+ } tmp;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'setgid'\n");
+ tmp.gid = (gid_t) args->gid;
+ return setgid(p, &tmp, retval);
+}
+
+struct ibcs2_setgroups_args {
+ int gidsetsize;
+ ibcs2_gid_t *gidset;
+};
+
+int
+ibcs2_setgroups(struct proc *p, struct ibcs2_setgroups_args *args, int *retval)
+{
+ struct setgroups_args {
+ u_int gidsetsize;
+ gid_t *gidset;
+ } tmp;
+ ibcs2_gid_t *ibcs2_gidset;
+ int i, error;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'setgroups'\n");
+ tmp.gidsetsize = args->gidsetsize;
+ tmp.gidset = (gid_t *)UA_ALLOC();
+ ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX];
+ if (error = copyin((caddr_t)args->gidset, (caddr_t)ibcs2_gidset,
+ sizeof(ibcs2_gid_t) * tmp.gidsetsize))
+ return error;
+ for (i = 0; i < tmp.gidsetsize; i++)
+ tmp.gidset[i] = (gid_t)ibcs2_gidset[i];
+ return setgroups(p, &tmp, retval);
+}
+
+struct ibcs2_setuid_args {
+ ibcs2_uid_t uid;
+};
+
+int
+ibcs2_setuid(struct proc *p, struct ibcs2_setuid_args *args, int *retval)
+{
+ struct setuid_args {
+ uid_t uid;
+ } tmp;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'setuid'\n");
+ tmp.uid = (uid_t) args->uid;
+ return setuid(p, &tmp, retval);
+}
+
+int
+ibcs2_smount(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'smount'\n");
+ return mount(p, args, retval);
+}
+
+struct ibcs2_stime_args {
+ long *timeptr;
+};
+
+int
+ibcs2_stime(struct proc *p, struct ibcs2_stime_args *args, int *retval)
+{
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'stime'\n");
+ if (error = suser(p->p_ucred, &p->p_acflag))
+ return error;
+ if (args->timeptr) {
+#if 0
+ /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
+ boottime.tv_sec += (long)args->timeptr - time.tv_sec;
+ s = splhigh();
+ time.tv_sec = (long)args->timeptr;
+ time.tv_usec = 0;
+ splx(s);
+ resettodr();
+#else
+ printf("IBCS2: trying to set system time %d\n",
+ (long)args->timeptr);
+#endif
+ }
+ return 0;
+}
+
+int
+ibcs2_sumount(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'sumount'\n");
+ return unmount(p, args, retval);
+}
+
+int
+ibcs2_symlink(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'symlink'\n");
+ return symlink(p, args, retval);
+}
+
+int
+ibcs2_sync(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'sync'\n");
+ return sync(p, args, retval);
+}
+
+int
+ibcs2_sysacct(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'sysacct'\n");
+ return acct(p, args, retval);
+}
+
+struct ibcs2_tms {
+ long tms_utime;
+ long tms_stime;
+ long tms_cutime;
+ long tms_cstime;
+};
+
+int
+ibcs2_times(struct proc *p, struct ibcs2_tms *args, int *retval)
+{
+ extern int hz;
+ struct timeval tv;
+ struct ibcs2_tms tms;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'times'\n");
+ tms.tms_utime = p->p_uticks;
+ tms.tms_stime = p->p_sticks;
+ tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz +
+ ((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000);
+ tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz +
+ ((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000);
+ microtime(&tv);
+ *retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000;
+ return (copyout((caddr_t)&tms,
+ (caddr_t)args->tms_utime,
+ sizeof(struct ibcs2_tms)));
+}
+
+struct ibcs2_ulimit_args {
+ int cmd;
+ long limit;
+};
+
+int
+ibcs2_ulimit(struct proc *p, struct ibcs2_ulimit_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'ulimit'\n");
+ switch (args->cmd) {
+ case IBCS2_GETFSIZE:
+ *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
+ return 0;
+
+ case IBCS2_SETFSIZE:
+ return EINVAL;
+
+ case IBCS2_GETPSIZE:
+ *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur;
+ return 0;
+ case IBCS2_GETMOPEN:
+ *retval = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
+ return 0;
+ }
+ return EINVAL;
+}
+
+int
+ibcs2_umask(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'umask'\n");
+ return umask(p, args, retval);
+}
+
+int
+ibcs2_unlink(struct proc *p, void *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'unlink'\n");
+ return unlink(p, args, retval);
+}
+
+struct ibcs2_utime_args {
+ char *fname;
+ ibcs2_time_t *timeptr;
+};
+
+int
+ibcs2_utime(struct proc *p, struct ibcs2_utime_args *args, int *retval)
+{
+ struct bsd_utimes_args {
+ char *fname;
+ struct timeval *tptr;
+ } bsdutimes;
+ struct timeval tv;
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'utime'\n");
+ tv.tv_sec = (long)args->timeptr;
+ tv.tv_usec = 0;
+ bsdutimes.tptr = &tv;
+ bsdutimes.fname = args->fname;
+ return utimes(p, &bsdutimes, retval);
+}
+
+struct ibcs2_utssys_args {
+ char *buf;
+ int mv;
+ int cmd;
+};
+
+int
+ibcs2_utssys(struct proc *p, struct ibcs2_utssys_args *args, int *retval)
+{
+ struct ibcs2_utsname {
+ char sysname[9];
+ char nodename[9];
+ char release[9];
+ char version[9];
+ char machine[9];
+ } ibcs2_uname;
+ extern char ostype[], hostname[], osrelease[], machine[];
+
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'utssys' cmd=%d\n", args->cmd);
+ switch(args->cmd) {
+ case 0: /* uname */
+ bzero(&ibcs2_uname, sizeof(struct ibcs2_utsname));
+ strncpy(ibcs2_uname.sysname, ostype, 8);
+ strncpy(ibcs2_uname.nodename, hostname, 8);
+ strncpy(ibcs2_uname.release, osrelease, 8);
+ strncpy(ibcs2_uname.version, version, 8);
+ strncpy(ibcs2_uname.machine, machine, 8);
+ return (copyout((caddr_t)&ibcs2_uname,
+ (caddr_t)args->buf,
+ sizeof(struct ibcs2_utsname)));
+
+ case 2: /* ustat */
+ printf("IBCS2: utssys(ustat) not implemented yet\n");
+ return EINVAL;
+
+ case 1: /* umask, obsolete */
+ default:
+ printf("IBCS2: 'utssys cmd (%d) not implemented yet'\n",
+ args->cmd);
+ return EINVAL;
+ }
+}
+
+int
+ibcs2_wait(struct proc *p, void *args, int *retval)
+{
+ struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
+ struct ibcs2_waitpid_args {
+ int pid;
+ int *status;
+ int options;
+ } *t = args;
+ struct wait4_args {
+ int pid;
+ int *status;
+ int options;
+ struct rusage *rusage;
+ int compat;
+ } tmp;
+
+ tmp.compat = 1;
+ tmp.rusage = 0;
+ if (ibcs2_trace & IBCS2_TRACE_MISC)
+ printf("IBCS2: 'wait'\n");
+
+ if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V))
+ == (PSL_Z|PSL_PF|PSL_N|PSL_V)) {
+ tmp.pid = t->pid;
+ tmp.status = t->status;
+ tmp.options = 0;
+ if (t->options & 02)
+ tmp.options |= WUNTRACED;
+ if (t->options & 01)
+ tmp.options |= WNOHANG;
+ tmp.options = t->options;
+ } else {
+ tmp.pid = WAIT_ANY;
+ tmp.status = (int*)t->pid;
+ tmp.options = 0;
+ }
+ return wait1(p, &tmp, retval);
+}
diff --git a/sys/i386/ibcs2/ibcs2_signal.c b/sys/i386/ibcs2/ibcs2_signal.c
new file mode 100644
index 000000000000..7824a0b08754
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_signal.c
@@ -0,0 +1,462 @@
+/*-
+ * Copyright (c) 1994 Sean Eric Fagan
+ * Copyright (c) 1994 Søren Schmidt
+ * All rights reserved.
+ *
+ * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ibcs2_signal.c,v 1.9 1994/10/12 19:38:03 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/ioctl.h>
+#include <sys/ioctl_compat.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/namei.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/stat.h>
+#include <sys/tty.h>
+#include <sys/termios.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/vnode.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+
+
+#define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
+
+int bsd_to_ibcs2_signal[NSIG] = {
+ 0, IBCS2_SIGHUP, IBCS2_SIGINT, IBCS2_SIGQUIT,
+ IBCS2_SIGILL, IBCS2_SIGTRAP, IBCS2_SIGABRT, IBCS2_SIGEMT,
+ IBCS2_SIGFPE, IBCS2_SIGKILL, IBCS2_SIGBUS, IBCS2_SIGSEGV,
+ IBCS2_SIGSYS, IBCS2_SIGPIPE, IBCS2_SIGALRM, IBCS2_SIGTERM,
+ IBCS2_SIGURG, IBCS2_SIGSTOP, IBCS2_SIGTSTP, IBCS2_SIGCONT,
+ IBCS2_SIGCHLD, IBCS2_SIGTTIN, IBCS2_SIGTTOU, IBCS2_SIGIO,
+ IBCS2_SIGGXCPU, IBCS2_SIGGXFSZ, IBCS2_SIGVTALRM, IBCS2_SIGPROF,
+ IBCS2_SIGWINCH, 0, IBCS2_SIGUSR1, IBCS2_SIGUSR2
+};
+
+int ibcs2_to_bsd_signal[IBCS2_NSIG] = {
+ 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT,
+ SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM,
+ SIGUSR1, SIGUSR2, SIGCHLD, 0, SIGWINCH, SIGURG, SIGIO, SIGSTOP,
+ SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ
+};
+
+static char ibcs2_sig_name[IBCS2_NSIG][10] = {
+ "UNKNOWN", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
+ "SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS", "SIGSEGV",
+ "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1", "SIGUSR2",
+ "SIGCHLD", "SIGPWR", "SIGWINCH", "SIGURG", "SIGIO", "SIGSTOP",
+ "SIGTSTP", "SIGCONT", "SIGTTIN", "SIGTTOU", "SIGVTALRM",
+ "SIGPROF", "SIGXCPU", "SIGXFSZ"
+};
+
+/*#define LEGAL_SIG(x) \
+ (((x & IBCS2_SIGMASK) < IBCS2_NSIG) ? (x & IBCS2_SIGMASK) : (0))*/
+int
+LEGAL_SIG(int sig)
+{
+ if ((sig & IBCS2_SIGMASK) > IBCS2_NSIG) {
+ printf("IBCS2: illegal ibcs2 signal %d(%08x)\n",
+ sig & IBCS2_SIGMASK, sig);
+ return 0;
+ }
+ else
+ return (sig & IBCS2_SIGMASK);
+}
+
+char *
+ibcs2_sig_to_str(int sig)
+{
+ if (sig > IBCS2_NSIG) {
+ printf("IBCS2: ibcs2 signal out of range (%d)\n", sig);
+ return ibcs2_sig_name[0];
+ }
+ else
+ return ibcs2_sig_name[sig];
+}
+
+static sig_t
+ibcs2_to_bsd_sigfunc(ibcs2_sig_t func) {
+ switch ((int)func) {
+ case IBCS2_SIG_DFL:
+ return SIG_DFL;
+ case IBCS2_SIG_IGN:
+ return SIG_IGN;
+ case IBCS2_SIG_HOLD:
+ return SIG_HOLD;
+ default:
+ return func;
+ }
+}
+
+static ibcs2_sig_t
+bsd_to_ibcs2_sigfunc(sig_t func) {
+ switch ((int)func) {
+ case SIG_DFL:
+ return IBCS2_SIG_DFL;
+ case SIG_IGN:
+ return IBCS2_SIG_IGN;
+ case SIG_CATCH:
+ printf("IBCS2: Oops - SIG_CATCH does not translate :-(\n");
+ return IBCS2_SIG_DFL;
+ case SIG_HOLD:
+ return IBCS2_SIG_HOLD;
+ default:
+ return func;
+ }
+}
+
+static sigset_t
+ibcs2_to_bsd_sigmask(ibcs2_sigset_t mask) {
+ int i;
+ sigset_t new = 0;
+
+ for (i = 1; i < NSIG; i++)
+ if (mask & (1 << i-1))
+ new |= (1 << (ibcs2_to_bsd_signal[i]-1));
+ return new;
+}
+
+static ibcs2_sigset_t
+bsd_to_ibcs2_sigmask(sigset_t mask) {
+ int i;
+ sigset_t new = 0;
+
+ for (i = 1; i < IBCS2_NSIG; i++)
+ if (mask & (1 << i-1))
+ new |= (1 << (bsd_to_ibcs2_signal[i]-1));
+ return new;
+}
+
+struct ibcs2_signal_args {
+ int signo;
+ ibcs2_sig_t func;
+};
+
+static int
+ibcs2_sigset(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ struct sigaction tmp;
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ *retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
+ if (args->func == IBCS2_SIG_HOLD) {
+ (void) splhigh();
+ p->p_sigmask |= (sigmask(sig_bsd) &~ DONTMASK);
+ (void) spl0();
+ }
+ else {
+ tmp.sa_mask = sigmask(sig_bsd);
+ tmp.sa_handler = ibcs2_to_bsd_sigfunc(args->func);
+ tmp.sa_flags = 0;
+ setsigvec(p, sig_bsd, &tmp);
+ }
+ return 0;
+}
+
+static int
+ibcs2_sighold(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ (void) splhigh();
+ *retval = p->p_sigmask;
+ p->p_sigmask |= (sigmask(sig_bsd) & ~DONTMASK);
+ (void) spl0();
+ return 0;
+}
+
+static int
+ibcs2_sigrelse(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ (void) splhigh();
+ *retval = p->p_sigmask;
+ p->p_sigmask &= ~sigmask(sig_bsd);
+ (void) spl0();
+ return 0;
+}
+
+static int
+ibcs2_sigignore(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ struct sigaction tmp;
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ tmp.sa_mask = sigmask(sig_bsd);
+ tmp.sa_handler = SIG_IGN;
+ tmp.sa_flags = 0;
+ *retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
+ setsigvec(p, sig_bsd, &tmp);
+ return 0;
+}
+
+static int
+ibcs2_sigpause(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ struct sigacts *ps = p->p_sigacts;
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ ps->ps_oldmask = p->p_sigmask;
+ ps->ps_flags |= SAS_OLDMASK;
+ p->p_sigmask = sigmask(sig_bsd) &~ DONTMASK;
+ (void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "i-pause", 0);
+ *retval = -1;
+ return EINTR;
+}
+
+static int
+ibcs2_signal(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ struct sigaction tmp;
+ int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+
+ tmp.sa_mask = sigmask(sig_bsd);
+ tmp.sa_handler = ibcs2_to_bsd_sigfunc(args->func);
+ tmp.sa_flags = 0;
+ *retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
+ setsigvec(p, sig_bsd, &tmp);
+ return 0;
+}
+
+int
+ibcs2_sigsys(struct proc *p, struct ibcs2_signal_args *args, int *retval)
+{
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'sigsys' signo=%d(%s) ",
+ args->signo & IBCS2_SIGMASK,
+ ibcs2_sig_to_str(args->signo & IBCS2_SIGMASK));
+
+ switch (args->signo & ~IBCS2_SIGMASK ) {
+ case 0x0000:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("signal() func=%x\n", args->func);
+ return ibcs2_signal(p, args, retval);
+ case 0x0100:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("sigset() func=%x\n", args->func);
+ return ibcs2_sigset(p, args, retval);
+ case 0x0200:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("sighold()\n");
+ return ibcs2_sighold(p, args, retval);
+ case 0x0400:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("sigrelse()\n");
+ return ibcs2_sigrelse(p, args, retval);
+ case 0x0800:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("sigignore()\n");
+ return ibcs2_sigignore(p, args, retval);
+ case 0x1000:
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("sigpause()\n");
+ return ibcs2_sigpause(p, args, retval);
+ default:
+ printf("IBCS2: unknown signal action\n"); break;
+ }
+ *retval = -1;
+ return EINVAL;
+}
+
+struct ibcs2_sigaction_args {
+ int signo;
+ struct sigaction *osa, *nsa;
+};
+
+int
+ibcs2_sigaction(struct proc *p, struct ibcs2_sigaction_args *args, int *retval)
+{
+ struct sigaction vec;
+ register struct sigaction *sa;
+ register struct sigacts *ps = p->p_sigacts;
+ register int sig;
+ int bit, error;
+
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'sigaction' signo=%d(%s)\n",
+ args->signo, ibcs2_sig_to_str(args->signo));
+ sig = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
+ if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
+ *retval = -1;
+ return EINVAL;
+ }
+ sa = &vec;
+ if (args->osa) {
+ sa->sa_handler = ps->ps_sigact[sig];
+ sa->sa_mask = ps->ps_catchmask[sig];
+ bit = sigmask(sig);
+ sa->sa_flags = 0;
+ if (p->p_flag & SA_NOCLDSTOP)
+ sa->sa_flags = IBCS2_SA_NOCLDSTOP;
+ if (error = copyout((caddr_t)sa, (caddr_t)args->osa,
+ sizeof(vec))) {
+ *retval = -1;
+ return error;
+ }
+ }
+ if (args->nsa) {
+ if (error = copyin((caddr_t)args->nsa, (caddr_t)sa,
+ sizeof(vec))) {
+ *retval = -1;
+ return error;
+ }
+ /*
+ * iBCS2 only defines one SA_ flag right now
+ */
+ if (vec.sa_flags & IBCS2_SA_NOCLDSTOP)
+ vec.sa_flags = SA_NOCLDSTOP;
+ setsigvec(p, sig, sa);
+ }
+ *retval = 0;
+ return 0;
+}
+
+struct ibcs2_sigprocmask_args {
+ int how;
+ unsigned long *mask;
+ unsigned long *omask;
+};
+
+int
+ibcs2_sigprocmask(struct proc *p, struct ibcs2_sigprocmask_args *args, int *retval)
+{
+ int error;
+ sigset_t umask;
+ sigset_t omask = bsd_to_ibcs2_sigmask(p->p_sigmask);
+
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'sigprocmask' how=%d\n", args->how);
+ if (error = copyin(args->mask, &umask, sizeof(args->mask))) {
+ *retval = -1;
+ return error;
+ }
+ umask = ibcs2_to_bsd_sigmask(umask);
+ if (args->omask)
+ if (error = copyout(&omask, args->omask, sizeof(args->omask))) {
+ *retval = -1;
+ return error;
+ }
+ (void) splhigh();
+ switch (args->how) {
+ case 0: /* SIG_SETMASK */
+ p->p_sigmask = umask &~ DONTMASK;
+ break;
+
+ case 1: /* SIG_BLOCK */
+ p->p_sigmask |= (umask &~ DONTMASK);
+ break;
+
+ case 2: /* SIG_UNBLOCK */
+ p->p_sigmask &= ~umask;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ (void) spl0();
+ if (error)
+ *retval = -1;
+ else
+ *retval = 0;
+ return error;
+}
+
+struct ibcs2_sigpending_args {
+ unsigned long *sigs;
+};
+
+int
+ibcs2_sigpending(struct proc *p, struct ibcs2_sigpending_args *args, int *retval)
+{
+ int error;
+ sigset_t mask = bsd_to_ibcs2_sigmask(p->p_siglist);
+
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'sigpending' which=%x\n", args->sigs);
+ if (error = copyout(&mask, args->sigs, sizeof(unsigned long)))
+ *retval = -1;
+ else
+ *retval = 0;
+ return error;
+}
+
+struct ibcs2_sigsuspend_args {
+ sigset_t *mask;
+};
+
+int
+ibcs2_sigsuspend(struct proc *p, struct ibcs2_sigsuspend_args *args, int *retval)
+{
+ sigset_t mask = ibcs2_to_bsd_sigmask((sigset_t)args->mask);
+
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'sigsuspend'\n");
+ return sigsuspend(p, &mask, retval);
+}
+
+struct kill_args {
+ int pid;
+ int signo;
+};
+
+int
+ibcs2_kill(struct proc *p, struct kill_args *args, int *retval)
+{
+ struct kill_args tmp;
+
+ if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
+ printf("IBCS2: 'kill' pid=%d, sig=%d(%s)\n", args->pid,
+ args->signo, ibcs2_sig_to_str(args->signo));
+ tmp.pid = args->pid;
+ tmp.signo = (args->signo < IBCS2_NSIG) ?
+ ibcs2_to_bsd_signal[args->signo] : IBCS2_NSIG;
+ return kill(p, &tmp, retval);
+}
+
diff --git a/sys/i386/ibcs2/ibcs2_socksys.c b/sys/i386/ibcs2/ibcs2_socksys.c
new file mode 100644
index 000000000000..a5076da2f292
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_socksys.c
@@ -0,0 +1,1450 @@
+/*-
+ * Copyright (c) 1994 Mostyn Lewis
+ * All rights reserved.
+ *
+ * This software is based on code which is:
+ * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
+ *
+ * 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: ibcs2_socksys.c,v 1.2 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/filedesc.h>
+#include <sys/file.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <sys/malloc.h>
+#include <sys/un.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <vm/vm.h>
+#include <i386/ibcs2/ibcs2.h>
+#include <i386/ibcs2/ibcs2_socksys.h>
+
+/* Socksys pseudo driver entry points */
+
+int sockopen (dev_t dev, int mode, int devtype, struct proc *p);
+int sockioctl(dev_t dev, int cmd, caddr_t arg, int fflag, struct proc *p);
+int sockclose(dev_t dev, int flag, int mode, struct proc *p);
+
+/* Socksys internal functions */
+
+static void put_socket_fops(struct proc *p, int fd);
+static int ss_fop_close(struct file *fp, struct proc *p);
+static int ss_fop_ioctl(struct file*fp, int cmd, caddr_t arg, struct proc *p);
+static int ss_syscall(caddr_t arg, struct proc *p);
+
+/*
+ * This structure is setup on first usage. Its address is planted
+ * into a socket's file structure fileops pointer after a successful
+ * socket creation or accept.
+ */
+static struct fileops ss_socket_fops = {
+ NULL, /* normal socket read */
+ NULL, /* normal socket write */
+ NULL, /* socksys ioctl */
+ NULL, /* normal socket select */
+ NULL, /* socksys close */
+};
+
+static int (*close_s)__P((struct file *fp, struct proc *p));
+static int (*ioctl_s)__P((struct file *fp, int cmd, caddr_t data, struct proc *p));
+
+int ss_debug = 1;
+
+static int
+ss_syscall(arg, p)
+ caddr_t arg;
+ struct proc *p;
+{
+ int cmd;
+ int error;
+ int retval[2];
+
+ retval[0] = retval[1] = 0;
+ cmd = ((struct ss_call *)arg)->arg[0];
+
+#ifdef SS_DEBUG
+ if(ss_debug) {
+ static char *ss_syscall_strings[] = {
+ "0?", "accept", "bind", "connect", "getpeername",
+ "getsockname", "getsockopt", "listen", "recv(from)",
+ "recvfrom", "send(to)", "sendto", "setsockopt", "shutdown",
+ "socket", "select", "getipdomain", "setipdomain",
+ "adjtime", "setreuid", "setregid", "gettimeofday",
+ "settimeofday", "getitimer", "setitimer",
+ };
+
+ printf("ss_syscall: [%d] ",p->p_pid);
+ if(cmd < 0 || (cmd > CMD_SO_SETITIMER && cmd != CMD_SO_SS_DEBUG) )
+ printf("? ");
+ else {
+ if(cmd == CMD_SO_SS_DEBUG)
+ printf("%s ","ss_debug");
+ else
+ printf("%s ",ss_syscall_strings[cmd]);
+ }
+ printf("(%d) <0x%x,0x%x,0x%x,0x%x,0x%x,0x%x>\n",
+ cmd,
+ ((struct ss_call *)arg)->arg[1],
+ ((struct ss_call *)arg)->arg[2],
+ ((struct ss_call *)arg)->arg[3],
+ ((struct ss_call *)arg)->arg[4],
+ ((struct ss_call *)arg)->arg[5],
+ ((struct ss_call *)arg)->arg[6]);
+ }
+#endif /* SS_DEBUG */
+
+ error = 0;
+
+ switch (cmd) {
+
+ case CMD_SO_SS_DEBUG:
+
+ ss_debug = ((struct ss_call *)arg)->arg[1];
+ break;
+
+ case CMD_SO_SOCKET: { /* NO CONV */
+
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("SO_SOCKET af in %d\n",
+ ((struct ss_call *)arg)->arg[1]);
+#endif /* SS_DEBUG */
+ ((struct ss_call *)arg)->arg[1] = ss_convert(
+ af_whatevers,
+ &(((struct ss_call *)arg)->arg[1]),
+ 0);
+#ifdef SS_DEBUG
+ if(ss_debug > 1) {
+ printf("SO_SOCKET af out %d\n",
+ ((struct ss_call *)arg)->arg[1]);
+
+ printf("SO_SOCKET type in %d\n",
+ ((struct ss_call *)arg)->arg[2]);
+ }
+#endif /* SS_DEBUG */
+ ((struct ss_call *)arg)->arg[2] = ss_convert(
+ type_whatevers,
+ &(((struct ss_call *)arg)->arg[2]),
+ 0);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("SO_SOCKET type out %d\n",
+ ((struct ss_call *)arg)->arg[2]);
+#endif /* SS_DEBUG */
+
+ SYSCALL(SYS_socket, 0, 0);
+
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_syscall: [%d] socket fd=%d\n",
+ p->p_pid, retval[0]);
+#endif /* SS_DEBUG */
+ put_socket_fops(p,retval[0]);
+
+ break;
+ }
+
+ case CMD_SO_ACCEPT: { /* CONVERSION in arg 2 */
+
+ SYSCALL(SYS_accept, 2, SS_STRUCT_SOCKADDR);
+
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_syscall: [%d] accept fd=%d\n",
+ p->p_pid, retval[0]);
+#endif /* SS_DEBUG */
+ put_socket_fops(p,retval[0]);
+
+ break;
+ }
+
+ case CMD_SO_BIND:
+ SYSCALL(SYS_bind, 2, SS_STRUCT_SOCKADDR);
+ break;
+
+ case CMD_SO_CONNECT: {
+ struct alien_sockaddr *sa;
+ unsigned short family;
+
+ /* Remap any INADDR_ANY (0.0.0.0) to localhost */
+
+ sa = (struct alien_sockaddr *)((struct ss_call *)arg)->arg[1];
+ if(error = copyin((caddr_t)&sa->sa_family,
+ (caddr_t)&family, sizeof(short)))
+ return(error);
+ if (family == AF_INET) {
+ unsigned long *addr;
+ unsigned long saddr;
+
+ addr = &(((struct alien_sockaddr_in *)sa)->sin_addr.s_addr);
+ if(error = copyin((caddr_t)addr, (caddr_t)&saddr, sizeof(long)))
+ return(error);
+ if (saddr == INADDR_ANY) {
+ /* 0x0100007f is 127.0.0.1 reversed */
+ saddr = 0x0100007f;
+ if(error = copyout((caddr_t)&saddr,
+ (caddr_t)addr, sizeof(long)))
+ return(error);
+#ifdef SS_DEBUG
+ if (ss_debug)
+ printf("ss_syscall: remapped INADDR_ANY to localhost\n");
+#endif /* SS_DEBUG */
+ }
+ }
+ SYSCALL(SYS_connect, 2, SS_STRUCT_SOCKADDR);
+ break;
+ }
+
+ case CMD_SO_GETPEERNAME:
+ SYSCALL(SYS_getpeername, 2, SS_STRUCT_SOCKADDR);
+ break;
+
+ case CMD_SO_GETSOCKNAME:
+ SYSCALL(SYS_getsockname, 2, SS_STRUCT_SOCKADDR);
+ break;
+
+ case CMD_SO_GETSOCKOPT:
+ if(error = ss_getsockopt((caddr_t)(((int *)arg) + 1),retval,p))
+ return(error);
+ break;
+
+ case CMD_SO_LISTEN:
+ SYSCALL(SYS_listen, 0, 0);
+ break;
+
+ case CMD_SO_RECV:
+ ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
+ ((struct ss_call *)arg)->arg[6] = 0;
+ SYSCALL(SYS_recvfrom, 0, 0);
+ break;
+
+ case CMD_SO_RECVFROM:
+ SYSCALL(SYS_recvfrom, 5, SS_STRUCT_SOCKADDR);
+ break;
+
+ case CMD_SO_SEND:
+ ((struct ss_call *)arg)->arg[5] = (int)((struct sockaddr *)NULL);
+ ((struct ss_call *)arg)->arg[6] = 0;
+ SYSCALL(SYS_sendto, 0, 0);
+ break;
+
+ case CMD_SO_SENDTO:
+ SYSCALL(SYS_sendto, 5, SS_STRUCT_SOCKADDR);
+ break;
+
+ case CMD_SO_SETSOCKOPT:
+ if(error = ss_setsockopt((caddr_t)(((int *)arg) + 1),retval,p))
+ return(error);
+
+ case CMD_SO_SHUTDOWN:
+ SYSCALL(SYS_shutdown, 0, 0);
+ break;
+
+ case CMD_SO_GETIPDOMAIN:
+ SYSCALL(SYS_getdomainname, 0, 0);
+ break;
+
+ case CMD_SO_SETIPDOMAIN: /* Note check on BSD utsname no change? */
+ SYSCALL(SYS_setdomainname, 0, 0);
+ break;
+
+ case CMD_SO_SETREUID:
+ SYSCALL(126/*SYS_setreuid*/, 0, 0);
+ break;
+
+ case CMD_SO_SETREGID:
+ SYSCALL(127/*SYS_setregid*/, 0, 0);
+ break;
+
+ case CMD_SO_GETTIME:
+ SYSCALL(SYS_gettimeofday, 0, 0);
+ break;
+
+ case CMD_SO_SETTIME:
+ SYSCALL(SYS_settimeofday, 0, 0);
+ break;
+
+ case CMD_SO_GETITIMER:
+ SYSCALL(SYS_getitimer, 0, 0);
+ break;
+
+ case CMD_SO_SETITIMER:
+ SYSCALL(SYS_setitimer, 0, 0);
+ break;
+
+ case CMD_SO_SELECT:
+ SYSCALL(SYS_select, 0, 0);
+ break;
+
+ case CMD_SO_ADJTIME:
+ SYSCALL(SYS_adjtime, 0, 0);
+ break;
+
+ default:
+ printf("ss_syscall: default 0x%x\n",cmd);
+ return (EINVAL);
+ }
+ IBCS2_MAGIC_RETURN;
+}
+
+
+static int
+ss_fop_ioctl(fp, cmd, arg, p)
+ struct file *fp;
+ int cmd;
+ caddr_t arg;
+ struct proc *p;
+{
+ int error;
+ int retval[2];
+
+#ifdef SS_DEBUG
+ if(ss_debug) {
+ static char **ioctl_strings;
+ int fd;
+ struct filedesc *fdp;
+ unsigned int ioctl_type;
+ unsigned int ioctl_len;
+ char cmd_type;
+ int cmd_ordinal;
+
+ static char *ioctl_type_strings[] = {
+ "0?", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
+ };
+ static char *ioctl_S_strings[] = {
+ "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
+ "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
+ "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
+ "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
+ };
+ static char *ioctl_R_strings[] = {
+ "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
+ "SIOCADDRT", "SIOCDELRT"
+ };
+ static char *ioctl_I_strings[] = {
+ "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
+ "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
+ "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
+ "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
+ "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
+ "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
+ "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
+ "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
+ "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
+ "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
+ "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
+ "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
+ "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
+ "SIOCSOCKSYS"
+ };
+
+ cmd_type = (cmd >> 8) & 0xff;
+ cmd_ordinal = cmd & 0xff;
+
+ switch (cmd_type) {
+
+ case 'S':
+ ioctl_strings = ioctl_S_strings;
+ if (cmd_ordinal > 15)
+ cmd_ordinal = -1;
+ break;
+
+ case 'R':
+ ioctl_strings = ioctl_R_strings;
+ if (cmd_ordinal > 10)
+ cmd_ordinal = -1;
+ break;
+
+ case 'I':
+ ioctl_strings = ioctl_I_strings;
+ if (cmd_ordinal > 66)
+ cmd_ordinal = -1;
+ break;
+
+ default:
+ cmd_type = '?';
+ break;
+ }
+ fdp = p->p_fd;
+ fd = -1;
+ while(++fd < NOFILE)
+ if ( fp == fdp->fd_ofiles[fd] )
+ break;
+
+ ioctl_type = (0xe0000000 & cmd) >> 29;
+ ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
+
+ printf("ss_fop_ioctl: [%d] fd=%d ",p->p_pid, fd);
+ if(cmd_type != '?'){
+ if(cmd_ordinal != -1)
+ printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ else {
+ cmd_ordinal = cmd & 0xff;
+ printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ }
+ }
+ else {
+ printf("? %s('%c',%d,l=%d) ",
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ }
+
+ printf("0x%x (0x%x) <0x%x>\n",
+ fp, cmd, arg);
+ }
+#endif /* SS_DEBUG */
+
+ /* No dogs allowed */
+
+ if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
+ printf("ss_fop_ioctl: bad magic (sys_generic.c has no socksys mods?)\n");
+ return(EINVAL);
+ }
+
+ if(fp->f_type != DTYPE_SOCKET)
+ return (ENOTSOCK);
+
+ retval[0] = retval[1] = 0;
+
+
+ error = 0;
+
+ switch (cmd) {
+ case SS_SIOCSHIWAT: /* set high watermark */
+ case SS_SIOCSLOWAT: /* set low watermark */
+ break; /* return value of 0 and no error */
+
+ case SS_SIOCGHIWAT: /* get high watermark */
+ case SS_SIOCGLOWAT: /* get low watermark */
+ break; /* return value of 0 and no error */
+
+ case SS_SIOCATMARK: /* at oob mark */
+ IOCTL(SIOCATMARK);
+ break;
+
+ case SS_SIOCSPGRP: /* set process group */
+ IOCTL(SIOCSPGRP);
+ break;
+ case SS_SIOCGPGRP: /* get process group */
+ IOCTL(SIOCGPGRP);
+ break;
+
+ case FIONREAD:
+ case SS_FIONREAD: /* get # bytes to read */
+ IOCTL(FIONREAD);
+ break;
+
+ case SS_FIONBIO: /* set/clear non-blocking i/o */
+ IOCTL(FIONBIO);
+ break;
+
+ case SS_FIOASYNC: /* set/clear async i/o */
+ IOCTL(FIOASYNC);
+ break;
+
+ case SS_SIOCADDRT: /* add route - uses struct ortentry */
+ IOCTL(SIOCADDRT);
+ break;
+
+ case SS_SIOCDELRT: /* delete route - uses struct ortentry */
+ IOCTL(SIOCDELRT);
+ break;
+
+ case SS_SIOCSIFADDR: /* set ifnet address */
+ IOCTL(SIOCSIFADDR);
+ break;
+
+ case SS_SIOCGIFADDR: /* get ifnet address */
+ IOCTL(SIOCGIFADDR);
+ break;
+
+ case SS_SIOCSIFDSTADDR: /* set p-p address */
+ IOCTL(SIOCSIFDSTADDR);
+ break;
+
+ case SS_SIOCGIFDSTADDR: /* get p-p address */
+ IOCTL(SIOCGIFDSTADDR);
+ break;
+
+ case SS_SIOCSIFFLAGS: /* set ifnet flags */
+ IOCTL(SIOCSIFFLAGS);
+ break;
+
+ case SS_SIOCGIFFLAGS: /* get ifnet flags */
+ IOCTL(SIOCGIFFLAGS);
+ break;
+
+ case SS_SIOCGIFCONF: /* get ifnet ltst */
+ IOCTL(SIOCGIFCONF);
+ break;
+
+ case SS_SIOCGIFBRDADDR: /* get broadcast addr */
+ IOCTL(SIOCGIFBRDADDR);
+ break;
+
+ case SS_SIOCSIFBRDADDR: /* set broadcast addr */
+ IOCTL(SIOCSIFBRDADDR);
+ break;
+
+ case SS_SIOCGIFNETMASK: /* get net addr mask */
+ IOCTL(SIOCGIFNETMASK);
+ break;
+
+ case SS_SIOCSIFNETMASK: /* set net addr mask */
+ IOCTL(SIOCSIFNETMASK);
+ break;
+
+ case SS_SIOCGIFMETRIC: /* get IF metric */
+ IOCTL(SIOCGIFMETRIC);
+ break;
+
+ case SS_SIOCSIFMETRIC: /* set IF metric */
+ IOCTL(SIOCSIFMETRIC);
+ break;
+
+/* FreeBSD 2.0 does not have socket ARPs */
+
+#ifdef SIOCSARP
+
+ case SS_SIOCSARP: /* set arp entry */
+ IOCTL(SIOCSARP);
+ break;
+
+ case SS_SIOCGARP: /* get arp entry */
+ IOCTL(SIOCGARP);
+ break;
+
+ case SS_SIOCDARP: /* delete arp entry */
+ IOCTL(SIOCDARP);
+ break;
+
+#else /* SIOCSARP */
+
+ case SS_SIOCSARP: /* set arp entry */
+ return(EINVAL);
+
+ case SS_SIOCGARP: /* get arp entry */
+ return(EINVAL);
+
+ case SS_SIOCDARP: /* delete arp entry */
+ return(EINVAL);
+
+#endif /* SIOCSARP */
+
+ case SS_SIOCGENADDR: /* Get ethernet addr XXX */
+ return (EINVAL);
+/* return (error = ioctl_s(fp, SIOCGIFHWADDR, arg, p)); */
+
+ case SS_SIOCSIFMTU: /* get if_mtu */
+ IOCTL(SIOCSIFMTU);
+ break;
+
+ case SS_SIOCGIFMTU: /* set if_mtu */
+ IOCTL(SIOCGIFMTU);
+ break;
+
+ case SS_SIOCGETNAME: /* getsockname XXX */
+ return (EINVAL);
+/* return (ioctl_s(fp, SIOCGIFNAME, arg, p)); MMM */
+
+ case SS_SIOCGETPEER: { /* getpeername */
+ struct moose {
+ int fd;
+ caddr_t asa;
+ int *alen;
+ int compat_43;
+ } args;
+
+ struct alien_sockaddr uaddr;
+ struct sockaddr nuaddr;
+ int nuaddr_len = sizeof(struct sockaddr);
+ struct filedesc *fdp;
+
+ if(fp->f_type != DTYPE_SOCKET)
+ return (ENOTSOCK);
+
+ bzero((caddr_t)&nuaddr, sizeof(struct sockaddr));
+ fdp = p->p_fd;
+ args.fd = -1;
+ while(++args.fd < NOFILE)
+ if ( fp == fdp->fd_ofiles[args.fd] )
+ break;
+ if(args.fd == NOFILE){
+ printf("ss_fop_ioctl: [%d] SS_SIOCGETPEER args.fd > NOFILE\n", p->p_pid);
+ return(EBADF);
+ }
+ args.asa = (caddr_t)&nuaddr;
+ args.alen = &nuaddr_len;
+ args.compat_43 = 0;
+ error = SYSCALLX(SYS_getpeername, &args);
+ if(error)
+ return(error);
+
+ bzero((caddr_t)&uaddr, sizeof(struct alien_sockaddr));
+ uaddr.sa_family = (unsigned short)nuaddr.sa_family;
+ bcopy(&nuaddr.sa_data, &uaddr.sa_data, __ALIEN_SOCK_SIZE__ - sizeof(unsigned short));
+
+ error = copyout((caddr_t)&uaddr, (caddr_t)arg, sizeof(struct alien_sockaddr));
+ return error;
+ }
+
+ default:
+ printf("ss_fop_ioctl: [%d] %lx unknown ioctl 0x%x, 0x%lx\n",
+ p->p_pid, (unsigned long)fp,
+ cmd, (unsigned long)arg);
+ return (EINVAL);
+ }
+ IBCS2_MAGIC_RETURN;
+}
+
+int
+sockioctl(dev, cmd, arg, fflag, p)
+ dev_t dev;
+ int cmd;
+ caddr_t arg;
+ int fflag;
+ struct proc *p;
+{
+ int error;
+ int retval[2];
+
+#ifdef SS_DEBUG
+ if(ss_debug) {
+ char cmd_type;
+ int cmd_ordinal;
+ static char **ioctl_strings;
+ unsigned int ioctl_type;
+ unsigned int ioctl_len;
+
+ static char *ioctl_type_strings[] = {
+ "NIOCxx", "SS_IO", "SS_IOR", "3?", "SS_IOW", "5?", "SS_IOWR"
+ };
+ static char *ioctl_S_strings[] = {
+ "0?", "SIOCSHIWAT", "SIOCGHIWAT", "SIOCSLOWAT", "SIOCGLOWAT",
+ "SIOCATMARK", "SIOCSPGRP", "SIOCGPGRP", "FIONREAD",
+ "FIONBIO", "FIOASYNC", "SIOCPROTO", "SIOCGETNAME",
+ "SIOCGETPEER", "IF_UNITSEL", "SIOCXPROTO"
+ };
+ static char *ioctl_R_strings[] = {
+ "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
+ "SIOCADDRT", "SIOCDELRT"
+ };
+ static char *ioctl_I_strings[] = {
+ "0?", "1?", "2?", "3?", "4?", "5?", "6?", "7?", "8?",
+ "9?", "10?", "SIOCSIFADDR", "SIOCGIFADDR", "SIOCSIFDSTADDR",
+ "SIOCGIFDSTADDR", "SIOCSIFFLAGS", "SIOCGIFFLAGS",
+ "SIOCGIFCONF", "18?", "19?", "20?", "SIOCSIFMTU",
+ "SIOCGIFMTU", "23?", "24?", "25?", "SIOCIFDETACH",
+ "SIOCGENPSTATS", "28?", "SIOCX25XMT", "SS_SIOCX25RCV",
+ "SS_SIOCX25TBL", "SIOCGIFBRDADDR" ,"SIOCSIFBRDADDR",
+ "SIOCGIFNETMASK", "SIOCSIFNETMASK", "SIOCGIFMETRIC",
+ "SIOCSIFMETRIC", "SIOCSARP", "SIOCGARP", "SIOCDARP",
+ "SIOCSIFNAME", "SIOCGIFONEP", "SIOCSIFONEP ",
+ "44?", "45?", "46?", "47?", "48?", "49?", "50?", "51?",
+ "52?", "53?", "54?", "55?", "56?", "57?", "58?", "59?",
+ "60?", "61?", "62?", "63?", "64?", "SIOCGENADDR",
+ "SIOCSOCKSYS"
+ };
+ static char *ioctl_NIOC_strings[] = {
+ "0?", "NIOCNFSD", "NIOCOLDGETFH", "NIOCASYNCD",
+ "NIOCSETDOMNAM", "NIOCGETDOMNAM", "NIOCCLNTHAND",
+ "NIOCEXPORTFS", "NIOCGETFH", "NIOCLSTAT"
+ };
+
+ cmd_ordinal = cmd & 0xff;
+ cmd_type = (cmd >> 8) & 0xff;
+ switch (cmd_type) {
+
+ case 0:
+ ioctl_strings = ioctl_NIOC_strings;
+ cmd_type = ' ';
+ if (cmd_ordinal > 9)
+ cmd_ordinal = -1;
+ break;
+
+ case 'S':
+ ioctl_strings = ioctl_S_strings;
+ if (cmd_ordinal > 15)
+ cmd_ordinal = -1;
+ break;
+
+ case 'R':
+ ioctl_strings = ioctl_R_strings;
+ if (cmd_ordinal > 10)
+ cmd_ordinal = -1;
+ break;
+
+ case 'I':
+ ioctl_strings = ioctl_I_strings;
+ if (cmd_ordinal > 66)
+ cmd_ordinal = -1;
+ break;
+
+ default:
+ cmd_type = '?';
+ break;
+
+ }
+ ioctl_type = (0xe0000000 & cmd) >> 29;
+ ioctl_len = (cmd >> 16) & SS_IOCPARM_MASK;
+
+ printf("sockioctl: [%d] ",p->p_pid);
+ if(cmd_type != '?'){
+ if(cmd_ordinal != -1)
+ printf("%s %s('%c',%d,l=%d) ",ioctl_strings[cmd_ordinal],
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ else {
+ cmd_ordinal = cmd & 0xff;
+ printf("[unknown ordinal %d] %s('%c',%d,l=%d) ",cmd_ordinal,
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ }
+ }
+ else {
+ printf("? %s('%c',%d,l=%d) ",
+ ioctl_type_strings[ioctl_type],
+ cmd_type,
+ cmd_ordinal,
+ ioctl_len);
+ }
+
+ printf("0x%x (0x%x) <0x%x>\n",
+ dev, cmd, arg);
+ }
+#endif /* SS_DEBUG */
+
+ if(*(((int *)arg) - 3) != IBCS2_MAGIC_IN){
+ printf("sockioctl: bad magic (sys_generic.c has no socksys mods?)\n");
+ return(EINVAL);
+ }
+
+ switch (cmd) {
+
+ case SS_SIOCSOCKSYS: /* ss syscall */
+ return ss_syscall(arg, p);
+
+ /* NIOCxx: These ioctls are really just integers
+ * (no other information to go on).
+ */
+
+ case NIOCSETDOMNAM: {
+ struct sgdomarg domargs;
+
+ if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
+ return(error);
+
+ arg = (caddr_t)&domargs;
+ SYSCALL_N(SYS_setdomainname, 0, 0);
+ break;
+ }
+
+ case NIOCGETDOMNAM: {
+ struct sgdomarg domargs;
+
+ if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&domargs, sizeof(struct sgdomarg)))
+ return(error);
+
+ arg = (caddr_t)&domargs;
+ SYSCALL_N(SYS_getdomainname, 0, 0);
+ break;
+ }
+
+ case NIOCLSTAT: {
+ struct lstatarg st;
+
+ if(error = copyin((caddr_t)*((caddr_t *)arg), (caddr_t)&st, sizeof(struct lstatarg)))
+ return(error);
+
+ /* DO WE HAVE A FOREIGN LSTAT */
+/* return mumbo_lstat(st.fname, st.statb); */
+ return (EINVAL);
+ }
+
+ case NIOCNFSD:
+ case NIOCOLDGETFH:
+ case NIOCASYNCD:
+ case NIOCCLNTHAND:
+ case NIOCEXPORTFS:
+ case NIOCGETFH:
+ return (EINVAL);
+
+
+ case SS_IF_UNITSEL: /* set unit number */
+ case SS_SIOCXPROTO: /* empty proto table */
+
+ case SS_SIOCIFDETACH: /* detach interface */
+ case SS_SIOCGENPSTATS: /* get ENP stats */
+
+ case SS_SIOCSIFNAME: /* set interface name */
+ case SS_SIOCGIFONEP: /* get one-packet params */
+ case SS_SIOCSIFONEP: /* set one-packet params */
+
+ case SS_SIOCPROTO: /* link proto */
+ case SS_SIOCX25XMT:
+ case SS_SIOCX25RCV:
+ case SS_SIOCX25TBL:
+
+ printf("sockioctl: [%d] unsupported ioctl 0x%x , 0x%lx\n",
+ p->p_pid,
+ cmd, (unsigned long)arg);
+ return (EINVAL);
+
+ default:
+ printf("sockioctl: [%d] unknown ioctl 0x%x , 0x%lx\n",
+ p->p_pid,
+ cmd, (unsigned long)arg);
+ return (EINVAL);
+ }
+ IBCS2_MAGIC_RETURN;
+}
+
+
+int sockopen(dev, mode, devtype, p)
+ dev_t dev;
+ int mode;
+ int devtype;
+ struct proc *p;
+{
+
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("sockopen: [%d] 0x%x\n", p->p_pid, dev);
+#endif /* SS_DEBUG */
+
+ /* minor = 0 is the socksys device itself. No special handling
+ * will be needed as it is controlled by the application
+ * via ioctls.
+ */
+ if (minor(dev) == 0)
+ return 0;
+
+ /* minor = 1 is the spx device. This is the client side of a
+ * streams pipe to the X server. Under SCO and friends
+ * the library code messes around setting the connection
+ * up itself. We do it ourselves - this means we don't
+ * need to worry about the implementation of the server
+ * side (/dev/X0R - which must exist but can be a link
+ * to /dev/null) nor do we need to actually implement
+ * getmsg/putmsg.
+ */
+{ /* SPX */
+ int fd, error, args[3];
+ int retval[2];
+#define SUN_LEN(su) \
+ (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) + 1
+ struct sockaddr_un *Xaddr = (struct sockaddr_un *)UA_ALLOC();
+ retval[0] = retval[1] = 0;
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("sockopen: SPX: [%d] opening\n", p->p_pid);
+#endif /* SS_DEBUG */
+
+ /* Grab a socket. */
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("sockopen: SPX: [%d] get a unix domain socket\n",
+ p->p_pid);
+#endif /* SS_DEBUG */
+ args[0] = AF_UNIX;
+ args[1] = SOCK_STREAM;
+ args[2] = 0;
+ error = SYSCALLX(SYS_socket, args);
+ if (error)
+ return error;
+ fd = retval[0];
+ if(fd < 1) {
+ printf("sockopen: SPX: [%d] unexpected fd of %d\n",
+ p->p_pid, fd);
+ return(EOPNOTSUPP); /* MRL whatever */
+ }
+
+ /* Connect the socket to X. */
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("sockopen: SPX: [%d] connect to /tmp/X11-unix/X0\n",
+ p->p_pid);
+#endif /* SS_DEBUG */
+ args[0] = fd;
+ Xaddr->sun_family = AF_UNIX;
+ copyout("/tmp/.X11-unix/X0", Xaddr->sun_path, 18);
+ Xaddr->sun_len = SUN_LEN(Xaddr);
+ args[1] = (int)Xaddr;
+ args[2] = sizeof(struct sockaddr_un);
+ error = SYSCALLX(SYS_connect, args);
+ if (error) {
+ (void)SYSCALLX(SYS_close, &fd);
+ return error;
+ }
+
+ put_socket_fops(p,fd);
+
+ return 0;
+} /* SPX */
+}
+
+
+int sockclose(dev, flag, mode, p)
+ dev_t dev;
+ int flag;
+ int mode;
+ struct proc *p;
+{
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("sockclose: [%d] 0x%x\n", p->p_pid, dev);
+#endif /* SS_DEBUG */
+ return(0);
+}
+
+static
+int ss_fop_close(struct file *fp, struct proc *p)
+{
+
+#ifdef SS_DEBUG
+int fd;
+struct filedesc *fdp;
+
+ if(ss_debug){
+ fdp = p->p_fd;
+ fd = -1;
+ while(++fd < NOFILE)
+ if ( fp == fdp->fd_ofiles[fd] )
+ break;
+ printf("ss_fop_close: [%d] fd=%d ", p->p_pid, fd);
+ }
+#endif /* SS_DEBUG */
+
+ if(fp->f_type == DTYPE_SOCKET) {
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("is a socket\n");
+#endif /* SS_DEBUG */
+ return(close_s(fp, p));
+ }
+ else {
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("is not a socket\n");
+#endif /* SS_DEBUG */
+ return(ENOTSOCK);
+ }
+}
+
+void put_socket_fops(struct proc *p, int fd)
+{
+struct filedesc *fdp;
+struct file *fp;
+
+ fdp = p->p_fd;
+ fp = fdp->fd_ofiles[fd];
+ if (ss_socket_fops.fo_ioctl != fp->f_ops->fo_ioctl) {
+ bcopy(fp->f_ops, &ss_socket_fops, sizeof(struct fileops));
+ ioctl_s = ss_socket_fops.fo_ioctl; /* save standard ioctl */
+ close_s = ss_socket_fops.fo_close; /* save standard close */
+ ss_socket_fops.fo_ioctl = ss_fop_ioctl;
+ ss_socket_fops.fo_close = ss_fop_close;
+ }
+ fp->f_ops = &ss_socket_fops;
+
+ return;
+}
+
+int ss_SYSCALL(n,convert_arg,indicator,arg,p,retval)
+ int n; /* syscall ordinal */
+ int convert_arg; /* if not 0, argument to convert */
+ int indicator; /* type of argument to convert */
+ int *arg; /* address of alien arg */
+ struct proc *p;
+ int *retval;
+{
+int error;
+int rc;
+
+ if(convert_arg){
+ if(rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
+ indicator,
+ SS_ALIEN_TO_NATIVE))
+ return(rc);
+
+ error = (*sysent[n].sy_call)(p, arg + 1, retval);
+ rc = ss_convert_struct( (caddr_t)*(arg + convert_arg),
+ indicator,
+ SS_NATIVE_TO_ALIEN);
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_SYSCALL: [%d] error=%d, rc=%d\n",
+ p->p_pid, error, rc);
+#endif /* SS_DEBUG */
+ }
+ else {
+ rc = 0;
+ error = (*sysent[n].sy_call)(p, arg + 1, retval);
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_SYSCALL: [%d] error=%d\n",p->p_pid, error);
+#endif /* SS_DEBUG */
+ }
+
+ return(error ? error : rc);
+}
+
+int ss_IOCTL(fp, cmd, arg, p)
+ struct file *fp;
+ int cmd;
+ int *arg; /* address of alien arg */
+ struct proc *p;
+{
+int error, rc;
+int these[2];
+char cmd_type;
+int cmd_ordinal;
+int indicator;
+
+ cmd_type = (cmd >> 8) & 0xff;
+ cmd_ordinal = cmd & 0xff;
+ these[0] = cmd_type;
+ these[1] = cmd_ordinal;
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_IOCTL: calling ss_convert with %d(%c) %d\n",
+ these[0],these[0],these[1]);
+#endif /* SS_DEBUG */
+ indicator = ss_convert( struct_whatevers, these, 0);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_IOCTL: ss_convert returns indicator %d\n",indicator);
+#endif /* SS_DEBUG */
+ if(indicator){
+ error = ss_convert_struct((caddr_t)*(arg + 2),
+ indicator,
+ SS_ALIEN_TO_NATIVE);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_IOCTL: ss_convert_struct returns %d\n",error);
+#endif /* SS_DEBUG */
+ if(error)
+ return(error);
+ /* change len in ioctl now - in the general case */
+ error = ioctl_s(fp, cmd, (caddr_t)arg, p);
+ rc = ss_convert_struct( (caddr_t)*(arg + 2),
+ indicator,
+ SS_NATIVE_TO_ALIEN);
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_IOCTL: [%d] error=%d, rc=%d\n",p->p_pid,
+ error, rc);
+#endif /* SS_DEBUG */
+ }
+ else {
+ rc = 0;
+ error = ioctl_s(fp, cmd, (caddr_t)arg, p);
+#ifdef SS_DEBUG
+ if(ss_debug)
+ printf("ss_IOCTL: [%d] error=%d\n",p->p_pid, error);
+#endif /* SS_DEBUG */
+ }
+
+ return(error ? error : rc);
+}
+
+
+struct ss_socketopt_args {
+ int s;
+ int level;
+ int name;
+ caddr_t val;
+ int valsize;
+};
+
+int
+ss_setsockopt(arg, ret, p)
+ struct ss_socketopt_args *arg;
+ int *ret;
+ struct proc *p;
+{
+ int error, optname;
+ int retval[2];
+
+ if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
+ return (ENOPROTOOPT);
+
+ optname = ss_convert(sopt_whatevers, &arg->name, 0);
+
+ switch (optname) {
+
+ case SO_ACCEPTCONN:
+ case SO_BROADCAST:
+ case SO_DEBUG:
+ case SO_DONTROUTE:
+ case SO_LINGER:
+ case SO_KEEPALIVE:
+ case SO_OOBINLINE:
+ case SO_RCVBUF:
+ case SO_RCVLOWAT:
+ case SO_RCVTIMEO:
+ case SO_REUSEADDR:
+ case SO_SNDBUF:
+ case SO_SNDLOWAT:
+ case SO_SNDTIMEO:
+ case SO_USELOOPBACK:
+ error = SYSCALLX(SYS_setsockopt, arg);
+ *ret = retval[0];
+ *(ret + 1) = retval[1];
+ return(error);
+
+ case SO_ERROR:
+ case SO_IMASOCKET:
+ case SO_NO_CHECK:
+ case SO_ORDREL:
+ case SO_PRIORITY:
+ case SO_PROTOTYPE:
+ case SO_TYPE:
+ return (ENOPROTOOPT);
+
+ }
+
+ return (ENOPROTOOPT);
+}
+
+
+int
+ss_getsockopt(arg, ret, p)
+ struct ss_socketopt_args *arg;
+ int *ret;
+ struct proc *p;
+{
+ int error, optname;
+ int retval[2];
+
+ if (arg->level != 0xffff) /* FreeBSD, SCO and ? */
+ return (ENOPROTOOPT);
+
+ optname = ss_convert(sopt_whatevers, &arg->name, 0);
+
+ switch (optname) {
+
+ case SO_ACCEPTCONN:
+ case SO_BROADCAST:
+ case SO_DEBUG:
+ case SO_DONTROUTE:
+ case SO_ERROR:
+ case SO_KEEPALIVE:
+ case SO_LINGER:
+ case SO_OOBINLINE:
+ case SO_RCVBUF:
+ case SO_RCVLOWAT:
+ case SO_RCVTIMEO:
+ case SO_REUSEADDR:
+ case SO_SNDBUF:
+ case SO_SNDLOWAT:
+ case SO_SNDTIMEO:
+ case SO_TYPE:
+ case SO_USELOOPBACK:
+ error = SYSCALLX(SYS_getsockopt, arg);
+ *ret = retval[0];
+ *(ret + 1) = retval[1];
+ return(error);
+
+
+ case SO_PROTOTYPE: {
+ int value = 0;
+
+ error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
+ return(error);
+ }
+
+
+ case SO_IMASOCKET: {
+ int value = 1;
+
+ error = copyout((caddr_t)&value, (caddr_t)arg->s, sizeof(int));
+ return(error);
+ }
+
+ case SO_NO_CHECK:
+ case SO_ORDREL:
+ case SO_PRIORITY:
+ return (ENOPROTOOPT);
+ }
+
+ return (ENOPROTOOPT);
+}
+
+#define SS_CONVERT
+int system_type = SS_FREEBSD; /* FreeBSD */
+
+int
+ss_convert(what, this, otherwise)
+ struct whatever **what;
+ int *this;
+ int otherwise;
+{
+ struct whatever *specific;
+
+ if(!(specific = what[system_type]))
+ return *this;
+
+ for (; specific->from != -1; specific++)
+ if(specific->from <= *this && *this <= specific->to)
+ if(specific->from == specific->to){
+ if(specific->more){
+ specific = specific->more;
+ this++;
+ continue;
+ }
+ else {
+ return((int)specific->conversion);
+ }
+ }
+ else {
+ return(specific->conversion ? (
+ specific->all_the_same ? (int)specific->conversion : specific->conversion[*this - specific->from] ) : *this);
+ }
+
+ return otherwise;
+}
+
+/* Returns 0 - no conversion, no pointer modification
+ 1 - converted, relevant pointer modification
+ -1 - error
+ */
+int
+ss_convert_struct(alien, indicator, direction)
+ char *alien;
+ int indicator;
+ int direction;
+{
+int error, len;
+
+ switch (system_type) {
+
+ case SS_FREEBSD:
+ return(0);
+ case SS_SYSVR4:
+ case SS_SYSVR3:
+ case SS_SCO_32:
+ case SS_WYSE_321:
+ case SS_ISC:
+ case SS_LINUX:
+
+ switch(direction){
+
+ case SS_ALIEN_TO_NATIVE:
+
+ error = ss_atn(alien, indicator);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_convert: ATN ss_atn error %d\n",error);
+#endif /* SS_DEBUG */
+ return(error);
+
+ case SS_NATIVE_TO_ALIEN:
+
+ error = ss_nta(alien, indicator);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_convert: NTA ss_nta error %d\n",error);
+#endif /* SS_DEBUG */
+ return(error);
+
+ }
+
+ default:
+
+ printf("ss_convert_struct: not expecting system_type %d\n", system_type);
+ break;
+
+ }
+ return(EINVAL);
+}
+
+/* note sockaddr_un linux unsigned short fam, 108 path
+ BSD uchar , uchar 104 */
+int
+ss_atn(alien, indicator)
+ char *alien;
+ int indicator;
+{
+int error;
+
+ switch (indicator) {
+
+ case SS_STRUCT_ARPREQ:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_IFCONF:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_IFREQ:
+ /* length OK - more unions - function dependent */
+ return(0);
+
+ case SS_STRUCT_ORTENTRY:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_SOCKADDR:{
+ struct native_hdr {
+ u_char len;
+ u_char family;
+ };
+ union hdr_part {
+ struct native_hdr native;
+ u_short alien_family;
+ } hdr;
+
+ if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
+ return(error);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_atn:copyin 0x%x\n",hdr.alien_family);
+#endif /* SS_DEBUG */
+
+ if( hdr.alien_family < AF_MAX){
+ hdr.native.family = hdr.alien_family >> 8; /* 386 endianess */
+ /* OR LEN FOM A PARAM ? */
+ hdr.native.len = sizeof(struct sockaddr);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_atn:copyout 0x%x\n",hdr.alien_family);
+#endif /* SS_DEBUG */
+ error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
+ return(error);
+ }
+ else {
+ printf("ss_atn: sa_family = %d\n", hdr.alien_family);
+ return(EINVAL);
+ }
+
+ }
+
+ case SS_STRUCT_SOCKNEWPROTO:
+ /* don't have */
+ printf("ss_atn: not expecting SS_STRUCT_SOCKNEWPROTO\n");
+ return(EINVAL);
+
+ default:
+ printf("ss_atn: not expecting case %d\n",indicator);
+ return(EINVAL);
+
+ }
+}
+
+/* note sockaddr_un linux unsigned short fam, 108 path
+ BSD uchar , uchar 104 */
+int
+ss_nta(alien, indicator)
+ char *alien;
+ int indicator;
+{
+int error;
+
+ switch (indicator) {
+
+ case SS_STRUCT_ARPREQ:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_IFCONF:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_IFREQ:
+ /* length OK - more unions - function dependent */
+ return(0);
+
+ case SS_STRUCT_ORTENTRY:
+ /* compatible */
+ return(0);
+
+ case SS_STRUCT_SOCKADDR:{
+ struct native_hdr {
+ u_char len;
+ u_char family;
+ };
+ union hdr_part {
+ struct native_hdr native;
+ u_short alien_family;
+ } hdr;
+
+ if(error = copyin((caddr_t)alien,(caddr_t)&hdr,sizeof(hdr)))
+ return(error);
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_nta:copyin 0x%x\n",hdr.alien_family);
+#endif /* SS_DEBUG */
+ hdr.alien_family = hdr.native.family;
+#ifdef SS_DEBUG
+ if(ss_debug > 1)
+ printf("ss_nta:copyout 0x%x\n",hdr.alien_family);
+#endif /* SS_DEBUG */
+ error = copyout((caddr_t)&hdr,(caddr_t)alien,sizeof(hdr));
+ return(error);
+ }
+
+ case SS_STRUCT_SOCKNEWPROTO:
+ /* don't have */
+ printf("ss_nta: not expecting SS_STRUCT_SOCKNEWPROTO\n");
+ return(EINVAL);
+
+ default:
+ printf("ss_nta: not expecting case %d\n",indicator);
+ return(EINVAL);
+
+ }
+}
diff --git a/sys/i386/ibcs2/ibcs2_socksys.h b/sys/i386/ibcs2/ibcs2_socksys.h
new file mode 100644
index 000000000000..11a1b20231ab
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_socksys.h
@@ -0,0 +1,398 @@
+/*-
+ * Copyright (c) 1994 Mostyn Lewis
+ * All rights reserved.
+ *
+ * This software is based on code which is:
+ * Copyright (c) 1994 Mike Jagdis (jaggy@purplet.demon.co.uk)
+ *
+ * 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: ibcs2_socksys.h,v 1.2 1994/10/13 23:10:58 sos Exp $
+ */
+
+#define SS_DEBUG
+
+struct ss_call {
+ int arg[7];
+};
+
+/* Alien socket */
+struct alien_sockaddr {
+ unsigned short sa_family; /* address family, AF_xxx */
+ char sa_data[14]; /* 14 bytes of protocol address */
+};
+
+struct alien_in_addr {
+ unsigned long int s_addr;
+};
+
+#define __ALIEN_SOCK_SIZE__ 16 /* sizeof(struct alien_sockaddr)*/
+struct alien_sockaddr_in {
+ short int sin_family; /* Address family */
+ unsigned short int sin_port; /* Port number */
+ struct alien_in_addr sin_addr; /* Internet address */
+ unsigned char __filling[__ALIEN_SOCK_SIZE__ - sizeof(short int) -
+ sizeof(unsigned short int) - sizeof(struct alien_in_addr)];
+};
+
+struct sgdomarg {
+ char *name;
+ int namelen;
+};
+
+struct lstatarg {
+ char *fname;
+ void *statb;
+};
+
+struct socknewproto {
+ int family; /* address family (AF_INET, etc.) */
+ int type; /* protocol type (SOCK_STREAM, etc.) */
+ int proto; /* per family proto number */
+ dev_t dev; /* major/minor to use (must be a clone) */
+ int flags; /* protosw flags */
+};
+
+/* System type ordinals */
+#define SS_FREEBSD 0
+#define SS_SYSVR4 1
+#define SS_SYSVR3 2
+#define SS_SCO_32 3
+#define SS_WYSE_321 4
+#define SS_ISC 5
+#define SS_LINUX 6
+
+
+/* Socksys macros */
+#define IOCTL(cmd) \
+ if(error = ss_IOCTL(fp, cmd, arg, p))\
+ return(error);
+#define SYSCALL(number,conv_arg,indicator) \
+ if(error = ss_SYSCALL(number,conv_arg,indicator,arg,p,retval))\
+ return(error);
+#define SYSCALL_N(number,conv_arg,indicator) \
+ arg = (caddr_t)(((int *)arg) - 1);\
+ if(error = ss_SYSCALL(number,conv_arg,indicator,arg,p,retval))\
+ return(error);
+#define SYSCALLX(number,arg) (*sysent[number].sy_call)(p, (caddr_t)arg, retval)
+#define SYSCALL_RETURN(number) SYSCALL(number) ; IBCS2_MAGIC_RETURN
+
+/* Socksys commands */
+#define CMD_SO_ACCEPT 1
+#define CMD_SO_BIND 2
+#define CMD_SO_CONNECT 3
+#define CMD_SO_GETPEERNAME 4
+#define CMD_SO_GETSOCKNAME 5
+#define CMD_SO_GETSOCKOPT 6
+#define CMD_SO_LISTEN 7
+#define CMD_SO_RECV 8
+#define CMD_SO_RECVFROM 9
+#define CMD_SO_SEND 10
+#define CMD_SO_SENDTO 11
+#define CMD_SO_SETSOCKOPT 12
+#define CMD_SO_SHUTDOWN 13
+#define CMD_SO_SOCKET 14
+#define CMD_SO_SELECT 15
+#define CMD_SO_GETIPDOMAIN 16
+#define CMD_SO_SETIPDOMAIN 17
+#define CMD_SO_ADJTIME 18
+#define CMD_SO_SETREUID 19
+#define CMD_SO_SETREGID 20
+#define CMD_SO_GETTIME 21
+#define CMD_SO_SETTIME 22
+#define CMD_SO_GETITIMER 23
+#define CMD_SO_SETITIMER 24
+
+#define CMD_SO_SS_DEBUG 255
+
+/* socksys ioctls */
+#define SS_IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
+#define SS_IOC_VOID 0x20000000 /* no parameters */
+#define SS_IOC_OUT 0x40000000 /* copy out parameters */
+#define SS_IOC_IN 0x80000000 /* copy in parameters */
+#define SS_IOC_INOUT (SS_IOC_IN|SS_IOC_OUT)
+
+#define SS_IO(x,y) (SS_IOC_VOID|(x<<8)|y)
+#define SS_IOR(x,y,t) (SS_IOC_OUT|((sizeof(t)&SS_IOCPARM_MASK)<<16)|(x<<8)|y)
+#define SS_IOW(x,y,t) (SS_IOC_IN|((sizeof(t)&SS_IOCPARM_MASK)<<16)|(x<<8)|y)
+#define SS_IOWR(x,y,t) (SS_IOC_INOUT|((sizeof(t)&SS_IOCPARM_MASK)<<16)|(x<<8)|y)
+
+#define SS_SIOCSHIWAT SS_IOW ('S', 1, int) /* set high watermark */
+#define SS_SIOCGHIWAT SS_IOR ('S', 2, int) /* get high watermark */
+#define SS_SIOCSLOWAT SS_IOW ('S', 3, int) /* set low watermark */
+#define SS_SIOCGLOWAT SS_IOR ('S', 4, int) /* get low watermark */
+#define SS_SIOCATMARK SS_IOR ('S', 5, int) /* at oob mark? */
+#define SS_SIOCSPGRP SS_IOW ('S', 6, int) /* set process group */
+#define SS_SIOCGPGRP SS_IOR ('S', 7, int) /* get process group */
+#define SS_FIONREAD SS_IOR ('S', 8, int)
+#define SS_FIONBIO SS_IOW ('S', 9, int)
+#define SS_FIOASYNC SS_IOW ('S', 10, int)
+#define SS_SIOCPROTO SS_IOW ('S', 11, struct socknewproto) /* link proto */
+#define SS_SIOCGETNAME SS_IOR ('S', 12, struct sockaddr) /* getsockname */
+#define SS_SIOCGETPEER SS_IOR ('S', 13,struct sockaddr) /* getpeername */
+#define SS_IF_UNITSEL SS_IOW ('S', 14, int)/* set unit number */
+#define SS_SIOCXPROTO SS_IO ('S', 15) /* empty proto table */
+
+#define SS_SIOCADDRT SS_IOW ('R', 9, struct ortentry) /* add route */
+#define SS_SIOCDELRT SS_IOW ('R', 10, struct ortentry)/* delete route */
+
+#define SS_SIOCSIFADDR SS_IOW ('I', 11, struct ifreq)/* set ifnet address */
+#define SS_SIOCGIFADDR SS_IOWR('I', 12, struct ifreq)/* get ifnet address */
+#define SS_SIOCSIFDSTADDR SS_IOW ('I', 13, struct ifreq)/* set p-p address */
+#define SS_SIOCGIFDSTADDR SS_IOWR('I', 14,struct ifreq) /* get p-p address */
+#define SS_SIOCSIFFLAGS SS_IOW ('I', 15, struct ifreq)/* set ifnet flags */
+#define SS_SIOCGIFFLAGS SS_IOWR('I', 16, struct ifreq)/* get ifnet flags */
+#define SS_SIOCGIFCONF SS_IOWR('I', 17, struct ifconf)/* get ifnet list */
+
+#define SS_SIOCSIFMTU SS_IOW ('I', 21, struct ifreq)/* get if_mtu */
+#define SS_SIOCGIFMTU SS_IOWR('I', 22, struct ifreq)/* set if_mtu */
+
+#define SS_SIOCIFDETACH SS_IOW ('I', 26, struct ifreq)/* detach interface */
+#define SS_SIOCGENPSTATS SS_IOWR('I', 27, struct ifreq)/* get ENP stats */
+
+#define SS_SIOCX25XMT SS_IOWR('I', 29, struct ifreq)/* start a slp proc in x25if */
+#define SS_SIOCX25RCV SS_IOWR('I', 30, struct ifreq)/* start a slp proc in x25if */
+#define SS_SIOCX25TBL SS_IOWR('I', 31, struct ifreq)/* xfer lun table to kernel */
+
+#define SS_SIOCGIFBRDADDR SS_IOWR('I', 32, struct ifreq)/* get broadcast addr */
+#define SS_SIOCSIFBRDADDR SS_IOW ('I', 33, struct ifreq)/* set broadcast addr */
+#define SS_SIOCGIFNETMASK SS_IOWR('I', 34, struct ifreq)/* get net addr mask */
+#define SS_SIOCSIFNETMASK SS_IOW ('I', 35, struct ifreq)/* set net addr mask */
+#define SS_SIOCGIFMETRIC SS_IOWR('I', 36, struct ifreq)/* get IF metric */
+#define SS_SIOCSIFMETRIC SS_IOW ('I', 37, struct ifreq)/* set IF metric */
+
+#define SS_SIOCSARP SS_IOW ('I', 38, struct arpreq)/* set arp entry */
+#define SS_SIOCGARP SS_IOWR('I', 39, struct arpreq)/* get arp entry */
+#define SS_SIOCDARP SS_IOW ('I', 40, struct arpreq)/* delete arp entry */
+
+#define SS_SIOCSIFNAME SS_IOW ('I', 41, struct ifreq)/* set interface name */
+#define SS_SIOCGIFONEP SS_IOWR('I', 42, struct ifreq)/* get 1-packet parms */
+#define SS_SIOCSIFONEP SS_IOW ('I', 43, struct ifreq)/* set 1-packet parms */
+
+#define SS_SIOCGENADDR SS_IOWR('I', 65, struct ifreq)/* Get ethernet addr */
+
+#define SS_SIOCSOCKSYS SS_IOW ('I', 66, struct ss_call)/* ss syscall */
+
+
+/*
+ * NFS/NIS has a pseudo device called /dev/nfsd which may accept ioctl
+ * calls. /dev/nfsd is linked to /dev/socksys.
+ */
+
+#define NIOCNFSD 1
+#define NIOCOLDGETFH 2
+#define NIOCASYNCD 3
+#define NIOCSETDOMNAM 4
+#define NIOCGETDOMNAM 5
+#define NIOCCLNTHAND 6
+#define NIOCEXPORTFS 7
+#define NIOCGETFH 8
+#define NIOCLSTAT 9
+
+
+/*
+ * noso
+ */
+
+#define SO_ORDREL 0xff02
+#define SO_IMASOCKET 0xff03
+#define SO_PROTOTYPE 0xff04
+/* Check below */
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+
+/*
+ * convert
+ */
+
+/* Structure conversion indicators */
+
+#define SS_STRUCT_ARPREQ 1
+#define SS_STRUCT_IFCONF 2
+#define SS_STRUCT_IFREQ 3
+#define SS_STRUCT_ORTENTRY 4
+#define SS_STRUCT_SOCKADDR 5
+#define SS_STRUCT_SOCKNEWPROTO 6
+
+#define SS_ALIEN_TO_NATIVE 1
+#define SS_NATIVE_TO_ALIEN 2
+
+struct whatever {
+ int from, to;
+ unsigned char *conversion;
+ unsigned char all_the_same;
+ struct whatever *more;
+};
+
+
+extern struct whatever *af_whatevers[];
+extern struct whatever *type_whatevers[];
+extern struct whatever *sopt_whatevers[];
+extern struct whatever *struct_whatevers[];
+
+extern int ss_convert(struct whatever **what, int *this, int otherwise);
+extern int ss_convert_struct(char *alien, int indicator, int direction);
+
+/*
+ * convert af
+ */
+
+
+static struct whatever af_whatevers_all[] = {
+ { 0, 2, NULL, 0, 0 },
+ { -1 }
+};
+
+
+struct whatever *af_whatevers[] = {
+ NULL, /* FreeBSD */
+ af_whatevers_all, /* SysVR4 */
+ af_whatevers_all, /* SysVR3 */
+ af_whatevers_all, /* SCO 3.2.[24] */
+ af_whatevers_all, /* Wyse Unix V/386 3.2.1 */
+ af_whatevers_all, /* ISC */
+ af_whatevers_all /* Linux */
+};
+
+/*
+ * convert sopt
+ */
+
+static struct whatever sopt_whatevers_all[] = {
+ { 0x0001, 0x0001, (char *)SO_DEBUG, 0, 0 },
+ { 0x0002, 0x0002, (char *)SO_ACCEPTCONN, 0, 0 },
+ { 0x0004, 0x0004, (char *)SO_REUSEADDR, 0, 0 },
+ { 0x0008, 0x0008, (char *)SO_KEEPALIVE, 0, 0 },
+ { 0x0010, 0x0010, (char *)SO_DONTROUTE, 0, 0 },
+ { 0x0020, 0x0020, (char *)SO_BROADCAST, 0, 0 },
+ { 0x0040, 0x0040, (char *)SO_USELOOPBACK, 0, 0 },
+ { 0x0080, 0x0080, (char *)SO_LINGER, 0, 0 },
+ { 0x0100, 0x0100, (char *)SO_OOBINLINE, 0, 0 },
+ { 0x0200, 0x0200, (char *)SO_ORDREL, 0, 0 },
+ { 0x0400, 0x0400, (char *)SO_IMASOCKET, 0, 0 },
+ { 0x1001, 0x1001, (char *)SO_SNDBUF, 0, 0 },
+ { 0x1002, 0x1001, (char *)SO_RCVBUF, 0, 0 },
+ { 0x1003, 0x1001, (char *)SO_SNDLOWAT, 0, 0 },
+ { 0x1004, 0x1001, (char *)SO_RCVLOWAT, 0, 0 },
+ { 0x1005, 0x1001, (char *)SO_SNDTIMEO, 0, 0 },
+ { 0x1006, 0x1001, (char *)SO_RCVTIMEO, 0, 0 },
+ { 0x1007, 0x1001, (char *)SO_ERROR, 0, 0 },
+ { 0x1008, 0x1001, (char *)SO_TYPE, 0, 0 },
+ { 0x1009, 0x1001, (char *)SO_PROTOTYPE, 0, 0 },
+ { -1 }
+};
+
+
+struct whatever *sopt_whatevers[] = {
+ NULL, /* FreeBSD */
+ sopt_whatevers_all, /* SysVR4 */
+ sopt_whatevers_all, /* SysVR3 */
+ sopt_whatevers_all, /* SCO 3.2.[24] */
+ sopt_whatevers_all, /* Wyse Unix V/386 3.2.1 */
+ sopt_whatevers_all, /* ISC */
+ sopt_whatevers_all /* Linux */
+};
+
+/*
+ * convert struct
+ */
+
+static struct whatever struct_whatever_typeI_ranges[] = {
+ { 11, 16, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* OK */
+ { 17, 17, (char *)SS_STRUCT_IFCONF , 1, 0 }, /* OK */
+ { 21, 22, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* SIZE OK */
+ { 26, 27, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* SIZE OK */
+ { 29, 37, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* SIZE OK */
+ { 38, 40, (char *)SS_STRUCT_ARPREQ , 1, 0 }, /* OK */
+ { 41, 43, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* SIZE OK */
+ { 65, 65, (char *)SS_STRUCT_IFREQ , 1, 0 }, /* SIZE OK */
+ { -1 }
+};
+
+static struct whatever struct_whatever_typeR_ranges[] = {
+ { 9, 10, (char *)SS_STRUCT_ORTENTRY , 1, 0 }, /* SIZE OK */
+ { -1 }
+};
+
+static struct whatever struct_whatever_typeS_ranges[] = {
+ { 1, 10, 0 , 1, 0 },
+ { 11, 11, (char *)SS_STRUCT_SOCKNEWPROTO, 1, 0 }, /* NO SUPPORT */
+ { 12, 13, (char *)SS_STRUCT_SOCKADDR , 1, 0 }, /* len and family */
+ { 14, 15, 0 , 1, 0 },
+ { -1 }
+};
+
+static struct whatever struct_whatevers_all[] = {
+ { 'I', 'I', 0, 0, struct_whatever_typeI_ranges },
+ { 'R', 'R', 0, 0, struct_whatever_typeR_ranges },
+ { 'S', 'S', 0, 0, struct_whatever_typeS_ranges },
+ { -1 }
+};
+
+struct whatever *struct_whatevers[] = {
+ struct_whatevers_all, /* FreeBSD */
+ struct_whatevers_all, /* SysVR4 */
+ struct_whatevers_all, /* SysVR3 */
+ struct_whatevers_all, /* SCO 3.2.[24] */
+ struct_whatevers_all, /* Wyse Unix V/386 3.2.1 */
+ struct_whatevers_all, /* ISC */
+ struct_whatevers_all /* Linux */
+};
+
+int ss_struct_native_sizes[] = {
+ sizeof(struct arpreq),
+ sizeof(struct ifconf),
+ sizeof(struct ifreq),
+ sizeof(struct rtentry),
+ sizeof(struct sockaddr),
+ sizeof(struct socknewproto)
+};
+
+/*
+ * convert type
+ */
+
+static char type_conversion_SysVr4_range1[] = {
+ SOCK_DGRAM,
+ SOCK_STREAM,
+ 0,
+ SOCK_RAW,
+ SOCK_RDM,
+ SOCK_SEQPACKET
+};
+
+static struct whatever type_whatevers_SysVr4[] = {
+ { 1, 6, type_conversion_SysVr4_range1, 0 },
+ { -1 }
+};
+
+struct whatever *type_whatevers[] = {
+ NULL, /* FreeBSD */
+ type_whatevers_SysVr4, /* SysVR4 */
+ NULL, /* SysVR3 */
+ NULL, /* SCO 3.2.[24] */
+ NULL, /* Wyse Unix V/386 3.2.1 */
+ NULL, /* ISC */
+ NULL /* Linux */
+};
diff --git a/sys/i386/ibcs2/ibcs2_stats.c b/sys/i386/ibcs2/ibcs2_stats.c
new file mode 100644
index 000000000000..749c632e4f28
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_stats.c
@@ -0,0 +1,285 @@
+/*-
+ * Copyright (c) 1994 Sean Eric Fagan
+ * Copyright (c) 1994 Søren Schmidt
+ * All rights reserved.
+ *
+ * Copyright (c) 1989 The Regents of the University of California.
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: ibcs2_stats.c,v 1.11 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/mount.h>
+#include <sys/namei.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/vnode.h>
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_map.h>
+#include <vm/vm_kern.h>
+
+struct ibcs2_stat {
+ ibcs2_dev_t stat_dev;
+ ibcs2_ino_t stat_ino;
+ ibcs2_mode_t stat_mode;
+ ibcs2_nlink_t stat_nlink;
+ ibcs2_uid_t stat_uid;
+ ibcs2_gid_t stat_gid;
+ ibcs2_dev_t stat_rdev;
+ ibcs2_size_t stat_size;
+ ibcs2_time_t stat_atime;
+ ibcs2_time_t stat_mtime;
+ ibcs2_time_t stat_ctime;
+};
+
+struct ibcs2_stat_args {
+ char *path;
+ struct ibcs2_stat *buf;
+};
+
+static int
+stat_copyout(struct stat *buf, void *ubuf)
+{
+ struct ibcs2_stat tbuf;
+
+ tbuf.stat_dev = buf->st_dev;
+ tbuf.stat_ino = buf->st_ino;
+ tbuf.stat_mode = buf->st_mode;
+ tbuf.stat_nlink = buf->st_nlink;
+ tbuf.stat_uid = buf->st_uid;
+ tbuf.stat_gid = buf->st_gid;
+ tbuf.stat_rdev = buf->st_rdev;
+ tbuf.stat_size = buf->st_size;
+ tbuf.stat_atime = buf->st_atime;
+ tbuf.stat_mtime = buf->st_mtime;
+ tbuf.stat_ctime = buf->st_ctime;
+ return copyout(&tbuf, ubuf, sizeof(tbuf));
+}
+
+int
+ibcs2_stat(struct proc *p, struct ibcs2_stat_args *args, int *retval)
+{
+ struct stat buf;
+ struct ibcs2_stat tbuf;
+ struct nameidata nd;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_STATS)
+ printf("IBCS2: 'stat' path=%s\n", args->path);
+
+ nd.ni_cnd.cn_nameiop = LOOKUP;
+ nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW;
+ nd.ni_cnd.cn_proc = curproc;
+ nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
+ nd.ni_segflg = UIO_USERSPACE;
+ nd.ni_dirp = args->path;
+ error = namei(&nd);
+
+ if (!error) {
+ error = vn_stat(nd.ni_vp, &buf, p);
+ vput(nd.ni_vp);
+ }
+
+ if (!error)
+ error = stat_copyout(&buf, args->buf);
+
+ return error;
+}
+
+int
+ibcs2_lstat(struct proc *p, struct ibcs2_stat_args *args, int *retval)
+{
+ struct stat buf;
+ struct ibcs2_stat tbuf;
+ struct nameidata nd;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_STATS)
+ printf("IBCS2: 'lstat' path=%s\n", args->path);
+ nd.ni_cnd.cn_nameiop = LOOKUP;
+ nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW;
+ nd.ni_cnd.cn_proc = curproc;
+ nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
+ nd.ni_segflg = UIO_USERSPACE;
+ nd.ni_dirp = args->path;
+ error = namei(&nd);
+
+ if (!error) {
+ error = vn_stat(nd.ni_vp, &buf, p);
+ vput(nd.ni_vp);
+ }
+
+ if (!error)
+ error = stat_copyout(&buf, args->buf);
+
+ return error;
+}
+
+struct ibcs2_fstat_args {
+ int fd;
+ struct ibcs2_stat *buf;
+};
+
+int
+ibcs2_fstat(struct proc *p, struct ibcs2_fstat_args *args, int *retval)
+{
+ struct ibcs2_stat tbuf;
+ struct filedesc *fdp = p->p_fd;
+ struct file *fp;
+ struct stat buf;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_STATS)
+ printf("IBCS2: 'fstat' fd=%d\n", args->fd);
+ if ((unsigned)args->fd >= fdp->fd_nfiles
+ || (fp = fdp->fd_ofiles[args->fd]) == NULL)
+ return EBADF;
+
+ switch (fp->f_type) {
+ case DTYPE_VNODE:
+ error = vn_stat((struct vnode *)fp->f_data, &buf, p);
+ break;
+
+ case DTYPE_SOCKET:
+ error = soo_stat((struct socket *)fp->f_data, &buf);
+ break;
+
+ default:
+ panic("IBCS2 fstat");
+ /*NOTREACHED*/
+ }
+ if (!error)
+ error = stat_copyout(&buf, args->buf);
+
+ return error;
+}
+
+struct ibcs2_statfs {
+ short f_fstyp;
+ long f_bsize;
+ long f_frsize;
+ long f_blocks;
+ long f_bfree;
+ long f_files;
+ long f_ffree;
+ char f_fname[6];
+ char f_fpack[6];
+};
+
+struct ibcs2_statfs_args {
+ char *path;
+ struct statfs *buf;
+ int len;
+ int fstyp;
+};
+
+int
+ibcs2_statfs(struct proc *p, struct ibcs2_statfs_args *args, int *retval)
+{
+ struct mount *mp;
+ struct nameidata *ndp;
+ struct statfs *sp;
+ struct nameidata nd;
+ struct ibcs2_statfs tmp;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_STATS)
+ printf("IBCS2: 'statfs' path=%s\n", args->path);
+ ndp = &nd;
+ ndp->ni_cnd.cn_nameiop = LOOKUP;
+ ndp->ni_cnd.cn_flags = FOLLOW;
+ ndp->ni_cnd.cn_proc = curproc;
+ ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
+ ndp->ni_segflg = UIO_USERSPACE;
+ ndp->ni_dirp = args->path;
+ if (error = namei(ndp))
+ return error;
+ mp = ndp->ni_vp->v_mount;
+ sp = &mp->mnt_stat;
+ vrele(ndp->ni_vp);
+ if (error = VFS_STATFS(mp, sp, p))
+ return error;
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ tmp.f_fstyp = sp->f_type;
+ tmp.f_bsize = sp->f_bsize;
+ tmp.f_frsize = sp->f_iosize;
+ tmp.f_blocks = sp->f_blocks;
+ tmp.f_bfree = sp->f_bfree;
+ tmp.f_ffree = sp->f_ffree;
+ tmp.f_files = sp->f_files;
+ bcopy (sp->f_mntonname, tmp.f_fname, 6);
+ bcopy (sp->f_mntfromname, tmp.f_fpack, 6);
+ return copyout((caddr_t)&tmp, (caddr_t)args->buf, args->len);
+}
+
+struct ibcs2_fstatfs_args {
+ int fd;
+ struct statfs *buf;
+};
+
+int
+ibcs2_fstatfs(struct proc *p, struct ibcs2_fstatfs_args *args, int *retval)
+{
+ struct file *fp;
+ struct mount *mp;
+ struct statfs *sp;
+ struct ibcs2_statfs tmp;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_STATS)
+ printf("IBCS2: 'fstatfs' fd=%d\n", args->fd);
+ if (error = getvnode(p->p_fd, args->fd, &fp))
+ return error;
+ mp = ((struct vnode *)fp->f_data)->v_mount;
+ sp = &mp->mnt_stat;
+ if (error = VFS_STATFS(mp, sp, p))
+ return error;
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ tmp.f_fstyp = sp->f_type;
+ tmp.f_bsize = sp->f_bsize;
+ tmp.f_frsize = sp->f_iosize;
+ tmp.f_blocks = sp->f_blocks;
+ tmp.f_bfree = sp->f_bfree;
+ tmp.f_ffree = sp->f_ffree;
+ tmp.f_files = sp->f_files;
+ bcopy (sp->f_mntonname, tmp.f_fname, 6);
+ bcopy (sp->f_mntfromname, tmp.f_fpack, 6);
+ return copyout((caddr_t)&tmp, (caddr_t)args->buf,
+ sizeof(struct statfs));
+}
diff --git a/sys/i386/ibcs2/ibcs2_sysent.c b/sys/i386/ibcs2/ibcs2_sysent.c
new file mode 100644
index 000000000000..1f1422d07e17
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_sysent.c
@@ -0,0 +1,500 @@
+/*-
+ * Copyright (c) 1994 Søren Schmidt
+ * Copyright (c) 1994 Sean Eric Fagan
+ * 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: ibcs2_sysent.c,v 1.14 1994/10/13 23:10:58 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signal.h>
+#include <sys/sysent.h>
+
+#define NERR 80 /* XXX must match sys/errno.h */
+
+/* errno conversion tables */
+int bsd_to_svr3_errno[NERR] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 45, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 11, 91, 92, 93, 94,
+ 95, 96,118, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108, 63,110,111,112,113,
+ 114,115, 31, 78,116,117,145, 11, 11, 11,
+ 0, 66, 0, 0, 0, 0, 0, 46, 89, 0,
+};
+
+/* function defines */
+int ibcs2_access();
+int ibcs2_advfs();
+int ibcs2_alarm();
+int ibcs2_break();
+int ibcs2_chdir();
+int ibcs2_chmod();
+int ibcs2_chown();
+int ibcs2_chroot();
+int ibcs2_cisc();
+int ibcs2_clocal();
+int ibcs2_close();
+int ibcs2_creat();
+int ibcs2_cxenix();
+int ibcs2_dup();
+int ibcs2_exec();
+int ibcs2_exece();
+int ibcs2_exit();
+int ibcs2_fcntl();
+int ibcs2_fork();
+int ibcs2_fstat();
+int ibcs2_fstatfs();
+int ibcs2_fsync();
+int ibcs2_getdents();
+int ibcs2_getgid();
+int ibcs2_getmsg();
+int ibcs2_getpid();
+int ibcs2_getuid();
+int ibcs2_gtime();
+int ibcs2_gtty();
+int ibcs2_ioctl();
+int ibcs2_kill();
+int ibcs2_libattach();
+int ibcs2_libdetach();
+int ibcs2_link();
+int ibcs2_lstat();
+int ibcs2_mkdir();
+int ibcs2_mknod();
+int ibcs2_msgsys();
+int ibcs2_nice();
+int ibcs2_nosys();
+int ibcs2_open();
+int ibcs2_pause();
+int ibcs2_pipe();
+int ibcs2_plock();
+int ibcs2_poll();
+int ibcs2_procids();
+int ibcs2_profil();
+int ibcs2_ptrace();
+int ibcs2_putmsg();
+int ibcs2_read();
+int ibcs2_readlink();
+int ibcs2_rfdebug();
+int ibcs2_rfstart();
+int ibcs2_rfstop();
+int ibcs2_rfsys();
+int ibcs2_rmdir();
+int ibcs2_rmount();
+int ibcs2_rumount();
+int ibcs2_secure();
+int ibcs2_seek();
+int ibcs2_semsys();
+int ibcs2_setgid();
+int ibcs2_setuid();
+int ibcs2_shmsys();
+int ibcs2_sigsys();
+int ibcs2_smount();
+int ibcs2_stat();
+int ibcs2_statfs();
+int ibcs2_stime();
+int ibcs2_stty();
+int ibcs2_sumount();
+int ibcs2_symlink();
+int ibcs2_sync();
+int ibcs2_sysacct();
+int ibcs2_sysfs();
+int ibcs2_sysi86();
+int ibcs2_times();
+int ibcs2_uadmin();
+int ibcs2_ulimit();
+int ibcs2_umask();
+int ibcs2_unadvfs();
+int ibcs2_unlink();
+int ibcs2_utime();
+int ibcs2_utssys();
+int ibcs2_wait();
+int ibcs2_write();
+int ibcs2_traceemu(); /* XXX */
+int sigreturn(); /* XXX */
+
+/* ibcs2 svr3 sysent table */
+struct sysent svr3_sysent[] =
+{
+ 0, ibcs2_nosys, /* 0 = indir */
+ 1, ibcs2_exit, /* 1 = exit */
+ 0, ibcs2_fork, /* 2 = fork */
+ 3, ibcs2_read, /* 3 = read */
+ 3, ibcs2_write, /* 4 = write */
+ 3, ibcs2_open, /* 5 = open */
+ 1, ibcs2_close, /* 6 = close */
+ 3, ibcs2_wait, /* 7 = wait */
+ 2, ibcs2_creat, /* 8 = creat */
+ 2, ibcs2_link, /* 9 = link */
+ 1, ibcs2_unlink, /* 10 = unlink */
+ 2, ibcs2_exec, /* 11 = exec */
+ 1, ibcs2_chdir, /* 12 = chdir */
+ 0, ibcs2_gtime, /* 13 = time */
+ 3, ibcs2_mknod, /* 14 = mknod */
+ 2, ibcs2_chmod, /* 15 = chmod */
+ 3, ibcs2_chown, /* 16 = chown */
+ 1, ibcs2_break, /* 17 = break */
+ 2, ibcs2_stat, /* 18 = stat */
+ 3, ibcs2_seek, /* 19 = seek */
+ 0, ibcs2_getpid, /* 20 = getpid */
+ 6, ibcs2_smount, /* 21 = mount */
+ 1, ibcs2_sumount, /* 22 = umount */
+ 1, ibcs2_setuid, /* 23 = setuid */
+ 0, ibcs2_getuid, /* 24 = getuid */
+ 1, ibcs2_stime, /* 25 = stime */
+ 4, ibcs2_ptrace, /* 26 = ptrace */
+ 1, ibcs2_alarm, /* 27 = alarm */
+ 2, ibcs2_fstat, /* 28 = fstat */
+ 0, ibcs2_pause, /* 29 = pause */
+ 2, ibcs2_utime, /* 30 = utime */
+ 2, ibcs2_stty, /* 31 = stty */
+ 2, ibcs2_gtty, /* 32 = gtty */
+ 2, ibcs2_access, /* 33 = access */
+ 1, ibcs2_nice, /* 34 = nice */
+ 4, ibcs2_statfs, /* 35 = statfs */
+ 0, ibcs2_sync, /* 36 = sync */
+ 2, ibcs2_kill, /* 37 = kill */
+ 4, ibcs2_fstatfs, /* 38 = fstatfs */
+ 1, ibcs2_procids, /* 39 = procids */
+ 5, ibcs2_cxenix, /* 40 = XENIX special system call */
+ 1, ibcs2_dup, /* 41 = dup */
+ 1, ibcs2_pipe, /* 42 = pipe */
+ 1, ibcs2_times, /* 43 = times */
+ 4, ibcs2_profil, /* 44 = prof */
+ 1, ibcs2_plock, /* 45 = proc lock */
+ 1, ibcs2_setgid, /* 46 = setgid */
+ 0, ibcs2_getgid, /* 47 = getgid */
+ 2, ibcs2_sigsys, /* 48 = signal */
+ 6, ibcs2_msgsys, /* 49 = IPC message */
+ 4, ibcs2_sysi86, /* 50 = i386-specific system call */
+ 1, ibcs2_sysacct, /* 51 = turn acct off/on */
+ 4, ibcs2_shmsys, /* 52 = shared memory */
+ 5, ibcs2_semsys, /* 53 = IPC semaphores */
+ 3, ibcs2_ioctl, /* 54 = ioctl */
+ 3, ibcs2_uadmin, /* 55 = uadmin */
+ 0, ibcs2_nosys, /* 56 = reserved for exch */
+ 3, ibcs2_utssys, /* 57 = utssys */
+ 1, ibcs2_fsync, /* 58 = fsync */
+ 3, ibcs2_exece, /* 59 = exece */
+ 1, ibcs2_umask, /* 60 = umask */
+ 1, ibcs2_chroot, /* 61 = chroot */
+ 3, ibcs2_fcntl, /* 62 = fcntl */
+ 2, ibcs2_ulimit, /* 63 = ulimit */
+ 0, ibcs2_nosys, /* 64 = nosys */
+ 0, ibcs2_nosys, /* 65 = nosys */
+ 0, ibcs2_nosys, /* 66 = nosys */
+ 0, ibcs2_nosys, /* 67 = file locking call */
+ 0, ibcs2_nosys, /* 68 = local system calls */
+ 0, ibcs2_nosys, /* 69 = inode open */
+ 4, ibcs2_advfs, /* 70 = advfs */
+ 1, ibcs2_unadvfs, /* 71 = unadvfs */
+ 4, ibcs2_rmount, /* 72 = rmount */
+ 1, ibcs2_rumount, /* 73 = rumount */
+ 5, ibcs2_rfstart, /* 74 = rfstart */
+ 0, ibcs2_nosys, /* 75 = not used */
+ 1, ibcs2_rfdebug, /* 76 = rfdebug */
+ 0, ibcs2_rfstop, /* 77 = rfstop */
+ 6, ibcs2_rfsys, /* 78 = rfsys */
+ 1, ibcs2_rmdir, /* 79 = rmdir */
+ 2, ibcs2_mkdir, /* 80 = mkdir */
+ 4, ibcs2_getdents, /* 81 = getdents */
+ 3, ibcs2_libattach, /* 82 = libattach */
+ 1, ibcs2_libdetach, /* 83 = libdetach */
+ 3, ibcs2_sysfs, /* 84 = sysfs */
+ 4, ibcs2_getmsg, /* 85 = getmsg */
+ 4, ibcs2_putmsg, /* 86 = putmsg */
+ 3, ibcs2_poll, /* 87 = poll */
+ 0, ibcs2_nosys, /* 88 = not used */
+ 6, ibcs2_secure, /* 89 = secureware */
+ 2, ibcs2_symlink, /* 90 = symlink */
+ 2, ibcs2_lstat, /* 91 = lstat */
+ 3, ibcs2_readlink, /* 92 = readlink */
+ 0, ibcs2_nosys, /* 93 = not used */
+ 0, ibcs2_nosys, /* 94 = not used */
+ 0, ibcs2_nosys, /* 95 = not used */
+ 0, ibcs2_nosys, /* 96 = not used */
+ 0, ibcs2_nosys, /* 97 = not used */
+ 0, ibcs2_nosys, /* 98 = not used */
+ 0, ibcs2_nosys, /* 99 = not used */
+ 0, ibcs2_nosys, /* 100 = not used */
+ 0, ibcs2_nosys, /* 101 = not used */
+ 0, ibcs2_nosys, /* 102 = not used */
+ 1, sigreturn, /* 103 = BSD sigreturn XXX */
+ 0, ibcs2_nosys, /* 104 = not used */
+ 5, ibcs2_cisc, /* 105 = ISC special */
+ 0, ibcs2_nosys, /* 106 = not used */
+ 0, ibcs2_nosys, /* 107 = not used */
+ 0, ibcs2_nosys, /* 108 = not used */
+ 0, ibcs2_nosys, /* 109 = not used */
+ 0, ibcs2_nosys, /* 110 = not used */
+ 0, ibcs2_nosys, /* 111 = not used */
+ 0, ibcs2_nosys, /* 112 = not used */
+ 0, ibcs2_nosys, /* 113 = not used */
+ 0, ibcs2_nosys, /* 114 = not used */
+ 0, ibcs2_nosys, /* 115 = not used */
+ 0, ibcs2_nosys, /* 116 = not used */
+ 0, ibcs2_nosys, /* 117 = not used */
+ 0, ibcs2_nosys, /* 118 = not used */
+ 0, ibcs2_nosys, /* 119 = not used */
+ 0, ibcs2_nosys, /* 120 = not used */
+ 0, ibcs2_nosys, /* 121 = not used */
+ 0, ibcs2_nosys, /* 122 = not used */
+ 0, ibcs2_nosys, /* 123 = not used */
+ 0, ibcs2_nosys, /* 124 = not used */
+ 0, ibcs2_nosys, /* 125 = not used */
+ 1, ibcs2_traceemu, /* 126 = ibcs2 emulator trace cntl */
+ 5, ibcs2_clocal, /* 127 = local system calls */
+};
+
+struct sysentvec ibcs2_svr3_sysvec = {
+ sizeof (svr3_sysent) / sizeof (svr3_sysent[0]),
+ svr3_sysent,
+ 0x7F,
+ NSIG,
+ bsd_to_ibcs2_signal,
+ NERR,
+ bsd_to_svr3_errno
+};
+
+#if 0
+
+int ibcs2_acancel();
+int ibcs2_adjtime();
+int ibcs2_context();
+int ibcs2_evsys();
+int ibcs2_evtrapret();
+int ibcs2_fchdir();
+int ibcs2_fchmod();
+int ibcs2_fchown();
+int ibcs2_fstatvfs();
+int ibcs2_fxstat();
+int ibcs2_getgroups();
+int ibcs2_getpmsg();
+int ibcs2_getrlimit();
+int ibcs2_hrtsys();
+int ibcs2_lchown();
+int ibcs2_lxstat();
+int ibcs2_memcntl();
+int ibcs2_mincore();
+int ibcs2_mmap();
+int ibcs2_mprotect();
+int ibcs2_munmap();
+int ibcs2_pathconf();
+int ibcs2_priocntlsys();
+int ibcs2_putgmsg();
+int ibcs2_readv();
+int ibcs2_rename();
+int ibcs2_setegid();
+int ibcs2_seteuid();
+int ibcs2_setgroups();
+int ibcs2_setrlimit();
+int ibcs2_sigaction();
+int ibcs2_sigaltstack();
+int ibcs2_sigpending();
+int ibcs2_sigprocmask();
+int ibcs2_sigsendsys();
+int ibcs2_sigsuspend();
+int ibcs2_statvfs();
+int ibcs2_sysconfig();
+int ibcs2_systeminfo();
+int ibcs2_vfork();
+int ibcs2_waitsys();
+int ibcs2_writev();
+int ibcs2_xmknod();
+int ibcs2_xstat();
+
+int bsd_to_svr4_errno[NERR] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 45, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 11,150,149, 95, 96,
+ 97, 98, 99,120,121,122,123,124,125,126,
+ 127,128,129,130,131,132,133,134,143,144,
+ 145,146, 90, 78,147,148, 93, 11, 94, 11,
+ 0, 0, 0, 0, 0, 0, 0, 46, 89, 0,
+};
+
+/* ibcs2 svr4 sysent table */
+struct sysent svr4_sysent[] =
+{
+ 0, ibcs2_nosys, /* 0 = indir */
+ 1, ibcs2_exit, /* 1 = exit */
+ 0, ibcs2_fork, /* 2 = fork */
+ 3, ibcs2_read, /* 3 = read */
+ 3, ibcs2_write, /* 4 = write */
+ 3, ibcs2_open, /* 5 = open */
+ 1, ibcs2_close, /* 6 = close */
+ 3, ibcs2_wait, /* 7 = wait */
+ 2, ibcs2_creat, /* 8 = creat */
+ 2, ibcs2_link, /* 9 = link */
+ 1, ibcs2_unlink, /* 10 = unlink */
+ 2, ibcs2_exec, /* 11 = exec */
+ 1, ibcs2_chdir, /* 12 = chdir */
+ 0, ibcs2_gtime, /* 13 = time */
+ 3, ibcs2_mknod, /* 14 = mknod */
+ 2, ibcs2_chmod, /* 15 = chmod */
+ 3, ibcs2_chown, /* 16 = chown */
+ 1, ibcs2_break, /* 17 = break */
+ 2, ibcs2_stat, /* 18 = stat */
+ 3, ibcs2_seek, /* 19 = seek */
+ 0, ibcs2_getpid, /* 20 = getpid */
+ 6, ibcs2_smount, /* 21 = mount */
+ 1, ibcs2_sumount, /* 22 = umount */
+ 1, ibcs2_setuid, /* 23 = setuid */
+ 0, ibcs2_getuid, /* 24 = getuid */
+ 1, ibcs2_stime, /* 25 = stime */
+ 4, ibcs2_ptrace, /* 26 = ptrace */
+ 1, ibcs2_alarm, /* 27 = alarm */
+ 2, ibcs2_fstat, /* 28 = fstat */
+ 0, ibcs2_pause, /* 29 = pause */
+ 2, ibcs2_utime, /* 30 = utime */
+ 2, ibcs2_stty, /* 31 = stty */
+ 2, ibcs2_gtty, /* 32 = gtty */
+ 2, ibcs2_access, /* 33 = access */
+ 1, ibcs2_nice, /* 34 = nice */
+ 4, ibcs2_statfs, /* 35 = statfs */
+ 0, ibcs2_sync, /* 36 = sync */
+ 2, ibcs2_kill, /* 37 = kill */
+ 4, ibcs2_fstatfs, /* 38 = fstatfs */
+ 1, ibcs2_procids, /* 39 = procids */
+ 5, ibcs2_cxenix, /* 40 = XENIX special system call */
+ 1, ibcs2_dup, /* 41 = dup */
+ 1, ibcs2_pipe, /* 42 = pipe */
+ 1, ibcs2_times, /* 43 = times */
+ 4, ibcs2_profil, /* 44 = prof */
+ 1, ibcs2_plock, /* 45 = proc lock */
+ 1, ibcs2_setgid, /* 46 = setgid */
+ 0, ibcs2_getgid, /* 47 = getgid */
+ 2, ibcs2_sigsys, /* 48 = signal */
+ 6, ibcs2_msgsys, /* 49 = IPC message */
+ 4, ibcs2_sysi86, /* 50 = i386-specific system call */
+ 1, ibcs2_sysacct, /* 51 = turn acct off/on */
+ 4, ibcs2_shmsys, /* 52 = shared memory */
+ 5, ibcs2_semsys, /* 53 = IPC semaphores */
+ 3, ibcs2_ioctl, /* 54 = ioctl */
+ 3, ibcs2_uadmin, /* 55 = uadmin */
+ 0, ibcs2_nosys, /* 56 = reserved for exch */
+ 3, ibcs2_utssys, /* 57 = utssys */
+ 1, ibcs2_fsync, /* 58 = fsync */
+ 3, ibcs2_exece, /* 59 = exece */
+ 1, ibcs2_umask, /* 60 = umask */
+ 1, ibcs2_chroot, /* 61 = chroot */
+ 3, ibcs2_fcntl, /* 62 = fcntl */
+ 2, ibcs2_ulimit, /* 63 = ulimit */
+ 0, ibcs2_nosys, /* 64 = nosys */
+ 0, ibcs2_nosys, /* 65 = nosys */
+ 0, ibcs2_nosys, /* 66 = nosys */
+ 0, ibcs2_nosys, /* 67 = file locking call */
+ 0, ibcs2_nosys, /* 68 = local system calls */
+ 0, ibcs2_nosys, /* 69 = inode open */
+ 4, ibcs2_advfs, /* 70 = advfs */
+ 1, ibcs2_unadvfs, /* 71 = unadvfs */
+ 4, ibcs2_rmount, /* 72 = rmount */
+ 1, ibcs2_rumount, /* 73 = rumount */
+ 5, ibcs2_rfstart, /* 74 = rfstart */
+ 0, ibcs2_nosys, /* 75 = not used */
+ 1, ibcs2_rfdebug, /* 76 = rfdebug */
+ 0, ibcs2_rfstop, /* 77 = rfstop */
+ 6, ibcs2_rfsys, /* 78 = rfsys */
+ 1, ibcs2_rmdir, /* 79 = rmdir */
+ 2, ibcs2_mkdir, /* 80 = mkdir */
+ 4, ibcs2_getdents, /* 81 = getdents */
+ 3, ibcs2_libattach, /* 82 = libattach */
+ 1, ibcs2_libdetach, /* 83 = libdetach */
+ 3, ibcs2_sysfs, /* 84 = sysfs */
+ 4, ibcs2_getmsg, /* 85 = getmsg */
+ 4, ibcs2_putmsg, /* 86 = putmsg */
+ 3, ibcs2_poll, /* 87 = poll */
+ 6, ibcs2_lstat, /* 88 = lstat */
+ 2, ibcs2_symlink, /* 89 = symlink */
+ 3, ibcs2_readlink, /* 90 = readlink */
+ 2, ibcs2_setgroups, /* 91 = setgroups */
+ 2, ibcs2_getgroups, /* 92 = getgroups */
+ 2, ibcs2_fchmod, /* 93 = fchmod */
+ 3, ibcs2_fchown, /* 94 = fchown */
+ 3, ibcs2_sigprocmask, /* 95 = sigprocmask */
+ 0, ibcs2_sigsuspend, /* 96 = sigsuspend */
+ 2, ibcs2_sigaltstack, /* 97 = sigaltstack */
+ 3, ibcs2_sigaction, /* 98 = sigaction */
+ 1, ibcs2_sigpending, /* 99 = sigpending */
+ 0, ibcs2_context, /* 100 = context */
+ 0, ibcs2_evsys, /* 101 = evsys */
+ 0, ibcs2_evtrapret, /* 102 = evtrapret */
+ 0, ibcs2_statvfs, /* 103 = statvfs */
+ 0, ibcs2_fstatvfs, /* 104 = fstatvfs */
+ 5, ibcs2_cisc, /* 105 = ISC special */
+ 0, ibcs2_nfssys, /* 106 = nfssys */
+ 0, ibcs2_waitsys, /* 107 = waitsys */
+ 0, ibcs2_sigsendsys, /* 108 = sigsendsys */
+ 0, ibcs2_hrtsys, /* 109 = hrtsys */
+ 0, ibcs2_acancel, /* 110 = acancel */
+ 0, ibcs2_async, /* 111 = async */
+ 0, ibcs2_priocntlsys, /* 112 = priocntlsys */
+ 0, ibcs2_pathconf, /* 113 = pathconf */
+ 0, ibcs2_mincore, /* 114 = mincore */
+ 6, ibcs2_mmap, /* 115 = mmap */
+ 3, ibcs2_mprotect, /* 116 = mprotect */
+ 2, ibcs2_munmap, /* 117 = munmap */
+ 0, ibcs2_pathconf, /* 118 = fpathconf */
+ 0, ibcs2_vfork, /* 119 = vfork */
+ 0, ibcs2_fchdir, /* 120 = fchdir */
+ 0, ibcs2_readv, /* 121 = readv */
+ 0, ibcs2_writev, /* 122 = writev */
+ 3, ibcs2_xstat, /* 123 = xstat */
+ 3, ibcs2_lxstat, /* 124 = lxstat */
+ 3, ibcs2_fxstat, /* 125 = fxstat */
+ 4, ibcs2_xmknod, /* 126 = xmknod */
+ 5, ibcs2_clocal, /* 127 = local system calls */
+ 0, ibcs2_setrlimit, /* 128 = setrlimit */
+ 0, ibcs2_getrlimit, /* 129 = getrlimit */
+ 0, ibcs2_lchown, /* 130 = lchown */
+ 0, ibcs2_memcntl, /* 131 = memcntl */
+ 0, ibcs2_getpmsg, /* 132 = getpmsg */
+ 0, ibcs2_putgmsg, /* 133 = putgmsg */
+ 2, ibcs2_rename, /* 134 = rename */
+ 1, ibcs2_uname, /* 135 = uname */
+ 0, ibcs2_setegid, /* 136 = setegid */
+ 0, ibcs2_sysconfig, /* 137 = sysconfig */
+ 0, ibcs2_adjtime, /* 138 = adjtime */
+ 0, ibcs2_systeminfo, /* 139 = systeminfo */
+ 0, ibcs2_nosys, /* 140 = not used */
+ 0, ibcs2_seteuid, /* 141 = seteuid */
+};
+
+struct sysentvec ibcs2_svr4_sysvec = {
+ sizeof (svr4_sysent) / sizeof (svr4_sysent[0]),
+ svr4_sysent,
+ 0xFF,
+ NSIG,
+ bsd_to_ibcs2_signal,
+ NERR,
+ bsd_to_svr4_errno
+};
+
+#endif
diff --git a/sys/i386/ibcs2/ibcs2_sysi86.c b/sys/i386/ibcs2/ibcs2_sysi86.c
new file mode 100644
index 000000000000..bca0fe999c5a
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_sysi86.c
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 1994 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: ibcs2_sysi86.c,v 1.4 1994/10/12 19:38:38 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+
+
+struct ibcs2_sysi86_args {
+ int cmd;
+ int *arg;
+};
+
+int
+ibcs2_sysi86(struct proc *p, struct ibcs2_sysi86_args *args, int *retval)
+{
+ switch (args->cmd) {
+ case 0x28: { /* SI86_FPHW */
+ int val, error;
+ extern int hw_float;
+
+ if (hw_float) val = IBCS2_FP_387; /* FPU hardware */
+ else val = IBCS2_FP_SW; /* FPU emulator */
+
+ if (error = copyout(&val, args->arg, sizeof(val)))
+ return error;
+ return 0;
+ }
+
+ case 0x33: /* SI86_MEM */
+ *retval = ctob(physmem);
+ return 0;
+
+ default:
+ printf("IBCS2: 'sysi86' function %d(0x%x) "
+ "not implemented yet\n", args->cmd, args->cmd);
+ return EINVAL;
+ }
+}
diff --git a/sys/i386/ibcs2/ibcs2_xenix.c b/sys/i386/ibcs2/ibcs2_xenix.c
new file mode 100644
index 000000000000..051ed5801caf
--- /dev/null
+++ b/sys/i386/ibcs2/ibcs2_xenix.c
@@ -0,0 +1,367 @@
+/*-
+ * Copyright (c) 1994 Sean Eric Fagan
+ * Copyright (c) 1994 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: ibcs2_xenix.c,v 1.10 1994/10/12 19:38:38 sos Exp $
+ */
+
+#include <i386/ibcs2/ibcs2.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/signal.h>
+#include <sys/syslimits.h>
+#include <sys/unistd.h>
+#include <sys/timeb.h>
+#include <vm/vm.h>
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
+struct ibcs2_sco_chsize_args {
+ int fd;
+ ibcs2_off_t size;
+};
+
+static int
+sco_chsize(struct proc *p, struct ibcs2_sco_chsize_args *args, int *retval)
+{
+ struct ftruncate_args {
+ int fd;
+ int pad;
+ off_t length;
+ } tmp;
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix chsize'\n");
+ tmp.fd = args->fd;
+ tmp.pad = 0;
+ tmp.length = args->size;
+ return ftruncate(p, &tmp, retval);
+}
+
+struct ibcs2_sco_ftime_args {
+ struct timeb *tp;
+};
+
+static int
+sco_ftime(struct proc *p, struct ibcs2_sco_ftime_args *args, int *retval)
+{
+ struct timeval atv;
+ extern struct timezone tz;
+ struct timeb tb;
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix ftime'\n");
+ microtime(&atv);
+ tb.time = atv.tv_sec;
+ tb.millitm = atv.tv_usec / 1000;
+ tb.timezone = tz.tz_minuteswest;
+ tb.dstflag = tz.tz_dsttime != DST_NONE;
+
+ return copyout((caddr_t)&tb, (caddr_t)args->tp, sizeof(struct timeb));
+}
+
+struct ibcs2_sco_nap_args {
+ long time;
+};
+
+static int
+sco_nap(struct proc *p, struct ibcs2_sco_nap_args *args, int *retval)
+{
+ long period;
+ extern int hz;
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix nap %d ms'\n", args->time);
+ period = (long)args->time / (1000/hz);
+ if (period)
+ while (tsleep(&period, PUSER, "nap", period)
+ != EWOULDBLOCK) ;
+ return 0;
+}
+
+struct ibcs2_sco_rdchk_args {
+ int fd;
+};
+
+static int
+sco_rdchk(struct proc *p, struct ibcs2_sco_rdchk_args *args, int *retval)
+{
+ struct ioctl_arg {
+ int fd;
+ int cmd;
+ caddr_t arg;
+ } tmp;
+ int error;
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix rdchk'\n");
+ tmp.fd = args->fd;
+ tmp.cmd = FIONREAD;
+ tmp.arg = (caddr_t)UA_ALLOC();
+ error = ioctl(p, &tmp, retval);
+ if (!error)
+ *retval = *retval <= 0 ? 0 : 1;
+ return error;
+}
+
+struct ibcs2_sco_utsname_args {
+ long addr;
+};
+
+static int
+sco_utsname(struct proc *p, struct ibcs2_sco_utsname_args *args, int *retval)
+{
+ struct ibcs2_sco_utsname {
+ char sysname[9];
+ char nodename[9];
+ char release[16];
+ char kernelid[20];
+ char machine[9];
+ char bustype[9];
+ char sysserial[10];
+ unsigned short sysorigin;
+ unsigned short sysoem;
+ char numusers[9];
+ unsigned short numcpu;
+ } ibcs2_sco_uname;
+ extern char ostype[], hostname[], osrelease[], version[], machine[];
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sco_utsname'\n");
+ bzero(&ibcs2_sco_uname, sizeof(struct ibcs2_sco_utsname));
+ strncpy(ibcs2_sco_uname.sysname, ostype, 8);
+ strncpy(ibcs2_sco_uname.nodename, hostname, 8);
+ strncpy(ibcs2_sco_uname.release, osrelease, 15);
+ strncpy(ibcs2_sco_uname.kernelid, version, 19);
+ strncpy(ibcs2_sco_uname.machine, machine, 8);
+ bcopy("ISA/EISA", ibcs2_sco_uname.bustype, 8);
+ bcopy("no charge", ibcs2_sco_uname.sysserial, 9);
+ bcopy("unlim", ibcs2_sco_uname.numusers, 8);
+ ibcs2_sco_uname.sysorigin = 0xFFFF;
+ ibcs2_sco_uname.sysoem = 0xFFFF;
+ ibcs2_sco_uname.numcpu = 1;
+ return copyout((caddr_t)&ibcs2_sco_uname, (caddr_t)args->addr,
+ sizeof(struct ibcs2_sco_utsname));
+}
+
+int
+ibcs2_cxenix(struct proc *p, void *args, int *retval)
+{
+ struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
+
+ switch ((tf->tf_eax & 0xff00) >> 8) {
+
+ case 0x07: /* rdchk */
+ return sco_rdchk(p, args, retval);
+
+ case 0x0a: /* chsize */
+ return sco_chsize(p, args, retval);
+
+ case 0x0b: /* ftime */
+ return sco_ftime(p, args, retval);
+
+ case 0x0c: /* nap */
+ return sco_nap(p, args, retval);
+
+ case 0x15: /* scoinfo (not documented) */
+ *retval = 0;
+ return 0;
+
+ case 0x24: /* select */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix select'\n");
+ return select(p, args, retval);
+
+ case 0x25: /* eaccess */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix eaccess'\n");
+ return ibcs2_access(p, args, retval);
+
+ case 0x27: /* sigaction */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sigaction'\n");
+ return ibcs2_sigaction (p, args, retval);
+
+ case 0x28: /* sigprocmask */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sigprocmask'\n");
+ return ibcs2_sigprocmask (p, args, retval);
+
+ case 0x29: /* sigpending */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sigpending'\n");
+ return ibcs2_sigpending (p, args, retval);
+
+ case 0x2a: /* sigsuspend */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sigsuspend'\n");
+ return ibcs2_sigsuspend (p, args, retval);
+
+ case 0x2b: /* getgroups */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix getgroups'\n");
+ return ibcs2_getgroups(p, args, retval);
+
+ case 0x2c: /* setgroups */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix setgroups'\n");
+ return ibcs2_setgroups(p, args, retval);
+
+ case 0x2d: { /* sysconf */
+ struct ibcs2_sysconf_args {
+ int num;
+ } *sysconf_args = args;
+
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix sysconf'");
+ switch (sysconf_args->num) {
+ case 0: /* _SC_ARG_MAX */
+ *retval = (ARG_MAX);
+ break;
+ case 1: /* _SC_CHILD_MAX */
+ *retval = (CHILD_MAX);
+ break;
+ case 2: /* _SC_CLK_TCK */
+ *retval = (CLK_TCK);
+ break;
+ case 3: /* _SC_NGROUPS_MAX */
+ *retval = (NGROUPS_MAX);
+ break;
+ case 4: /* _SC_OPEN_MAX */
+ *retval = (OPEN_MAX);
+ break;
+ case 5: /* _SC_JOB_CONTROL */
+#ifdef _POSIX_JOB_CONTORL
+ *retval = _POSIX_JOB_CONTORL;
+#else
+ *retval = (0);
+#endif
+ break;
+ case 6: /* _SC_SAVED_IDS */
+#ifdef _POSIX_SAVED_IDS
+ *retval = (_POSIX_SAVED_IDS);
+#else
+ *retval = (0);
+#endif
+ break;
+ case 7: /* _SC_VERSION */
+ *retval = (_POSIX_VERSION);
+ break;
+ default:
+ *retval = -1;
+ return EINVAL;
+ }
+ return 0;
+ }
+
+ case 0x2e: /* pathconf */
+ case 0x2f: /* fpathconf */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix (f)pathconf'\n");
+ return ibcs2_pathconf(p, args, retval);
+
+ case 0x30: /* rename */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix rename'\n");
+ return ibcs2_rename(p, args, retval);
+
+ case 0x32: /* sco_utsname */
+ return sco_utsname(p, args, retval);
+
+ case 0x37: /* getitimer */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix getitimer'\n");
+ return getitimer(p, args, retval);
+
+ case 0x38: /* setitimer */
+ if (ibcs2_trace & IBCS2_TRACE_XENIX)
+ printf("IBCS2: 'cxenix setitimer'\n");
+ return setitimer(p, args, retval);
+
+
+ /* Not implemented yet SORRY */
+ case 0x01: /* xlocking */
+ printf("IBCS2: 'cxenix xlocking'");
+ break;
+ case 0x02: /* creatsem */
+ printf("IBCS2: 'cxenix creatsem'");
+ break;
+ case 0x03: /* opensem */
+ printf("IBCS2: 'cxenix opensem'");
+ break;
+ case 0x04: /* sigsem */
+ printf("IBCS2: 'cxenix sigsem'");
+ break;
+ case 0x05: /* waitsem */
+ printf("IBCS2: 'cxenix waitsem'");
+ break;
+ case 0x06: /* nbwaitsem */
+ printf("IBCS2: 'cxenix nbwaitsem'");
+ break;
+ case 0x0d: /* sdget */
+ printf("IBCS2: 'cxenix sdget'");
+ break;
+ case 0x0e: /* sdfree */
+ printf("IBCS2: 'cxenix sdfree'");
+ break;
+ case 0x0f: /* sdenter */
+ printf("IBCS2: 'cxenix sdenter'");
+ break;
+ case 0x10: /* sdleave */
+ printf("IBCS2: 'cxenix sdleave'");
+ break;
+ case 0x11: /* sdgetv */
+ printf("IBCS2: 'cxenix sdgetv'");
+ break;
+ case 0x12: /* sdwaitv */
+ printf("IBCS2: 'cxenix sdwaitv'");
+ break;
+ case 0x20: /* proctl */
+ printf("IBCS2: 'cxenix proctl'");
+ break;
+ case 0x21: /* execseg */
+ printf("IBCS2: 'cxenix execseg'");
+ break;
+ case 0x22: /* unexecseg */
+ printf("IBCS2: 'cxenix unexecseg'");
+ break;
+ case 0x26: /* paccess */
+ printf("IBCS2: 'cxenix paccess'");
+ break;
+ default:
+ printf("IBCS2: 'cxenix' function %d(0x%x)",
+ tf->tf_eax>>8, tf->tf_eax>>8);
+ break;
+ }
+ printf(" not implemented yet\n");
+ return EINVAL;
+}
diff --git a/sys/i386/ibcs2/imgact_coff.c b/sys/i386/ibcs2/imgact_coff.c
new file mode 100644
index 000000000000..5d57d1804eb8
--- /dev/null
+++ b/sys/i386/ibcs2/imgact_coff.c
@@ -0,0 +1,457 @@
+/*-
+ * Copyright (c) 1994 Sean Eric Fagan
+ * Copyright (c) 1994 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: imgact_coff.c,v 1.11 1994/10/12 19:38:03 sos Exp $
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/exec.h>
+#include <sys/mman.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/sysent.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include "coff.h"
+#include "ibcs2.h"
+
+static int
+load_coff_section(vmspace, vp, offset, vmaddr, memsz, filsz, prot)
+ struct vmspace *vmspace;
+ struct vnode *vp;
+ vm_offset_t offset;
+ caddr_t vmaddr;
+ size_t memsz, filsz;
+ vm_prot_t prot;
+{
+ size_t map_len;
+ vm_offset_t map_offset;
+ caddr_t map_addr;
+ int error;
+ unsigned char *data_buf = 0;
+ size_t copy_len;
+
+ map_offset = trunc_page(offset);
+ map_addr = (caddr_t)trunc_page(vmaddr);
+
+ if (memsz > filsz) {
+ /*
+ * We have the stupid situation that
+ * the section is longer than it is on file,
+ * which means it has zero-filled areas, and
+ * we have to work for it. Stupid iBCS!
+ */
+ map_len = trunc_page(offset + filsz) - trunc_page(map_offset);
+ } else {
+ /*
+ * The only stuff we care about is on disk, and we
+ * don't care if we map in more than is really there.
+ */
+ map_len = round_page(offset + filsz) - trunc_page(map_offset);
+ }
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): vm_mmap(&vmspace->vm_map, &0x%08lx, 0x%x, 0x%x, "
+ "VM_PROT_ALL, MAP_FILE | MAP_PRIVATE | MAP_FIXED, vp, 0x%x)\n",
+ __FILE__, __LINE__, map_addr, map_len, prot, map_offset);
+}
+
+ if (error = vm_mmap(&vmspace->vm_map,
+ &map_addr,
+ map_len,
+ prot,
+ VM_PROT_ALL,
+ MAP_FILE | MAP_PRIVATE | MAP_FIXED,
+ vp,
+ map_offset))
+ return error;
+
+ if (memsz == filsz) {
+ /* We're done! */
+ return 0;
+ }
+
+ /*
+ * Now we have screwball stuff, to accomodate stupid COFF.
+ * We have to map the remaining bit of the file into the kernel's
+ * memory map, allocate some anonymous memory, copy that last
+ * bit into it, and then we're done. *sigh*
+ * For clean-up reasons, we actally map in the file last.
+ */
+
+ copy_len = (offset + filsz) - trunc_page(offset + filsz);
+ map_addr = (caddr_t)trunc_page(vmaddr + filsz);
+ map_len = round_page(memsz) - trunc_page(filsz);
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): vm_allocate(&vmspace->vm_map, &0x%08lx, 0x%x, FALSE)\n",
+ __FILE__, __LINE__, map_addr, map_len);
+}
+
+ if (error = vm_allocate(&vmspace->vm_map, &map_addr, map_len, FALSE))
+ return error;
+
+ if (error = vm_mmap(kernel_map, &data_buf, PAGE_SIZE,
+ VM_PROT_READ, VM_PROT_READ, MAP_FILE,
+ vp, trunc_page(offset + filsz)))
+ return error;
+
+ bcopy(data_buf, map_addr, copy_len);
+
+ if (vm_deallocate(kernel_map, data_buf, PAGE_SIZE))
+ panic("load_coff_section vm_deallocate failed");
+
+ return 0;
+}
+
+int
+coff_load_file(struct proc *p, char *name)
+{
+ struct vmspace *vmspace = p->p_vmspace;
+ int error;
+ struct nameidata nd;
+ struct vnode *vnodep;
+ struct vattr attr;
+ struct filehdr *fhdr;
+ struct aouthdr *ahdr;
+ struct scnhdr *scns;
+ char *ptr = 0;
+ int nscns;
+ unsigned long text_offset = 0, text_address = 0, text_size = 0;
+ unsigned long data_offset = 0, data_address = 0, data_size = 0;
+ unsigned long bss_size = 0;
+ int i;
+
+ nd.ni_cnd.cn_nameiop = LOOKUP;
+ nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME;
+ nd.ni_cnd.cn_proc = curproc;
+ nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
+ nd.ni_segflg = UIO_SYSSPACE;
+ nd.ni_dirp = name;
+
+ error = namei(&nd);
+ if (error)
+ return error;
+
+ vnodep = nd.ni_vp;
+ if (vnodep == NULL)
+ return ENOEXEC;
+
+ if (vnodep->v_writecount) {
+ error = ETXTBSY;
+ goto fail;
+ }
+
+ if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p))
+ goto fail;
+
+ if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC)
+ || ((attr.va_mode & 0111) == 0)
+ || (attr.va_type != VREG))
+ goto fail;
+
+ if (attr.va_size == 0) {
+ error = ENOEXEC;
+ goto fail;
+ }
+
+ if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p))
+ goto fail;
+
+ if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p))
+ goto fail;
+
+ if (error = vm_mmap(kernel_map, &ptr, PAGE_SIZE, VM_PROT_READ,
+ VM_PROT_READ, MAP_FILE, vnodep, 0))
+ goto fail;
+
+ fhdr = (struct filehdr *)ptr;
+
+ if (fhdr->f_magic != I386_COFF) {
+ error = ENOEXEC;
+ goto dealloc_and_fail;
+ }
+
+ nscns = fhdr->f_nscns;
+
+ if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
+ /*
+ * XXX -- just fail. I'm so lazy.
+ */
+ error = ENOEXEC;
+ goto dealloc_and_fail;
+ }
+
+ ahdr = (struct aouthdr*)(ptr + sizeof(struct filehdr));
+
+ scns = (struct scnhdr*)(ptr + sizeof(struct filehdr)
+ + sizeof(struct aouthdr));
+
+ for (i = 0; i < nscns; i++) {
+ if (scns[i].s_flags & STYP_NOLOAD)
+ continue;
+ else if (scns[i].s_flags & STYP_TEXT) {
+ text_address = scns[i].s_vaddr;
+ text_size = scns[i].s_size;
+ text_offset = scns[i].s_scnptr;
+ }
+ else if (scns[i].s_flags & STYP_DATA) {
+ data_address = scns[i].s_vaddr;
+ data_size = scns[i].s_size;
+ data_offset = scns[i].s_scnptr;
+ } else if (scns[i].s_flags & STYP_BSS) {
+ bss_size = scns[i].s_size;
+ }
+ }
+
+ if (error = load_coff_section(vmspace, vnodep, text_offset,
+ (caddr_t)text_address,
+ text_size, text_size,
+ VM_PROT_READ | VM_PROT_EXECUTE)) {
+ goto dealloc_and_fail;
+ }
+ if (error = load_coff_section(vmspace, vnodep, data_offset,
+ (caddr_t)data_address,
+ data_size + bss_size, data_size,
+ VM_PROT_ALL)) {
+ goto dealloc_and_fail;
+ }
+
+ error = 0;
+
+ dealloc_and_fail:
+ if (vm_deallocate(kernel_map, ptr, PAGE_SIZE))
+ panic(__FUNCTION__ " vm_deallocate failed");
+
+ fail:
+ vput(nd.ni_vp);
+ FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
+ return error;
+}
+
+int
+exec_coff_imgact(iparams)
+ struct image_params *iparams;
+{
+ struct filehdr *fhdr = (struct filehdr*)iparams->image_header;
+ struct aouthdr *ahdr;
+ struct scnhdr *scns;
+ int i;
+ struct vmspace *vmspace = iparams->proc->p_vmspace;
+ unsigned long vmaddr;
+ int nscns;
+ int error, len;
+ extern struct sysentvec ibcs2_svr3_sysvec;
+ unsigned long text_offset = 0, text_address = 0, text_size = 0;
+ unsigned long data_offset = 0, data_address = 0, data_size = 0;
+ unsigned long bss_size = 0;
+ int need_hack_p;
+ unsigned long data_end;
+ unsigned long data_map_start, data_map_len, data_map_addr = 0;
+ unsigned long bss_address, bss_map_start, data_copy_len, bss_map_len;
+ unsigned char *data_buf = 0;
+ caddr_t hole;
+
+ if (fhdr->f_magic != I386_COFF ||
+ !(fhdr->f_flags & F_EXEC)) {
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): return -1\n", __FILE__, __LINE__);
+}
+
+ return -1;
+ }
+
+ nscns = fhdr->f_nscns;
+ if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
+ /*
+ * For now, return an error -- need to be able to
+ * read in all of the section structures.
+ */
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): return -1\n", __FILE__, __LINE__);
+}
+ return -1;
+ }
+
+ ahdr = (struct aouthdr*)((char*)(iparams->image_header) +
+ sizeof(struct filehdr));
+ iparams->entry_addr = ahdr->entry;
+
+ scns = (struct scnhdr*)((char*)(iparams->image_header) +
+ sizeof(struct filehdr) +
+ sizeof(struct aouthdr));
+
+ if (error = exec_extract_strings(iparams)) {
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): return %d\n", __FILE__, __LINE__, error);
+}
+ return error;
+ }
+
+ exec_new_vmspace(iparams);
+
+ for (i = 0; i < nscns; i++) {
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("i = %d, scns[i].s_name = %s, scns[i].s_vaddr = %08lx, "
+ "scns[i].s_scnptr = %d\n", i, scns[i].s_name,
+ scns[i].s_vaddr, scns[i].s_scnptr);
+}
+ if (scns[i].s_flags & STYP_NOLOAD) {
+ /*
+ * A section that is not loaded, for whatever
+ * reason. It takes precedance over other flag
+ * bits...
+ */
+ continue;
+ } else if (scns[i].s_flags & STYP_TEXT) {
+ text_address = scns[i].s_vaddr;
+ text_size = scns[i].s_size;
+ text_offset = scns[i].s_scnptr;
+ } else if (scns[i].s_flags & STYP_DATA) {
+ /* .data section */
+ data_address = scns[i].s_vaddr;
+ data_size = scns[i].s_size;
+ data_offset = scns[i].s_scnptr;
+ } else if (scns[i].s_flags & STYP_BSS) {
+ /* .bss section */
+ bss_size = scns[i].s_size;
+ } else if (scns[i].s_flags & STYP_LIB) {
+ char *buf = 0, *ptr;
+ int foff = trunc_page(scns[i].s_scnptr);
+ int off = scns[i].s_scnptr - foff;
+ int len = round_page(scns[i].s_size + PAGE_SIZE);
+ int j;
+
+ if (error = vm_mmap(kernel_map, &buf, len,
+ VM_PROT_READ, VM_PROT_READ, MAP_FILE,
+ iparams->vnodep, foff)) {
+ return ENOEXEC;
+ }
+ for (j = off; j < scns[i].s_size + off; j++) {
+ char *libname;
+ libname = buf + j + 4 * *(long*)(buf + j + 4);
+ j += 4* *(long*)(buf + j);
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): shared library %s\n", __FILE__, __LINE__, libname);
+}
+ error = coff_load_file(iparams->proc, libname);
+ if (error)
+ break;
+ }
+ if (vm_deallocate(kernel_map, buf, len))
+ panic("exec_coff_imgact vm_deallocate failed");
+ if (error)
+ return error;
+ }
+ }
+ /*
+ * Map in .text now
+ */
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): load_coff_section(vmspace, "
+ "iparams->vnodep, %08lx, %08lx, 0x%x, 0x%x, 0x%x)\n",
+ __FILE__, __LINE__, text_offset, text_address,
+ text_size, text_size, VM_PROT_READ | VM_PROT_EXECUTE);
+}
+ if (error = load_coff_section(vmspace, iparams->vnodep,
+ text_offset, (caddr_t)text_address,
+ text_size, text_size,
+ VM_PROT_READ | VM_PROT_EXECUTE)) {
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+}
+ return error;
+ }
+ /*
+ * Map in .data and .bss now
+ */
+
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): load_coff_section(vmspace, "
+ "iparams->vnodep, 0x%08lx, 0x%08lx, 0x%x, 0x%x, 0x%x)\n",
+ __FILE__, __LINE__, data_offset, data_address,
+ data_size + bss_size, data_size, VM_PROT_ALL);
+}
+ if (error = load_coff_section(vmspace, iparams->vnodep,
+ data_offset, (caddr_t)data_address,
+ data_size + bss_size, data_size,
+ VM_PROT_ALL)) {
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+}
+ return error;
+ }
+
+ iparams->interpreted = 0;
+ iparams->proc->p_sysent = &ibcs2_svr3_sysvec;
+
+ vmspace->vm_tsize = round_page(text_size) >> PAGE_SHIFT;
+ vmspace->vm_dsize = round_page(data_size + bss_size) >> PAGE_SHIFT;
+ vmspace->vm_taddr = (caddr_t)text_address;
+ vmspace->vm_daddr = (caddr_t)data_address;
+
+ hole = (caddr_t)trunc_page(vmspace->vm_daddr) + ctob(vmspace->vm_dsize);
+
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("%s(%d): vm_allocate(&vmspace->vm_map, &0x%08lx, 1, FALSE)\n",
+ __FILE__, __LINE__, hole);
+printf("imgact: error = %d\n", error);
+}
+ error = vm_allocate(&vmspace->vm_map, &hole, 1, FALSE);
+
+if (ibcs2_trace & IBCS2_TRACE_COFF) {
+printf("IBCS2: start vm_dsize = 0x%x, vm_daddr = 0x%x end = 0x%x\n",
+ ctob(vmspace->vm_dsize), vmspace->vm_daddr,
+ ctob(vmspace->vm_dsize) + vmspace->vm_daddr );
+printf("%s(%d): returning successfully!\n", __FILE__, __LINE__);
+}
+ return 0;
+}
+
+/*
+ * Tell kern_execve.c about it, with a little help from the linker.
+ * Since `const' objects end up in the text segment, TEXT_SET is the
+ * correct directive to use.
+ */
+const struct execsw coff_execsw = { exec_coff_imgact, "coff" };
+TEXT_SET(execsw_set, coff_execsw);