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 +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; ic_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; ic_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; ic_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; ic_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; ic_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; ic_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; ic_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; ic_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; ic_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; ic_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 +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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);