iBCS2 emulator core files.

This is the main files for the iBCS2 emulator. It can be use
compiled into the kernel by using:

options		IBCS2
options 	COMPAT_IBCS2

or as a lkm module using:

options		COMPAT_IBCS2

and then loading it via the ibcs2 script in /usr/bin

REMEMBER: this code is still experimental ! NO WARRENTY !

Submitted by:	sef@kithrup.com, mostyn@mrl.com, sos@kmd-ac.dk
This commit is contained in:
sos 1994-10-14 08:53:16 +00:00
parent 457402dd33
commit 4fb6468674
16 changed files with 6962 additions and 14 deletions

106
sys/i386/ibcs2/coff.h Normal file
View File

@ -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 */

View File

@ -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

View File

@ -0,0 +1,169 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_dummy.c,v 1.14 1994/10/13 23:10:58 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/errno.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
int
ibcs2_nosys(struct proc *p, void *args, int *retval)
{
printf("IBCS2: no such syscall eax = %d(0x%x)\n",
((struct trapframe*)p->p_md.md_regs)->tf_eax,
((struct trapframe*)p->p_md.md_regs)->tf_eax);
return ENOSYS;
}
int
ibcs2_clocal(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'clocal' not implemented yet\n");
return EINVAL;
}
int
ibcs2_sysfs(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'sysfs' not implemented yet\n");
return EINVAL;
}
int
ibcs2_uadmin(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'uadmin' not implemented yet\n");
return EINVAL;
}
int
ibcs2_advfs(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'advfs' not implemented yet\n");
return EINVAL;
}
int
ibcs2_unadvfs(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'unadvfs' not implemented yet\n");
return EINVAL;
}
int
ibcs2_libattach(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'libattach' obsolete\n");
return EINVAL;
}
int
ibcs2_libdetach(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'libdetach' obsolete\n");
return EINVAL;
}
int
ibcs2_plock(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'plock' not supported\n");
return 0;
}
/*
* getmsg/putmsg are STREAMS related system calls
* We don't have STREAMS (yet??) but fake it anyways
*/
int
ibcs2_getmsg(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'getmsg' not supported\n");
return 0;
}
int
ibcs2_putmsg(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'putmsg' not supported\n");
return 0;
}
/*
* The following are RFS system calls
* We don't have RFS.
*/
int
ibcs2_rfdebug(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rdebug' not supported\n");
return EINVAL;
}
int
ibcs2_rfstart(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rfstart' not supported\n");
return EINVAL;
}
int
ibcs2_rfstop(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rfstop' not supported\n");
return EINVAL;
}
int
ibcs2_rfsys(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rfsys' not supported\n");
return EINVAL;
}
int
ibcs2_rmount(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rmount' not supported\n");
return EINVAL;
}
int
ibcs2_rumount(struct proc *p, void *args, int *retval)
{
printf("IBCS2: 'rumount' not supported\n");
return EINVAL;
}

525
sys/i386/ibcs2/ibcs2_file.c Normal file
View File

@ -0,0 +1,525 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ibcs2_file.c,v 1.8 1994/10/13 23:10:58 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/exec.h>
#include <vm/vm.h>
#include <ufs/ufs/dir.h>
struct ibcs2_close_args {
int fd;
};
int
ibcs2_close(struct proc *p, struct ibcs2_close_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'close' fd=%d\n", args->fd);
return close(p, args, retval);
}
struct ibcs2_creat_args {
char *fname;
int fmode;
};
int
ibcs2_creat(struct proc *p, struct ibcs2_creat_args *args, int *retval)
{
struct args {
char *fname;
int mode;
int crtmode;
} bsd_open_args;
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'creat' name=%s, mode=%x\n",
args->fname, args->fmode);
bsd_open_args.fname = args->fname;
bsd_open_args.crtmode = args->fmode;
bsd_open_args.mode = O_WRONLY | O_CREAT | O_TRUNC;
return open(p, &bsd_open_args, retval);
}
int
ibcs2_dup(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'dup'\n");
return dup(p, args, retval);
}
struct ibcs2_flock {
short l_type;
short l_whence;
ibcs2_off_t l_start;
ibcs2_off_t l_len;
short l_sysid;
ibcs2_pid_t l_pid;
};
static void
ibcs2_to_bsd_flock(struct ibcs2_flock *ibcs2_flock, struct flock *bsd_flock)
{
switch (ibcs2_flock->l_type) {
case IBCS2_F_RDLCK:
bsd_flock->l_type = F_RDLCK;
break;
case IBCS2_F_WRLCK:
bsd_flock->l_type = F_WRLCK;
break;
case IBCS2_F_UNLCK:
bsd_flock->l_type = F_UNLCK;
break;
}
bsd_flock->l_whence = ibcs2_flock->l_whence;
bsd_flock->l_start = (off_t)ibcs2_flock->l_start;
bsd_flock->l_len = (off_t)ibcs2_flock->l_len;
bsd_flock->l_pid = (pid_t)ibcs2_flock->l_pid;
}
static void
bsd_to_ibcs2_flock(struct flock *bsd_flock, struct ibcs2_flock *ibcs2_flock)
{
switch (bsd_flock->l_type) {
case F_RDLCK:
ibcs2_flock->l_type = IBCS2_F_RDLCK;
break;
case F_WRLCK:
ibcs2_flock->l_type = IBCS2_F_WRLCK;
break;
case F_UNLCK:
ibcs2_flock->l_type = IBCS2_F_UNLCK;
break;
}
ibcs2_flock->l_whence = bsd_flock->l_whence;
ibcs2_flock->l_start = (ibcs2_off_t)bsd_flock->l_start;
ibcs2_flock->l_len = (ibcs2_off_t)bsd_flock->l_len;
ibcs2_flock->l_sysid = 0;
ibcs2_flock->l_pid = (ibcs2_pid_t)bsd_flock->l_pid;
}
struct ibcs2_fcntl_args {
int fd;
int cmd;
int arg;
};
int
ibcs2_fcntl(struct proc *p, struct ibcs2_fcntl_args *args, int *retval)
{
int error, result;
struct fcntl_args {
int fd;
int cmd;
int arg;
} fcntl_args;
struct ibcs2_flock ibcs2_flock;
struct flock *bsd_flock = (struct flock *)UA_ALLOC();
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'fcntl' fd=%d, cmd=%d arg=%d\n",
args->fd, args->cmd, args->arg);
fcntl_args.fd = args->fd;
fcntl_args.arg = 0;
switch (args->cmd) {
case IBCS2_F_DUPFD:
fcntl_args.cmd = F_DUPFD;
return fcntl(p, &fcntl_args, retval);
case IBCS2_F_GETFD:
fcntl_args.cmd = F_GETFD;
return fcntl(p, &fcntl_args, retval);
case IBCS2_F_SETFD:
fcntl_args.cmd = F_SETFD;
return fcntl(p, &fcntl_args, retval);
case IBCS2_F_GETFL:
fcntl_args.cmd = F_GETFL;
error = fcntl(p, &fcntl_args, &result);
*retval = 0;
if (result & O_RDONLY) *retval |= IBCS2_RDONLY;
if (result & O_WRONLY) *retval |= IBCS2_WRONLY;
if (result & O_RDWR) *retval |= IBCS2_RDWR;
if (result & O_NDELAY) *retval |= IBCS2_NONBLOCK;
if (result & O_APPEND) *retval |= IBCS2_APPEND;
if (result & O_FSYNC) *retval |= IBCS2_SYNC;
return error;
case IBCS2_F_SETFL:
if (args->arg & IBCS2_NDELAY) fcntl_args.arg |= O_NONBLOCK;
if (args->arg & IBCS2_APPEND) fcntl_args.arg |= O_APPEND;
if (args->arg & IBCS2_SYNC) fcntl_args.arg |= O_FSYNC;
fcntl_args.cmd = F_SETFL;
return fcntl(p, &fcntl_args, retval);
case IBCS2_F_GETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
sizeof(struct ibcs2_flock))))
return error;
ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
fcntl_args.cmd = F_GETLK;
fcntl_args.arg = (int)bsd_flock;
if (error = fcntl(p, &fcntl_args, retval))
return error;
bsd_to_ibcs2_flock(bsd_flock, &ibcs2_flock);
return copyout((caddr_t)&ibcs2_flock, (caddr_t)args->arg,
sizeof(struct ibcs2_flock));
case IBCS2_F_SETLK:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
sizeof(struct ibcs2_flock))))
return error;
ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
fcntl_args.cmd = F_SETLK;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
case IBCS2_F_SETLKW:
if ((error = copyin((caddr_t)args->arg, (caddr_t)&ibcs2_flock,
sizeof(struct ibcs2_flock))))
return error;
ibcs2_to_bsd_flock(&ibcs2_flock, bsd_flock);
fcntl_args.cmd = F_SETLKW;
fcntl_args.arg = (int)bsd_flock;
return fcntl(p, &fcntl_args, retval);
}
return EINVAL;
}
struct ibcs2_dirent {
ibcs2_ino_t d_ino;
ibcs2_off_t d_off;
unsigned short d_reclen;
char d_name[256];
};
struct ibcs2_getdents_args {
int fd;
char *buf;
int nbytes;
};
#define BSD_DIRENT(cp) ((struct direct *)(cp))
#define IBCS2_RECLEN(p) \
(((2*sizeof(long)+sizeof(short)+BSD_DIRENT(p)->d_namlen+1)+3)&~3)
int
ibcs2_getdents(struct proc *p, struct ibcs2_getdents_args *args, int *retval)
{
struct vnode *vp;
struct ibcs2_dirent dir;
struct file *fp;
struct uio auio;
struct iovec aiov;
off_t off;
caddr_t inp, buf, outp;
int len, reclen, resid;
int buflen, error, eofflag;
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'getdents' fd = %d, size = %d\n",
args->fd, args->nbytes);
if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
return error;
if ((fp->f_flag & FREAD) == 0)
return EBADF;
vp = (struct vnode *)fp->f_data;
if (vp->v_type != VDIR)
return EINVAL;
buflen = min(MAXBSIZE, max(DIRBLKSIZ, args->nbytes));
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
off = fp->f_offset;
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
auio.uio_offset = off & ~(DIRBLKSIZ-1);
if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag))
goto out;
inp = buf + (off & (DIRBLKSIZ-1));
buflen -= off & (DIRBLKSIZ-1);
outp = args->buf;
resid = args->nbytes;
if ((len = buflen - auio.uio_resid) <= 0)
goto eof;
for (; len > 0 && resid > 0; len -= reclen) {
reclen = BSD_DIRENT(inp)->d_reclen;
if (reclen & 3)
panic("ibcs2_getdents");
if (BSD_DIRENT(inp)->d_ino == 0) {
off += reclen;
inp += reclen;
continue;
}
if (IBCS2_RECLEN(inp) > len || resid < IBCS2_RECLEN(inp)) {
outp++;
break;
}
bzero(&dir, sizeof(struct ibcs2_dirent));
dir.d_ino = BSD_DIRENT(inp)->d_ino;
dir.d_off = (ibcs2_off_t)off;
dir.d_reclen = IBCS2_RECLEN(inp);
bcopy(BSD_DIRENT(inp)->d_name, &dir.d_name,
BSD_DIRENT(inp)->d_namlen);
if (error = copyout(&dir, outp, dir.d_reclen))
goto out;
outp += IBCS2_RECLEN(inp);
resid -= IBCS2_RECLEN(inp);
off += reclen;
inp += reclen;
}
if (outp == args->buf)
goto again;
fp->f_offset = off;
eof:
*retval = args->nbytes - resid;
out:
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return error;
}
struct ibcs2_open_args {
char *fname;
int fmode;
int crtmode;
};
int
ibcs2_open(struct proc *p, struct ibcs2_open_args *args, int *retval)
{
int bsd_mode = 0;
int noctty = args->fmode & 0x8000;
int error;
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'open' name=%s, flags=%x, mode=%x\n",
args->fname, args->fmode, args->crtmode);
if (args->fmode & IBCS2_RDONLY) bsd_mode |= O_RDONLY;
if (args->fmode & IBCS2_WRONLY) bsd_mode |= O_WRONLY;
if (args->fmode & IBCS2_RDWR) bsd_mode |= O_RDWR;
if (args->fmode & IBCS2_NDELAY) bsd_mode |= O_NONBLOCK;
if (args->fmode & IBCS2_APPEND) bsd_mode |= O_APPEND;
if (args->fmode & IBCS2_SYNC) bsd_mode |= O_FSYNC;
if (args->fmode & IBCS2_NONBLOCK) bsd_mode |= O_NONBLOCK;
if (args->fmode & IBCS2_PRIV) bsd_mode |= O_EXLOCK;
if (args->fmode & IBCS2_CREAT) bsd_mode |= O_CREAT;
if (args->fmode & IBCS2_TRUNC) bsd_mode |= O_TRUNC | O_CREAT;
if (args->fmode & IBCS2_EXCL) bsd_mode |= O_EXCL;
if (args->fmode & IBCS2_NOCTTY) bsd_mode |= O_NOCTTY;
args->fmode = bsd_mode;
error = open(p, args, retval);
if (!error && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
struct filedesc *fdp = p->p_fd;
struct file *fp = fdp->fd_ofiles[*retval];
if (fp->f_type == DTYPE_VNODE)
(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
}
return error;
}
struct ibcs2_read_args {
int fd;
char *buffer;
unsigned int count;
};
int
ibcs2_read(struct proc *p, struct ibcs2_read_args *args, int *retval)
{
struct ibcs2_dir {
ibcs2_ino_t inode;
char fname[14];
} dirbuf;
struct vnode *vp;
struct file *fp;
struct uio auio;
struct iovec aiov;
caddr_t inp, buf, outp;
off_t off;
int buflen, error, eofflag;
int len, reclen, resid;
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'read' fd=%d, count=%d\n",
args->fd, args->count);
if (error = getvnode(p->p_fd, args->fd, &fp))
if (error == EINVAL)
return read(p, args, retval);
else
return error;
if ((fp->f_flag & FREAD) == 0)
return EBADF;
vp = (struct vnode *)fp->f_data;
if (vp->v_type != VDIR) {
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("normal read\n");
return read(p, args, retval);
}
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("read directory\n");
buflen = max(MAXBSIZE, args->count);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
off = fp->f_offset;
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_READ;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = p;
auio.uio_resid = buflen;
auio.uio_offset = off & ~(DIRBLKSIZ-1);
if (error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag))
goto out;
inp = buf + (off & (DIRBLKSIZ-1));
buflen -= off & (DIRBLKSIZ-1);
outp = args->buffer;
resid = args->count;
if ((len = buflen - auio.uio_resid) == 0)
goto eof;
for (; len > 0 && resid > 0; len -= reclen) {
reclen = BSD_DIRENT(inp)->d_reclen;
if (reclen & 3)
panic("ibcs2_read");
if (BSD_DIRENT(inp)->d_ino == 0) {
inp += reclen;
off += reclen;
continue;
}
if (reclen > len || resid < sizeof(struct ibcs2_dir)) {
outp++;
break;
}
/*
* TODO: break up name if > 14 chars
* put 14 chars in each dir entry wtih d_ino = 0xffff
* and set the last dir entry's d_ino = inode
*/
dirbuf.inode = (BSD_DIRENT(inp)->d_ino > 0x0000fffe) ?
0xfffe : BSD_DIRENT(inp)->d_ino;
bcopy(BSD_DIRENT(inp)->d_name, &dirbuf.fname, 14); /* XXX */
if (error = copyout(&dirbuf, outp, sizeof(dirbuf)))
goto out;
off += reclen;
inp += reclen;
outp += sizeof(struct ibcs2_dir);
resid -= sizeof(struct ibcs2_dir);
}
if (outp == args->buffer)
goto again;
fp->f_offset = off;
eof:
*retval = args->count - resid;
out:
VOP_UNLOCK(vp);
free(buf, M_TEMP);
return error;
}
struct ibcs2_seek_args {
int fdes;
ibcs2_off_t off;
int whence;
};
int
ibcs2_seek(struct proc *p, struct ibcs2_seek_args *args, int *retval)
{
struct seek_args {
int fdes;
int pad;
off_t off;
int whence;
} tmp_args;
off_t tmp_retval;
int error;
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'seek' fd=%d, offset=%d, how=%d\n",
args->fdes, args->off, args->whence);
tmp_args.fdes = args->fdes;
tmp_args.off = (off_t)args->off;
tmp_args.whence = args->whence;
error = lseek(p, &tmp_args, &tmp_retval);
*retval = (int)tmp_retval;
return error;
}
struct ibcs2_write_args {
int fd;
char *buffer;
unsigned int count;
};
int
ibcs2_write(struct proc *p, struct ibcs2_write_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_FILE)
printf("IBCS2: 'write' fd=%d, count=%d\n",
args->fd, args->count);
return write(p, args, retval);
}

View File

@ -0,0 +1,913 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_ioctl.c,v 1.13 1994/10/12 20:28:06 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/ioctl.h>
#include <sys/ioctl_compat.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/tty.h>
#include <sys/termios.h>
#include <machine/console.h>
struct ibcs2_termio {
unsigned short c_iflag;
unsigned short c_oflag;
unsigned short c_cflag;
unsigned short c_lflag;
char c_line;
unsigned char c_cc[IBCS2_NCC];
};
struct ibcs2_termios {
unsigned short c_iflag;
unsigned short c_oflag;
unsigned short c_cflag;
unsigned short c_lflag;
char c_line;
unsigned char c_cc[IBCS2_NCCS];
char c_ispeed;
char c_ospeed;
};
struct ibcs2_winsize {
char bytex, bytey;
short bitx, bity;
};
static struct speedtab sptab[] = {
{ 0, 0 }, { 50, 1 }, { 75, 2 }, { 110, 3 },
{ 134, 4 }, { 135, 4 }, { 150, 5 }, { 200, 6 },
{ 300, 7 }, { 600, 8 }, { 1200, 9 }, { 1800, 10 },
{ 2400, 11 }, { 4800, 12 }, { 9600, 13 },
{ 19200, 14 }, { 38400, 15 },
{ 57600, 15 }, { 115200, 15 }, {-1, -1 }
};
static int
ibcs2_to_bsd_speed(int code, struct speedtab *table)
{
for ( ; table->sp_code != -1; table++)
if (table->sp_code == code)
return (table->sp_speed);
return -1;
}
static int
bsd_to_ibcs2_speed(int speed, struct speedtab *table)
{
for ( ; table->sp_speed != -1; table++)
if (table->sp_speed == speed)
return (table->sp_code);
return -1;
}
static void
bsd_termios_to_ibcs2_termio(struct termios *bsd_termios,
struct ibcs2_termio *ibcs2_termio)
{
int speed;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: BSD termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
}
ibcs2_termio->c_iflag = bsd_termios->c_iflag &
(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK
|ISTRIP|INLCR|IGNCR|ICRNL|IXANY);
if (bsd_termios->c_iflag & IXON)
ibcs2_termio->c_iflag |= IBCS2_IXON;
if (bsd_termios->c_iflag & IXOFF)
ibcs2_termio->c_iflag |= IBCS2_IXOFF;
ibcs2_termio->c_oflag = 0;
if (bsd_termios->c_oflag & OPOST)
ibcs2_termio->c_oflag |= IBCS2_OPOST;
if (bsd_termios->c_oflag & ONLCR)
ibcs2_termio->c_oflag |= IBCS2_ONLCR;
if (bsd_termios->c_oflag & OXTABS)
ibcs2_termio->c_oflag |= (IBCS2_TAB1|IBCS2_TAB2);
speed = bsd_to_ibcs2_speed(bsd_termios->c_ospeed, sptab);
ibcs2_termio->c_cflag = speed >= 0 ? speed : 0;
ibcs2_termio->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; /* XXX */
if (bsd_termios->c_cflag & CSTOPB)
ibcs2_termio->c_cflag |= IBCS2_CSTOPB;
if (bsd_termios->c_cflag & PARENB)
ibcs2_termio->c_cflag |= IBCS2_PARENB;
if (bsd_termios->c_cflag & PARODD)
ibcs2_termio->c_cflag |= IBCS2_PARODD;
if (bsd_termios->c_cflag & HUPCL)
ibcs2_termio->c_cflag |= IBCS2_HUPCL;
if (bsd_termios->c_cflag & CLOCAL)
ibcs2_termio->c_cflag |= IBCS2_CLOCAL;
ibcs2_termio->c_lflag = 0;
if (bsd_termios->c_lflag & ISIG)
ibcs2_termio->c_lflag |= IBCS2_ISIG;
if (bsd_termios->c_lflag & ICANON)
ibcs2_termio->c_lflag |= IBCS2_ICANON;
if (bsd_termios->c_lflag & ECHO)
ibcs2_termio->c_lflag |= IBCS2_ECHO;
if (bsd_termios->c_lflag & ECHOE)
ibcs2_termio->c_lflag |= IBCS2_ECHOE;
if (bsd_termios->c_lflag & ECHOK)
ibcs2_termio->c_lflag |= IBCS2_ECHOK;
if (bsd_termios->c_lflag & ECHONL)
ibcs2_termio->c_lflag |= IBCS2_ECHONL;
if (bsd_termios->c_lflag & NOFLSH)
ibcs2_termio->c_lflag |= IBCS2_NOFLSH;
if (bsd_termios->c_lflag & ECHOCTL)
ibcs2_termio->c_lflag |= 0x0200; /* XXX */
if (bsd_termios->c_lflag & ECHOPRT)
ibcs2_termio->c_lflag |= 0x0400; /* XXX */
if (bsd_termios->c_lflag & ECHOKE)
ibcs2_termio->c_lflag |= 0x0800; /* XXX */
if (bsd_termios->c_lflag & IEXTEN)
ibcs2_termio->c_lflag |= 0x8000; /* XXX */
ibcs2_termio->c_cc[IBCS2_VINTR] = bsd_termios->c_cc[VINTR];
ibcs2_termio->c_cc[IBCS2_VQUIT] = bsd_termios->c_cc[VQUIT];
ibcs2_termio->c_cc[IBCS2_VERASE] = bsd_termios->c_cc[VERASE];
ibcs2_termio->c_cc[IBCS2_VKILL] = bsd_termios->c_cc[VKILL];
if (bsd_termios->c_lflag & ICANON) {
ibcs2_termio->c_cc[IBCS2_VEOF] = bsd_termios->c_cc[VEOF];
ibcs2_termio->c_cc[IBCS2_VEOL] = bsd_termios->c_cc[VEOL];
} else {
ibcs2_termio->c_cc[IBCS2_VMIN] = bsd_termios->c_cc[VMIN];
ibcs2_termio->c_cc[IBCS2_VTIME] = bsd_termios->c_cc[VTIME];
}
ibcs2_termio->c_cc[IBCS2_VEOL2] = bsd_termios->c_cc[VEOL2];
ibcs2_termio->c_cc[IBCS2_VSWTCH] = 0xff;
ibcs2_termio->c_line = 0;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: IBCS2 termio structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x speed=%d line=%d\n",
ibcs2_termio->c_iflag, ibcs2_termio->c_oflag,
ibcs2_termio->c_cflag, ibcs2_termio->c_lflag,
ibcs2_to_bsd_speed(
ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab),
ibcs2_termio->c_line);
printf("c_cc ");
for (i=0; i<IBCS2_NCC; i++)
printf("%02x ", ibcs2_termio->c_cc[i]);
printf("\n");
}
}
static void
ibcs2_termio_to_bsd_termios(struct ibcs2_termio *ibcs2_termio,
struct termios *bsd_termios)
{
int i, speed;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: IBCS2 termio structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x speed=%d line=%d\n",
ibcs2_termio->c_iflag, ibcs2_termio->c_oflag,
ibcs2_termio->c_cflag, ibcs2_termio->c_lflag,
ibcs2_to_bsd_speed(
ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab),
ibcs2_termio->c_line);
printf("c_cc ");
for (i=0; i<IBCS2_NCC; i++)
printf("%02x ", ibcs2_termio->c_cc[i]);
printf("\n");
}
bsd_termios->c_iflag = ibcs2_termio->c_iflag &
(IBCS2_IGNBRK|IBCS2_BRKINT|IBCS2_IGNPAR|IBCS2_PARMRK|IBCS2_INPCK
|IBCS2_ISTRIP|IBCS2_INLCR|IBCS2_IGNCR|IBCS2_ICRNL|IBCS2_IXANY);
if (ibcs2_termio->c_iflag & IBCS2_IXON)
bsd_termios->c_iflag |= IXON;
if (ibcs2_termio->c_iflag & IBCS2_IXOFF)
bsd_termios->c_iflag |= IXOFF;
bsd_termios->c_oflag = 0;
if (ibcs2_termio->c_oflag & IBCS2_OPOST)
bsd_termios->c_oflag |= OPOST;
if (ibcs2_termio->c_oflag & IBCS2_ONLCR)
bsd_termios->c_oflag |= ONLCR;
if (ibcs2_termio->c_oflag & (IBCS2_TAB1|IBCS2_TAB2))
bsd_termios->c_oflag |= OXTABS;
speed = ibcs2_to_bsd_speed(ibcs2_termio->c_cflag & IBCS2_CBAUD, sptab);
bsd_termios->c_ospeed = bsd_termios->c_ispeed = speed >= 0 ? speed : 0;
bsd_termios->c_cflag = (ibcs2_termio->c_cflag & IBCS2_CSIZE) << 4;
if (ibcs2_termio->c_cflag & IBCS2_CSTOPB)
bsd_termios->c_cflag |= CSTOPB;
if (ibcs2_termio->c_cflag & IBCS2_PARENB)
bsd_termios->c_cflag |= PARENB;
if (ibcs2_termio->c_cflag & IBCS2_PARODD)
bsd_termios->c_cflag |= PARODD;
if (ibcs2_termio->c_cflag & IBCS2_HUPCL)
bsd_termios->c_cflag |= HUPCL;
if (ibcs2_termio->c_cflag & IBCS2_CLOCAL)
bsd_termios->c_cflag |= CLOCAL;
bsd_termios->c_lflag = 0;
if (ibcs2_termio->c_lflag & IBCS2_ISIG)
bsd_termios->c_lflag |= ISIG;
if (ibcs2_termio->c_lflag & IBCS2_ICANON)
bsd_termios->c_lflag |= ICANON;
if (ibcs2_termio->c_lflag & IBCS2_ECHO)
bsd_termios->c_lflag |= ECHO;
if (ibcs2_termio->c_lflag & IBCS2_ECHOE)
bsd_termios->c_lflag |= ECHOE;
if (ibcs2_termio->c_lflag & IBCS2_ECHOK)
bsd_termios->c_lflag |= ECHOK;
if (ibcs2_termio->c_lflag & IBCS2_ECHONL)
bsd_termios->c_lflag |= ECHONL;
if (ibcs2_termio->c_lflag & IBCS2_NOFLSH)
bsd_termios->c_lflag |= NOFLSH;
if (ibcs2_termio->c_lflag & 0x0200) /* XXX */
bsd_termios->c_lflag |= ECHOCTL;
if (ibcs2_termio->c_lflag & 0x0400) /* XXX */
bsd_termios->c_lflag |= ECHOPRT;
if (ibcs2_termio->c_lflag & 0x0800) /* XXX */
bsd_termios->c_lflag |= ECHOKE;
if (ibcs2_termio->c_lflag & 0x8000) /* XXX */
bsd_termios->c_lflag |= IEXTEN;
for (i=0; i<NCCS; bsd_termios->c_cc[i++] = 0) ;
bsd_termios->c_cc[VINTR] = ibcs2_termio->c_cc[IBCS2_VINTR];
bsd_termios->c_cc[VQUIT] = ibcs2_termio->c_cc[IBCS2_VQUIT];
bsd_termios->c_cc[VERASE] = ibcs2_termio->c_cc[IBCS2_VERASE];
bsd_termios->c_cc[VKILL] = ibcs2_termio->c_cc[IBCS2_VKILL];
if (ibcs2_termio->c_lflag & IBCS2_ICANON) {
bsd_termios->c_cc[VEOF] = ibcs2_termio->c_cc[IBCS2_VEOF];
bsd_termios->c_cc[VEOL] = ibcs2_termio->c_cc[IBCS2_VEOL];
} else {
bsd_termios->c_cc[VMIN] = ibcs2_termio->c_cc[IBCS2_VMIN];
bsd_termios->c_cc[VTIME] = ibcs2_termio->c_cc[IBCS2_VTIME];
}
bsd_termios->c_cc[VEOL2] = ibcs2_termio->c_cc[IBCS2_VEOL2];
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: BSD termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
}
}
static void
bsd_to_ibcs2_termios(struct termios *bsd_termios,
struct ibcs2_termios *ibcs2_termios)
{
int speed;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: BSD termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
}
ibcs2_termios->c_iflag = bsd_termios->c_iflag &
(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK
|ISTRIP|INLCR|IGNCR|ICRNL|IXANY);
if (bsd_termios->c_iflag & IXON)
ibcs2_termios->c_iflag |= IBCS2_IXON;
if (bsd_termios->c_iflag & IXOFF)
ibcs2_termios->c_iflag |= IBCS2_IXOFF;
ibcs2_termios->c_oflag = 0;
if (bsd_termios->c_oflag & OPOST)
ibcs2_termios->c_oflag |= IBCS2_OPOST;
if (bsd_termios->c_oflag & ONLCR)
ibcs2_termios->c_oflag |= IBCS2_ONLCR;
if (bsd_termios->c_oflag & OXTABS)
ibcs2_termios->c_oflag |= (IBCS2_TAB1|IBCS2_TAB2);
ibcs2_termios->c_cflag = (bsd_termios->c_cflag & CSIZE) >> 4; /* XXX */
if (bsd_termios->c_cflag & CSTOPB)
ibcs2_termios->c_cflag |= IBCS2_CSTOPB;
if (bsd_termios->c_cflag & PARENB)
ibcs2_termios->c_cflag |= IBCS2_PARENB;
if (bsd_termios->c_cflag & PARODD)
ibcs2_termios->c_cflag |= IBCS2_PARODD;
if (bsd_termios->c_cflag & HUPCL)
ibcs2_termios->c_cflag |= IBCS2_HUPCL;
if (bsd_termios->c_cflag & CLOCAL)
ibcs2_termios->c_cflag |= IBCS2_CLOCAL;
if (bsd_termios->c_cflag & CRTSCTS)
ibcs2_termios->c_cflag |= 0x8000; /* XXX */
ibcs2_termios->c_lflag = 0;
if (bsd_termios->c_lflag & ISIG)
ibcs2_termios->c_lflag |= IBCS2_ISIG;
if (bsd_termios->c_lflag & ICANON)
ibcs2_termios->c_lflag |= IBCS2_ICANON;
if (bsd_termios->c_lflag & ECHO)
ibcs2_termios->c_lflag |= IBCS2_ECHO;
if (bsd_termios->c_lflag & ECHOE)
ibcs2_termios->c_lflag |= IBCS2_ECHOE;
if (bsd_termios->c_lflag & ECHOK)
ibcs2_termios->c_lflag |= IBCS2_ECHOK;
if (bsd_termios->c_lflag & ECHONL)
ibcs2_termios->c_lflag |= IBCS2_ECHONL;
if (bsd_termios->c_lflag & NOFLSH)
ibcs2_termios->c_lflag |= IBCS2_NOFLSH;
if (bsd_termios->c_lflag & ECHOCTL)
ibcs2_termios->c_lflag |= 0x0200; /* XXX */
if (bsd_termios->c_lflag & ECHOPRT)
ibcs2_termios->c_lflag |= 0x0400; /* XXX */
if (bsd_termios->c_lflag & ECHOKE)
ibcs2_termios->c_lflag |= 0x0800; /* XXX */
if (bsd_termios->c_lflag & IEXTEN)
ibcs2_termios->c_lflag |= 0x8000; /* XXX */
ibcs2_termios->c_cc[IBCS2_VINTR] = bsd_termios->c_cc[VINTR];
ibcs2_termios->c_cc[IBCS2_VQUIT] = bsd_termios->c_cc[VQUIT];
ibcs2_termios->c_cc[IBCS2_VERASE] = bsd_termios->c_cc[VERASE];
ibcs2_termios->c_cc[IBCS2_VKILL] = bsd_termios->c_cc[VKILL];
if (bsd_termios->c_lflag & ICANON) {
ibcs2_termios->c_cc[IBCS2_VEOF] = bsd_termios->c_cc[VEOF];
ibcs2_termios->c_cc[IBCS2_VEOL] = bsd_termios->c_cc[VEOL];
} else {
ibcs2_termios->c_cc[IBCS2_VMIN] = bsd_termios->c_cc[VMIN];
ibcs2_termios->c_cc[IBCS2_VTIME] = bsd_termios->c_cc[VTIME];
}
ibcs2_termios->c_cc[IBCS2_VEOL2] = bsd_termios->c_cc[VEOL2];
ibcs2_termios->c_cc[IBCS2_VSWTCH] = 0xff;
ibcs2_termios->c_cc[IBCS2_VSUSP] = bsd_termios->c_cc[VSUSP];
ibcs2_termios->c_cc[IBCS2_VSTART] = bsd_termios->c_cc[VSTART];
ibcs2_termios->c_cc[IBCS2_VSTOP] = bsd_termios->c_cc[VSTOP];
ibcs2_termios->c_ispeed =
bsd_to_ibcs2_speed(bsd_termios->c_ispeed, sptab);
ibcs2_termios->c_ospeed =
bsd_to_ibcs2_speed(bsd_termios->c_ospeed, sptab);
ibcs2_termios->c_line = 0;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: IBCS2 termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d "
"line=%d\n",
ibcs2_termios->c_iflag, ibcs2_termios->c_oflag,
ibcs2_termios->c_cflag, ibcs2_termios->c_lflag,
ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab),
ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab),
ibcs2_termios->c_line);
printf("c_cc ");
for (i=0; i<IBCS2_NCCS; i++)
printf("%02x ", ibcs2_termios->c_cc[i]);
printf("\n");
}
}
static void
ibcs2_to_bsd_termios(struct ibcs2_termios *ibcs2_termios,
struct termios *bsd_termios)
{
int i, speed;
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: IBCS2 termios structure (input):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d "
"line=%d\n",
ibcs2_termios->c_iflag, ibcs2_termios->c_oflag,
ibcs2_termios->c_cflag, ibcs2_termios->c_lflag,
ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab),
ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab),
ibcs2_termios->c_line);
printf("c_cc ");
for (i=0; i<IBCS2_NCCS; i++)
printf("%02x ", ibcs2_termios->c_cc[i]);
printf("\n");
}
bsd_termios->c_iflag = ibcs2_termios->c_iflag &
(IBCS2_IGNBRK|IBCS2_BRKINT|IBCS2_IGNPAR|IBCS2_PARMRK|IBCS2_INPCK
|IBCS2_ISTRIP|IBCS2_INLCR|IBCS2_IGNCR|IBCS2_ICRNL|IBCS2_IXANY);
if (ibcs2_termios->c_iflag & IBCS2_IXON)
bsd_termios->c_iflag |= IXON;
if (ibcs2_termios->c_iflag & IBCS2_IXOFF)
bsd_termios->c_iflag |= IXOFF;
bsd_termios->c_oflag = 0;
if (ibcs2_termios->c_oflag & IBCS2_OPOST)
bsd_termios->c_oflag |= OPOST;
if (ibcs2_termios->c_oflag & IBCS2_ONLCR)
bsd_termios->c_oflag |= ONLCR;
if (ibcs2_termios->c_oflag & (IBCS2_TAB1|IBCS2_TAB2))
bsd_termios->c_oflag |= OXTABS;
bsd_termios->c_cflag = (ibcs2_termios->c_cflag & IBCS2_CSIZE) << 4;
if (ibcs2_termios->c_cflag & IBCS2_CSTOPB)
bsd_termios->c_cflag |= CSTOPB;
if (ibcs2_termios->c_cflag & IBCS2_PARENB)
bsd_termios->c_cflag |= PARENB;
if (ibcs2_termios->c_cflag & IBCS2_PARODD)
bsd_termios->c_cflag |= PARODD;
if (ibcs2_termios->c_cflag & IBCS2_HUPCL)
bsd_termios->c_cflag |= HUPCL;
if (ibcs2_termios->c_cflag & IBCS2_CLOCAL)
bsd_termios->c_cflag |= CLOCAL;
if (ibcs2_termios->c_cflag & 0x8000)
bsd_termios->c_cflag |= CRTSCTS; /* XXX */
bsd_termios->c_lflag = 0;
if (ibcs2_termios->c_lflag & IBCS2_ISIG)
bsd_termios->c_lflag |= ISIG;
if (ibcs2_termios->c_lflag & IBCS2_ICANON)
bsd_termios->c_lflag |= ICANON;
if (ibcs2_termios->c_lflag & IBCS2_ECHO)
bsd_termios->c_lflag |= ECHO;
if (ibcs2_termios->c_lflag & IBCS2_ECHOE)
bsd_termios->c_lflag |= ECHOE;
if (ibcs2_termios->c_lflag & IBCS2_ECHOK)
bsd_termios->c_lflag |= ECHOK;
if (ibcs2_termios->c_lflag & IBCS2_ECHONL)
bsd_termios->c_lflag |= ECHONL;
if (ibcs2_termios->c_lflag & IBCS2_NOFLSH)
bsd_termios->c_lflag |= NOFLSH;
if (ibcs2_termios->c_lflag & 0x0200) /* XXX */
bsd_termios->c_lflag |= ECHOCTL;
if (ibcs2_termios->c_lflag & 0x0400) /* XXX */
bsd_termios->c_lflag |= ECHOPRT;
if (ibcs2_termios->c_lflag & 0x0800) /* XXX */
bsd_termios->c_lflag |= ECHOKE;
if (ibcs2_termios->c_lflag & 0x8000) /* XXX */
bsd_termios->c_lflag |= IEXTEN;
for (i=0; i<NCCS; bsd_termios->c_cc[i++] = 0) ;
bsd_termios->c_cc[VINTR] = ibcs2_termios->c_cc[IBCS2_VINTR];
bsd_termios->c_cc[VQUIT] = ibcs2_termios->c_cc[IBCS2_VQUIT];
bsd_termios->c_cc[VERASE] = ibcs2_termios->c_cc[IBCS2_VERASE];
bsd_termios->c_cc[VKILL] = ibcs2_termios->c_cc[IBCS2_VKILL];
if (ibcs2_termios->c_lflag & IBCS2_ICANON) {
bsd_termios->c_cc[VEOF] = ibcs2_termios->c_cc[IBCS2_VEOF];
bsd_termios->c_cc[VEOL] = ibcs2_termios->c_cc[IBCS2_VEOL];
} else {
bsd_termios->c_cc[VMIN] = ibcs2_termios->c_cc[IBCS2_VMIN];
bsd_termios->c_cc[VTIME] = ibcs2_termios->c_cc[IBCS2_VTIME];
}
bsd_termios->c_cc[VEOL2] = ibcs2_termios->c_cc[IBCS2_VEOL2];
bsd_termios->c_cc[VSUSP] = ibcs2_termios->c_cc[IBCS2_VSUSP];
bsd_termios->c_cc[VSTART] = ibcs2_termios->c_cc[IBCS2_VSTART];
bsd_termios->c_cc[VSTOP] = ibcs2_termios->c_cc[IBCS2_VSTOP];
bsd_termios->c_ispeed =
ibcs2_to_bsd_speed(ibcs2_termios->c_ispeed, sptab);
bsd_termios->c_ospeed =
ibcs2_to_bsd_speed(ibcs2_termios->c_ospeed, sptab);
if (ibcs2_trace & IBCS2_TRACE_IOCTLCNV) {
int i;
printf("IBCS2: BSD termios structure (output):\n");
printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n",
bsd_termios->c_iflag, bsd_termios->c_oflag,
bsd_termios->c_cflag, bsd_termios->c_lflag,
bsd_termios->c_ispeed, bsd_termios->c_ospeed);
printf("c_cc ");
for (i=0; i<NCCS; i++)
printf("%02x ", bsd_termios->c_cc[i]);
printf("\n");
}
}
struct ibcs2_ioctl_args {
int fd;
int cmd;
int arg;
};
int
ibcs2_ioctl(struct proc *p, struct ibcs2_ioctl_args *args, int *retval)
{
struct termios bsd_termios;
struct winsize bsd_winsize;
struct ibcs2_termio ibcs2_termio;
struct ibcs2_termios ibcs2_termios;
struct ibcs2_winsize ibcs2_winsize;
struct filedesc *fdp = p->p_fd;
struct file *fp;
int (*func)();
int type = (args->cmd&0xffff00)>>8;
int num = args->cmd&0xff;
int error;
if (ibcs2_trace & IBCS2_TRACE_IOCTL)
printf("IBCS2: 'ioctl' fd=%d, typ=%d(%c), num=%d\n",
args->fd, type, type, num);
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == 0)
return EBADF;
if (!fp || (fp->f_flag & (FREAD | FWRITE)) == 0) {
return EBADF;
}
func = fp->f_ops->fo_ioctl;
switch (type) {
case 'f':
switch (num) {
case 1:
args->cmd = FIOCLEX;
return ioctl(p, args, retval);
case 2:
args->cmd = FIONCLEX;
return ioctl(p, args, retval);
case 3:
args->cmd = FIONREAD;
return ioctl(p, args, retval);
}
break;
#if 0
case 'j':
switch (num) {
case 5: /* jerq winsize ?? */
ibcs2_winsize.bytex = 80;
/* p->p_session->s_ttyp->t_winsize.ws_col; XXX */
ibcs2_winsize.bytey = 25;
/* p->p_session->s_ttyp->t_winsize.ws_row; XXX */
ibcs2_winsize.bitx =
p->p_session->s_ttyp->t_winsize.ws_xpixel;
ibcs2_winsize.bity =
p->p_session->s_ttyp->t_winsize.ws_ypixel;
return copyout((caddr_t)&ibcs2_winsize,
(caddr_t)args->arg,
sizeof(ibcs2_winsize));
}
#endif
case 't':
switch (num) {
case 0:
args->cmd = TIOCGETD;
return ioctl(p, args, retval);
case 1:
args->cmd = TIOCSETD;
return ioctl(p, args, retval);
case 2:
args->cmd = TIOCHPCL;
return ioctl(p, args, retval);
case 8:
args->cmd = TIOCGETP;
return ioctl(p, args, retval);
case 9:
args->cmd = TIOCSETP;
return ioctl(p, args, retval);
case 10:
args->cmd = TIOCSETN;
return ioctl(p, args, retval);
case 13:
args->cmd = TIOCEXCL;
return ioctl(p, args, retval);
case 14:
args->cmd = TIOCNXCL;
return ioctl(p, args, retval);
case 16:
args->cmd = TIOCFLUSH;
return ioctl(p, args, retval);
case 17:
args->cmd = TIOCSETC;
return ioctl(p, args, retval);
case 18:
args->cmd = TIOCGETC;
return ioctl(p, args, retval);
}
break;
case 'T':
switch (num) {
case 1: /* TCGETA */
if ((error = (*func)(fp, TIOCGETA,
(caddr_t)&bsd_termios, p)) != 0)
return error;
bsd_termios_to_ibcs2_termio(&bsd_termios,&ibcs2_termio);
return copyout((caddr_t)&ibcs2_termio,
(caddr_t)args->arg,
sizeof(ibcs2_termio));
case 2: /* TCSETA */
ibcs2_termio_to_bsd_termios(
(struct ibcs2_termio *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
case 3: /* TCSETAW */
ibcs2_termio_to_bsd_termios(
(struct ibcs2_termio *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
case 4: /* TCSETAF */
ibcs2_termio_to_bsd_termios(
(struct ibcs2_termio *)args->arg, &bsd_termios);
return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
case 5: /* TCSBRK */
args->cmd = TIOCDRAIN;
if (error = ioctl(p, args, retval))
return error;
args->cmd = TIOCSBRK;
ioctl(p, args, retval);
args->cmd = TIOCCBRK;
error = ioctl(p, args, retval);
return error;
case 6: /* TCONC */
if (args->arg == 0) args->cmd = TIOCSTOP;
else args->cmd = TIOCSTART;
return ioctl(p, args, retval);
case 7: /* TCFLSH */
args->cmd = TIOCFLUSH;
if ((int)args->arg == 0) (int)args->arg = FREAD;
if ((int)args->arg == 1) (int)args->arg = FWRITE;
if ((int)args->arg == 2) (int)args->arg = FREAD|FWRITE;
return ioctl(p, args, retval);
case 103: /* TIOCSWINSZ */
bsd_winsize.ws_row =
((struct ibcs2_winsize *)(args->arg))->bytex;
bsd_winsize.ws_col =
((struct ibcs2_winsize *)(args->arg))->bytey;
bsd_winsize.ws_xpixel =
((struct ibcs2_winsize *)(args->arg))->bitx;
bsd_winsize.ws_ypixel =
((struct ibcs2_winsize *)(args->arg))->bity;
return (*func)(fp, TIOCSWINSZ,
(caddr_t)&bsd_winsize, p);
case 104: /* TIOCGWINSZ */
if ((error = (*func)(fp, TIOCGWINSZ,
(caddr_t)&bsd_winsize, p)) != 0)
return error;
ibcs2_winsize.bytex = bsd_winsize.ws_col;
ibcs2_winsize.bytey = bsd_winsize.ws_row;
ibcs2_winsize.bitx = bsd_winsize.ws_xpixel;
ibcs2_winsize.bity = bsd_winsize.ws_ypixel;
return copyout((caddr_t)&ibcs2_winsize,
(caddr_t)args->arg,
sizeof(ibcs2_winsize));
case 20: /* TCSETPGRP */
case 118: /* TIOCSPGRP */
args->cmd = TIOCSPGRP;
return ioctl(p, args, retval);
case 21: /* TCGETPGRP */
case 119: /* TIOCGPGRP */
args->cmd = TIOCGPGRP;
return ioctl(p, args, retval);
}
break;
case ('x'):
switch (num) {
case 1:
if ((error = (*func)(fp, TIOCGETA,
(caddr_t)&bsd_termios, p)) != 0)
return error;
bsd_to_ibcs2_termios(&bsd_termios, &ibcs2_termios);
return copyout((caddr_t)&ibcs2_termios,
(caddr_t)args->arg,
sizeof(ibcs2_termios));
case 2:
ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
&bsd_termios);
return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p);
case 3:
ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
&bsd_termios);
return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p);
case 4:
ibcs2_to_bsd_termios((struct ibcs2_termios *)args->arg,
&bsd_termios);
return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p);
}
break;
/* below is console ioctl's, we have syscons so no problem here */
case 'c':
switch (num) {
case 4:
args->cmd = CONS_BLANKTIME;
return ioctl(p, args, retval);
case 64:
args->cmd = PIO_FONT8x8;
return ioctl(p, args, retval);
case 65:
args->cmd = GIO_FONT8x8;
return ioctl(p, args, retval);
case 66:
args->cmd = PIO_FONT8x14;
return ioctl(p, args, retval);
case 67:
args->cmd = GIO_FONT8x14;
return ioctl(p, args, retval);
case 68:
args->cmd = PIO_FONT8x16;
return ioctl(p, args, retval);
case 69:
args->cmd = GIO_FONT8x16;
return ioctl(p, args, retval);
case 73:
args->cmd = CONS_GETINFO;
return ioctl(p, args, retval);
}
break;
case 'k':
switch (num) {
case 0:
args->cmd = GETFKEY;
return ioctl(p, args, retval);
case 1:
args->cmd = SETFKEY;
return ioctl(p, args, retval);
case 2:
args->cmd = GIO_SCRNMAP;
return ioctl(p, args, retval);
case 3:
args->cmd = PIO_SCRNMAP;
return ioctl(p, args, retval);
case 6:
args->cmd = GIO_KEYMAP;
return ioctl(p, args, retval);
case 7:
args->cmd = PIO_KEYMAP;
return ioctl(p, args, retval);
}
break;
case 'K':
switch (num) {
case 6:
args->cmd = KDGKBMODE;
return ioctl(p, args, retval);
case 7:
args->cmd = KDSKBMODE;
return ioctl(p, args, retval);
case 8:
args->cmd = KDMKTONE;
return ioctl(p, args, retval);
case 9:
args->cmd = KDGETMODE;
return ioctl(p, args, retval);
case 10:
args->cmd = KDSETMODE;
return ioctl(p, args, retval);
case 13:
args->cmd = KDSBORDER;
return ioctl(p, args, retval);
case 19:
args->cmd = KDGKBSTATE;
return ioctl(p, args, retval);
case 20:
args->cmd = KDSETRAD;
return ioctl(p, args, retval);
case 60:
args->cmd = KDENABIO;
return ioctl(p, args, retval);
case 61:
args->cmd = KDDISABIO;
return ioctl(p, args, retval);
case 63:
args->cmd = KIOCSOUND;
return ioctl(p, args, retval);
case 64:
args->cmd = KDGKBTYPE;
return ioctl(p, args, retval);
case 65:
args->cmd = KDGETLED;
return ioctl(p, args, retval);
case 66:
args->cmd = KDSETLED;
return ioctl(p, args, retval);
}
break;
case 'S':
args->cmd = _IO('S', num);
return ioctl(p, args, retval);
case 'v':
switch (num) {
case 1:
args->cmd = VT_OPENQRY;
return ioctl(p, args, retval);
case 2:
args->cmd = VT_SETMODE;
return ioctl(p, args, retval);
case 3:
args->cmd = VT_GETMODE;
return ioctl(p, args, retval);
case 4:
args->cmd = VT_RELDISP;
return ioctl(p, args, retval);
case 5:
args->cmd = VT_ACTIVATE;
return ioctl(p, args, retval);
case 6:
args->cmd = VT_WAITACTIVE;
return ioctl(p, args, retval);
}
break;
}
uprintf("IBCS2: 'ioctl' fd=%d, typ=%d(%c), num=%d not implemented\n",
args->fd, type, type, num);
return EINVAL;
}
struct ibcs2_sgtty_args {
int fd;
struct sgttyb *buf;
};
struct ioctl_args {
int fd;
int cmd;
caddr_t arg;
};
int
ibcs2_gtty(struct proc *p, struct ibcs2_sgtty_args *args, int *retval)
{
struct ioctl_args ioctl_arg;
if (ibcs2_trace & IBCS2_TRACE_IOCTL)
printf("IBCS2: 'gtty' fd=%d\n", args->fd);
ioctl_arg.fd = args->fd;
ioctl_arg.cmd = TIOCGETC;
ioctl_arg.arg = (caddr_t)args->buf;
return ioctl(p, &ioctl_arg, retval);
}
int
ibcs2_stty(struct proc *p, struct ibcs2_sgtty_args *args, int *retval)
{
struct ioctl_args ioctl_arg;
if (ibcs2_trace & IBCS2_TRACE_IOCTL)
printf("IBCS2: 'stty' fd=%d\n", args->fd);
ioctl_arg.fd = args->fd;
ioctl_arg.cmd = TIOCSETC;
ioctl_arg.arg = (caddr_t)args->buf;
return ioctl(p, &ioctl_arg, retval);
}

View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_ipc.c,v 1.3 1994/10/12 19:38:03 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/proc.h>
int
ibcs2_msgsys(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'msgsys'\n");
#ifdef SYSVMSG
return msgsys(p, args, retval);
#else
printf("IBCS2: 'msgsys' not implemented yet\n");
return EINVAL;
#endif
}
int
ibcs2_semsys(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'semsys'\n");
#ifdef SYSVSEM
return semsys(p, args, retval);
#else
printf("IBCS2: 'semsys' not implemented yet\n");
return EINVAL;
#endif
}
int
ibcs2_shmsys(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'shmsys'\n");
#ifdef SYSVSHM
return shmsys(p, args, retval);
#else
printf("IBCS2: 'shmsys' not implemented yet\n");
return EINVAL;
#endif
}

191
sys/i386/ibcs2/ibcs2_isc.c Normal file
View File

@ -0,0 +1,191 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_isc.c,v 1.5 1994/10/12 19:38:03 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/syslimits.h>
#include <sys/timeb.h>
#include <sys/unistd.h>
#include <sys/utsname.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
int
ibcs2_cisc(struct proc *p, void *args, int *retval)
{
struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
switch ((tf->tf_eax & 0xffffff00) >> 8) {
case 0x00:
printf("IBCS2: 'cisc #0' what is this ??\n");
return 0;
case 0x02:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc rename'\n");
return rename(p, args, retval);
case 0x03:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc sigaction'\n");
return ibcs2_sigaction(p, args, retval);
case 0x04:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc sigprocmask'\n");
return ibcs2_sigprocmask(p, args, retval);
case 0x05:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc sigpending'\n");
return ibcs2_sigpending(p, args, retval);
case 0x06:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc getgroups'\n");
return getgroups(p, args, retval);
case 0x07:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc setgroups'\n");
return setgroups(p, args, retval);
case 0x08: /* pathconf */
case 0x09: /* fpathconf */
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc (f)pathconf'");
return ibcs2_pathconf(p, args, retval);
case 0x10: { /* sysconf */
struct ibcs2_sysconf_args {
int num;
} *sysconf_args = args;
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc sysconf'");
switch (sysconf_args->num) {
case 0: /* _SC_ARG_MAX */
*retval = (ARG_MAX);
break;
case 1: /* _SC_CHILD_MAX */
*retval = (CHILD_MAX);
break;
case 2: /* _SC_CLK_TCK */
*retval = (CLK_TCK);
break;
case 3: /* _SC_NGROUPS_MAX */
*retval = (NGROUPS_MAX);
break;
case 4: /* _SC_OPEN_MAX */
*retval = (OPEN_MAX);
break;
case 5: /* _SC_JOB_CONTROL */
#ifdef _POSIX_JOB_CONTORL
*retval = _POSIX_JOB_CONTORL;
#else
*retval = (0);
#endif
break;
case 6: /* _SC_SAVED_IDS */
#ifdef _POSIX_SAVED_IDS
*retval = (_POSIX_SAVED_IDS);
#else
*retval = (0);
#endif
break;
case 7: /* _SC_VERSION */
*retval = (_POSIX_VERSION);
break;
default:
*retval = -1;
return EINVAL;
}
return 0;
}
case 0x0b:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc waitpid'\n");
return ibcs2_wait(p, args, retval);
case 0x0c:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc setsid'\n");
return setsid(p, args, retval);
case 0x0d:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc setpgid'\n");
return setpgid(p, args, retval);
case 0x11:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc sigsuspend'\n");
return ibcs2_sigsuspend(p, args, retval);
case 0x12:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc symlink'\n");
return symlink(p, args, retval);
case 0x13:
if (ibcs2_trace & IBCS2_TRACE_ISC)
printf("IBCS2: 'cisc readlink'\n");
return readlink(p, args, retval);
/* Here needs more work to be done */
case 0x01:
printf("IBCS2: 'cisc setostype'");
break;
case 0x0e:
printf("IBCS2: 'cisc adduser'");
break;
case 0x0f:
printf("IBCS2: 'cisc setuser'");
break;
case 0x14:
printf("IBCS2: 'cisc getmajor'");
break;
default:
printf("IBCS2: 'cisc' function %d(0x%x)",
tf->tf_eax>>8, tf->tf_eax>>8);
break;
}
printf(" not implemented yet\n");
return EINVAL;
}

968
sys/i386/ibcs2/ibcs2_misc.c Normal file
View File

@ -0,0 +1,968 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ibcs2_misc.c,v 1.16 1994/10/13 23:10:58 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/unistd.h>
#include <sys/wait.h>
#include <vm/vm.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
int ibcs2_trace = 0;
struct ibcs2_traceemu_args {
int options;
};
int
ibcs2_traceemu(struct proc *p, struct ibcs2_traceemu_args *args, int *retval)
{
*retval = ibcs2_trace;
ibcs2_trace = args->options;
return 0;
}
int
ibcs2_access(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'access'\n");
return access(p, args, retval);
}
struct ibcs2_alarm_args {
unsigned int secs;
};
int
ibcs2_alarm(struct proc *p, struct ibcs2_alarm_args *args, int *retval)
{
extern struct timeval time;
struct itimerval it, oit;
int s;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'alarm' secs=%d\n", args->secs);
it.it_value.tv_sec = (long)args->secs;
it.it_value.tv_usec = 0;
it.it_interval.tv_sec = 0;
it.it_interval.tv_usec = 0;
s = splclock();
oit = p->p_realtimer;
if (timerisset(&oit.it_value))
if (timercmp(&oit.it_value, &time, <))
timerclear(&oit.it_value);
else
timevalsub(&oit.it_value, &time);
splx(s);
if (itimerfix(&it.it_value) || itimerfix(&it.it_interval))
return EINVAL;
s = splclock();
untimeout(realitexpire, (caddr_t)p);
if (timerisset(&it.it_value)) {
timevaladd(&it.it_value, &time);
timeout(realitexpire, (caddr_t)p, hzto(&it.it_value));
}
p->p_realtimer = it;
splx(s);
if (oit.it_value.tv_usec)
oit.it_value.tv_sec++;
*retval = oit.it_value.tv_sec;
return 0;
}
struct ibcs2_break_args {
char *dsend;
};
int
ibcs2_break(struct proc *p, struct ibcs2_break_args *args, int *retval)
{
struct vmspace *vm = p->p_vmspace;
vm_offset_t new, old;
int rv, diff;
extern int swap_pager_full;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'break' dsend=%x\n",
(unsigned int)args->dsend);
if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr)
return EINVAL;
if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr)
> p->p_rlimit[RLIMIT_DATA].rlim_cur)
return ENOMEM;
old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize);
new = round_page((vm_offset_t)args->dsend);
diff = new - old;
if (diff > 0) {
if (swap_pager_full) {
return ENOMEM;
}
rv = vm_allocate(&vm->vm_map, &old, diff, FALSE);
if (rv != KERN_SUCCESS) {
return ENOMEM;
}
vm->vm_dsize += btoc(diff);
}
else if (diff < 0) {
diff = -diff;
rv = vm_deallocate(&vm->vm_map, new, diff);
if (rv != KERN_SUCCESS)
return ENOMEM;
vm->vm_dsize -= btoc(diff);
}
return 0;
}
int
ibcs2_chdir(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'chdir'\n");
return chdir(p, args, retval);
}
int
ibcs2_chmod(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'chmod'\n");
return chmod(p, args, retval);
}
int
ibcs2_chown(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'chown'\n");
return chown(p, args, retval);
}
int
ibcs2_chroot(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'chroot'\n");
return chroot(p, args, retval);
}
struct ibcs2_close_args {
int fd;
};
int
ibcs2_close(struct proc *p, struct ibcs2_close_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'close' fd=%d\n", args->fd);
return close(p, args, retval);
}
struct exec_args {
char *name;
char **argv;
};
int
ibcs2_exec(struct proc *p, struct exec_args *args, int *retval)
{
struct execve_args {
char *name;
char **argv;
char **envp;
} execve_args;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'exec' name=%s\n", args->name);
execve_args.name = args->name;
execve_args.argv = args->argv;
execve_args.envp = 0;
return execve(p, &execve_args, retval);
}
struct ibcs2_exece_args {
char *name;
char **argv;
char **envp;
};
int
ibcs2_exece(struct proc *p, struct ibcs2_exece_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'exece' name=%s\n", args->name);
return execve(p, args, retval);
}
int
ibcs2_exit(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'exit'\n");
return exit(p, args, retval);
}
int
ibcs2_fork(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'fork'\n");
return fork(p, args, retval);
}
int
ibcs2_fsync(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'fsync'\n");
return fsync(p, args, retval);
}
int
ibcs2_getgid(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'getgid'\n");
return getgid(p, args, retval);
}
struct ibcs2_getgroups_args {
int gidsetsize;
ibcs2_gid_t *gidset;
};
int
ibcs2_getgroups(struct proc *p, struct ibcs2_getgroups_args *args, int *retval)
{
struct getgroups_args {
u_int gidsetsize;
gid_t *gidset;
} tmp;
ibcs2_gid_t *ibcs2_gidset;
int i, error;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'getgroups'\n");
tmp.gidsetsize = args->gidsetsize;
tmp.gidset = (gid_t *)UA_ALLOC();
ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX];
if (error = getgroups(p, &tmp, retval))
return error;
for (i = 0; i < retval[0]; i++)
ibcs2_gidset[i] = (ibcs2_gid_t)tmp.gidset[i];
return copyout((caddr_t)ibcs2_gidset, (caddr_t)args->gidset,
sizeof(ibcs2_gid_t) * retval[0]);
}
int
ibcs2_getpid(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'getpid'\n");
return getpid(p, args, retval);
}
int
ibcs2_getuid(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'getuid'\n");
return getuid(p, args, retval);
}
struct gtime_args {
long *timeptr;
};
int
ibcs2_gtime(struct proc *p, struct gtime_args *args, int *retval)
{
int error = 0;
struct timeval tv;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'gtime'\n");
microtime(&tv);
*retval = tv.tv_sec;
if (args)
(long)args->timeptr = tv.tv_sec;
return error;
}
int
ibcs2_link(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'link'\n");
return link(p, args, retval);
}
int
ibcs2_mkdir(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'mkdir'\n");
return mkdir(p, args, retval);
}
struct ibcs2_mknod_args {
char *fname;
int fmode;
ibcs2_dev_t dev;
};
int
ibcs2_mknod(struct proc *p, struct ibcs2_mknod_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'mknod'\n");
if (S_ISFIFO(args->fmode))
return mkfifo(p, args, retval);
return mknod(p, args, retval);
}
struct ibcs2_nice_args {
int niceval;
};
int
ibcs2_nice(struct proc *p, struct ibcs2_nice_args *args, int *retval)
{
int error;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'nice'\n");
error = donice(p, p, args->niceval);
*retval = p->p_nice;
return error;
}
struct ibcs2_pathconf_args {
long unused;
int cmd;
};
int
ibcs2_pathconf(struct proc *p, struct ibcs2_pathconf_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: '(f)pathconf'\n");
switch (args->cmd) {
case 0: /* _PC_LINK_MAX */
*retval = (LINK_MAX);
break;
case 1: /* _PC_MAX_CANON */
*retval = (MAX_CANON);
break;
case 2: /* _PC_MAX_INPUT */
*retval = (MAX_INPUT);
break;
case 5: /* _PC_PATH_MAX */
*retval = (PATH_MAX);
break;
case 8: /* _PC_VDISABLE */
*retval = (_POSIX_VDISABLE);
break;
case 3: /* _PC_NAME_MAX */
*retval = (NAME_MAX);
break;
case 4: /* _PC_PATH_MAX */
*retval = (PATH_MAX);
break;
case 6: /* _PC_CHOWN_RESTRICTED */
#ifdef _POSIX_CHOWN_RESTRICTED
*retval = _POSIX_CHOWN_RESTRICTED;
#else
*retval = (0);
#endif
break;
case 7: /* _PC_NO_TRUNC */
#ifdef _POSIX_NO_TRUNC
*retval = _POSIX_NO_TRUNC;
#else
*retval = (1);
#endif
break;
default:
*retval = -1;
return EINVAL;
}
return 0;
}
int
ibcs2_pause(struct proc *p, void *args, int *retval)
{
int mask = 0;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'pause'\n");
return sigsuspend(p, &mask, retval);
}
int
ibcs2_pipe(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'pipe'\n");
return pipe(p, args, retval);
}
struct ibcs2_poll {
int fd;
short events;
short revents;
};
struct ibcs2_poll_args {
struct ibcs2_poll *fds;
unsigned long nfds;
int timeout;
};
int
ibcs2_poll(struct proc *p, struct ibcs2_poll_args *args, int *retval)
{
struct ibcs2_poll conv;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
struct select_args {
u_int nd;
fd_set *in, *ou, *ex;
struct timeval *tv;
} tmp_select;
int i, error;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'poll'\n");
if (args->nfds > FD_SETSIZE)
return EINVAL;
readfds = (fd_set *)UA_ALLOC();
FD_ZERO(readfds);
writefds = (fd_set *)UA_ALLOC() + sizeof(fd_set *);
FD_ZERO(writefds);
exceptfds = (fd_set *)UA_ALLOC() + 2*sizeof(fd_set *);
FD_ZERO(exceptfds);
timeout = (struct timeval *)UA_ALLOC() + 3*sizeof(fd_set *);
if (args->timeout == -1)
timeout = NULL;
else {
timeout->tv_usec = (args->timeout % 1000)*1000;
timeout->tv_sec = args->timeout / 1000;
}
tmp_select.nd = 0;
tmp_select.in = readfds;
tmp_select.ou = writefds;
tmp_select.ex = exceptfds;
tmp_select.tv = timeout;
for (i = 0; i < args->nfds; i++) {
if (error = copyin(args->fds + i*sizeof(struct ibcs2_poll),
&conv, sizeof(conv)))
return error;
conv.revents = 0;
if (conv.fd < 0 || conv.fd > FD_SETSIZE)
continue;
if (conv.fd >= tmp_select.nd)
tmp_select.nd = conv.fd + 1;
if (conv.events & IBCS2_READPOLL)
FD_SET(conv.fd, readfds);
if (conv.events & IBCS2_WRITEPOLL)
FD_SET(conv.fd, writefds);
FD_SET(conv.fd, exceptfds);
}
if (error = select(p, &tmp_select, retval))
return error;
if (*retval == 0)
return 0;
*retval = 0;
for (*retval = 0, i = 0; i < args->nfds; i++) {
copyin(args->fds + i*sizeof(struct ibcs2_poll),
&conv, sizeof(conv));
conv.revents = 0;
if (conv.fd < 0 || conv.fd > FD_SETSIZE)
/* should check for open as well */
conv.revents |= IBCS2_POLLNVAL;
else {
if (FD_ISSET(conv.fd, readfds))
conv.revents |= IBCS2_POLLIN;
if (FD_ISSET(conv.fd, writefds))
conv.revents |= IBCS2_POLLOUT;
if (FD_ISSET(conv.fd, exceptfds))
conv.revents |= IBCS2_POLLERR;
if (conv.revents)
++*retval;
}
if (error = copyout(&conv,
args->fds + i*sizeof(struct ibcs2_poll),
sizeof(conv)))
return error;
}
return 0;
}
struct ibcs2_procids_args {
int req;
int eax;
};
int
ibcs2_procids(struct proc *p, struct ibcs2_procids_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'procids' request=%d, eax=%x\n",
args->req, args->eax);
switch (args->req) {
case 0: /* getpgrp */
return getpgrp(p, args, retval);
case 1: /* setpgrp */
{
struct setpgid_args {
int pid;
int pgid;
} tmp;
tmp.pid = tmp.pgid = 0;
return setpgid(p, &tmp, retval);
}
case 2: /* setpgid */
return setpgid(p, args, retval);
case 3: /* setsid */
return setsid(p, args, retval);
default:
return EINVAL;
}
}
int
ibcs2_profil(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'profil'\n");
return profil(p, args, retval);
}
int
ibcs2_ptrace(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'ptrace'\n");
return ptrace(p, args, retval);
}
int
ibcs2_readlink(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'readlink'\n");
return readlink(p, args, retval);
}
int
ibcs2_rename(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'rename'\n");
return rename(p, args, retval);
}
int
ibcs2_rmdir(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'rmdir'\n");
return rmdir(p, args, retval);
}
struct ibcs2_secure_args {
int cmd;
int arg1;
int arg2;
int arg3;
int arg4;
int arg5;
};
int
ibcs2_secure(struct proc *p, struct ibcs2_secure_args *args, int *retval)
{
struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'secure'\n");
switch (args->cmd) {
case 1: /* get login uid */
*retval = p->p_ucred->cr_uid;
return EPERM;
case 2: /* set login uid */
default:
printf("IBCS2: 'secure' cmd=%d not implemented\n",args->cmd);
}
return EINVAL;
}
struct ibcs2_setgid_args {
ibcs2_gid_t gid;
};
int
ibcs2_setgid(struct proc *p, struct ibcs2_setgid_args *args, int *retval)
{
struct setgid_args {
gid_t gid;
} tmp;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'setgid'\n");
tmp.gid = (gid_t) args->gid;
return setgid(p, &tmp, retval);
}
struct ibcs2_setgroups_args {
int gidsetsize;
ibcs2_gid_t *gidset;
};
int
ibcs2_setgroups(struct proc *p, struct ibcs2_setgroups_args *args, int *retval)
{
struct setgroups_args {
u_int gidsetsize;
gid_t *gidset;
} tmp;
ibcs2_gid_t *ibcs2_gidset;
int i, error;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'setgroups'\n");
tmp.gidsetsize = args->gidsetsize;
tmp.gidset = (gid_t *)UA_ALLOC();
ibcs2_gidset = (ibcs2_gid_t *)&tmp.gidset[NGROUPS_MAX];
if (error = copyin((caddr_t)args->gidset, (caddr_t)ibcs2_gidset,
sizeof(ibcs2_gid_t) * tmp.gidsetsize))
return error;
for (i = 0; i < tmp.gidsetsize; i++)
tmp.gidset[i] = (gid_t)ibcs2_gidset[i];
return setgroups(p, &tmp, retval);
}
struct ibcs2_setuid_args {
ibcs2_uid_t uid;
};
int
ibcs2_setuid(struct proc *p, struct ibcs2_setuid_args *args, int *retval)
{
struct setuid_args {
uid_t uid;
} tmp;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'setuid'\n");
tmp.uid = (uid_t) args->uid;
return setuid(p, &tmp, retval);
}
int
ibcs2_smount(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'smount'\n");
return mount(p, args, retval);
}
struct ibcs2_stime_args {
long *timeptr;
};
int
ibcs2_stime(struct proc *p, struct ibcs2_stime_args *args, int *retval)
{
int error;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'stime'\n");
if (error = suser(p->p_ucred, &p->p_acflag))
return error;
if (args->timeptr) {
#if 0
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */
boottime.tv_sec += (long)args->timeptr - time.tv_sec;
s = splhigh();
time.tv_sec = (long)args->timeptr;
time.tv_usec = 0;
splx(s);
resettodr();
#else
printf("IBCS2: trying to set system time %d\n",
(long)args->timeptr);
#endif
}
return 0;
}
int
ibcs2_sumount(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'sumount'\n");
return unmount(p, args, retval);
}
int
ibcs2_symlink(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'symlink'\n");
return symlink(p, args, retval);
}
int
ibcs2_sync(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'sync'\n");
return sync(p, args, retval);
}
int
ibcs2_sysacct(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'sysacct'\n");
return acct(p, args, retval);
}
struct ibcs2_tms {
long tms_utime;
long tms_stime;
long tms_cutime;
long tms_cstime;
};
int
ibcs2_times(struct proc *p, struct ibcs2_tms *args, int *retval)
{
extern int hz;
struct timeval tv;
struct ibcs2_tms tms;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'times'\n");
tms.tms_utime = p->p_uticks;
tms.tms_stime = p->p_sticks;
tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz +
((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000);
tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz +
((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000);
microtime(&tv);
*retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000;
return (copyout((caddr_t)&tms,
(caddr_t)args->tms_utime,
sizeof(struct ibcs2_tms)));
}
struct ibcs2_ulimit_args {
int cmd;
long limit;
};
int
ibcs2_ulimit(struct proc *p, struct ibcs2_ulimit_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'ulimit'\n");
switch (args->cmd) {
case IBCS2_GETFSIZE:
*retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
return 0;
case IBCS2_SETFSIZE:
return EINVAL;
case IBCS2_GETPSIZE:
*retval = p->p_rlimit[RLIMIT_RSS].rlim_cur;
return 0;
case IBCS2_GETMOPEN:
*retval = p->p_rlimit[RLIMIT_NOFILE].rlim_cur;
return 0;
}
return EINVAL;
}
int
ibcs2_umask(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'umask'\n");
return umask(p, args, retval);
}
int
ibcs2_unlink(struct proc *p, void *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'unlink'\n");
return unlink(p, args, retval);
}
struct ibcs2_utime_args {
char *fname;
ibcs2_time_t *timeptr;
};
int
ibcs2_utime(struct proc *p, struct ibcs2_utime_args *args, int *retval)
{
struct bsd_utimes_args {
char *fname;
struct timeval *tptr;
} bsdutimes;
struct timeval tv;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'utime'\n");
tv.tv_sec = (long)args->timeptr;
tv.tv_usec = 0;
bsdutimes.tptr = &tv;
bsdutimes.fname = args->fname;
return utimes(p, &bsdutimes, retval);
}
struct ibcs2_utssys_args {
char *buf;
int mv;
int cmd;
};
int
ibcs2_utssys(struct proc *p, struct ibcs2_utssys_args *args, int *retval)
{
struct ibcs2_utsname {
char sysname[9];
char nodename[9];
char release[9];
char version[9];
char machine[9];
} ibcs2_uname;
extern char ostype[], hostname[], osrelease[], machine[];
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'utssys' cmd=%d\n", args->cmd);
switch(args->cmd) {
case 0: /* uname */
bzero(&ibcs2_uname, sizeof(struct ibcs2_utsname));
strncpy(ibcs2_uname.sysname, ostype, 8);
strncpy(ibcs2_uname.nodename, hostname, 8);
strncpy(ibcs2_uname.release, osrelease, 8);
strncpy(ibcs2_uname.version, version, 8);
strncpy(ibcs2_uname.machine, machine, 8);
return (copyout((caddr_t)&ibcs2_uname,
(caddr_t)args->buf,
sizeof(struct ibcs2_utsname)));
case 2: /* ustat */
printf("IBCS2: utssys(ustat) not implemented yet\n");
return EINVAL;
case 1: /* umask, obsolete */
default:
printf("IBCS2: 'utssys cmd (%d) not implemented yet'\n",
args->cmd);
return EINVAL;
}
}
int
ibcs2_wait(struct proc *p, void *args, int *retval)
{
struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
struct ibcs2_waitpid_args {
int pid;
int *status;
int options;
} *t = args;
struct wait4_args {
int pid;
int *status;
int options;
struct rusage *rusage;
int compat;
} tmp;
tmp.compat = 1;
tmp.rusage = 0;
if (ibcs2_trace & IBCS2_TRACE_MISC)
printf("IBCS2: 'wait'\n");
if ((tf->tf_eflags & (PSL_Z|PSL_PF|PSL_N|PSL_V))
== (PSL_Z|PSL_PF|PSL_N|PSL_V)) {
tmp.pid = t->pid;
tmp.status = t->status;
tmp.options = 0;
if (t->options & 02)
tmp.options |= WUNTRACED;
if (t->options & 01)
tmp.options |= WNOHANG;
tmp.options = t->options;
} else {
tmp.pid = WAIT_ANY;
tmp.status = (int*)t->pid;
tmp.options = 0;
}
return wait1(p, &tmp, retval);
}

View File

@ -0,0 +1,462 @@
/*-
* Copyright (c) 1994 Sean Eric Fagan
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ibcs2_signal.c,v 1.9 1994/10/12 19:38:03 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/ioctl.h>
#include <sys/ioctl_compat.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/namei.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <sys/stat.h>
#include <sys/tty.h>
#include <sys/termios.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
#define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD))
int bsd_to_ibcs2_signal[NSIG] = {
0, IBCS2_SIGHUP, IBCS2_SIGINT, IBCS2_SIGQUIT,
IBCS2_SIGILL, IBCS2_SIGTRAP, IBCS2_SIGABRT, IBCS2_SIGEMT,
IBCS2_SIGFPE, IBCS2_SIGKILL, IBCS2_SIGBUS, IBCS2_SIGSEGV,
IBCS2_SIGSYS, IBCS2_SIGPIPE, IBCS2_SIGALRM, IBCS2_SIGTERM,
IBCS2_SIGURG, IBCS2_SIGSTOP, IBCS2_SIGTSTP, IBCS2_SIGCONT,
IBCS2_SIGCHLD, IBCS2_SIGTTIN, IBCS2_SIGTTOU, IBCS2_SIGIO,
IBCS2_SIGGXCPU, IBCS2_SIGGXFSZ, IBCS2_SIGVTALRM, IBCS2_SIGPROF,
IBCS2_SIGWINCH, 0, IBCS2_SIGUSR1, IBCS2_SIGUSR2
};
int ibcs2_to_bsd_signal[IBCS2_NSIG] = {
0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT,
SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM,
SIGUSR1, SIGUSR2, SIGCHLD, 0, SIGWINCH, SIGURG, SIGIO, SIGSTOP,
SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM, SIGPROF, SIGXCPU, SIGXFSZ
};
static char ibcs2_sig_name[IBCS2_NSIG][10] = {
"UNKNOWN", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
"SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS", "SIGSEGV",
"SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1", "SIGUSR2",
"SIGCHLD", "SIGPWR", "SIGWINCH", "SIGURG", "SIGIO", "SIGSTOP",
"SIGTSTP", "SIGCONT", "SIGTTIN", "SIGTTOU", "SIGVTALRM",
"SIGPROF", "SIGXCPU", "SIGXFSZ"
};
/*#define LEGAL_SIG(x) \
(((x & IBCS2_SIGMASK) < IBCS2_NSIG) ? (x & IBCS2_SIGMASK) : (0))*/
int
LEGAL_SIG(int sig)
{
if ((sig & IBCS2_SIGMASK) > IBCS2_NSIG) {
printf("IBCS2: illegal ibcs2 signal %d(%08x)\n",
sig & IBCS2_SIGMASK, sig);
return 0;
}
else
return (sig & IBCS2_SIGMASK);
}
char *
ibcs2_sig_to_str(int sig)
{
if (sig > IBCS2_NSIG) {
printf("IBCS2: ibcs2 signal out of range (%d)\n", sig);
return ibcs2_sig_name[0];
}
else
return ibcs2_sig_name[sig];
}
static sig_t
ibcs2_to_bsd_sigfunc(ibcs2_sig_t func) {
switch ((int)func) {
case IBCS2_SIG_DFL:
return SIG_DFL;
case IBCS2_SIG_IGN:
return SIG_IGN;
case IBCS2_SIG_HOLD:
return SIG_HOLD;
default:
return func;
}
}
static ibcs2_sig_t
bsd_to_ibcs2_sigfunc(sig_t func) {
switch ((int)func) {
case SIG_DFL:
return IBCS2_SIG_DFL;
case SIG_IGN:
return IBCS2_SIG_IGN;
case SIG_CATCH:
printf("IBCS2: Oops - SIG_CATCH does not translate :-(\n");
return IBCS2_SIG_DFL;
case SIG_HOLD:
return IBCS2_SIG_HOLD;
default:
return func;
}
}
static sigset_t
ibcs2_to_bsd_sigmask(ibcs2_sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i < NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (ibcs2_to_bsd_signal[i]-1));
return new;
}
static ibcs2_sigset_t
bsd_to_ibcs2_sigmask(sigset_t mask) {
int i;
sigset_t new = 0;
for (i = 1; i < IBCS2_NSIG; i++)
if (mask & (1 << i-1))
new |= (1 << (bsd_to_ibcs2_signal[i]-1));
return new;
}
struct ibcs2_signal_args {
int signo;
ibcs2_sig_t func;
};
static int
ibcs2_sigset(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
struct sigaction tmp;
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
*retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
if (args->func == IBCS2_SIG_HOLD) {
(void) splhigh();
p->p_sigmask |= (sigmask(sig_bsd) &~ DONTMASK);
(void) spl0();
}
else {
tmp.sa_mask = sigmask(sig_bsd);
tmp.sa_handler = ibcs2_to_bsd_sigfunc(args->func);
tmp.sa_flags = 0;
setsigvec(p, sig_bsd, &tmp);
}
return 0;
}
static int
ibcs2_sighold(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
(void) splhigh();
*retval = p->p_sigmask;
p->p_sigmask |= (sigmask(sig_bsd) & ~DONTMASK);
(void) spl0();
return 0;
}
static int
ibcs2_sigrelse(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
(void) splhigh();
*retval = p->p_sigmask;
p->p_sigmask &= ~sigmask(sig_bsd);
(void) spl0();
return 0;
}
static int
ibcs2_sigignore(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
struct sigaction tmp;
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
tmp.sa_mask = sigmask(sig_bsd);
tmp.sa_handler = SIG_IGN;
tmp.sa_flags = 0;
*retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
setsigvec(p, sig_bsd, &tmp);
return 0;
}
static int
ibcs2_sigpause(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
struct sigacts *ps = p->p_sigacts;
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
ps->ps_oldmask = p->p_sigmask;
ps->ps_flags |= SAS_OLDMASK;
p->p_sigmask = sigmask(sig_bsd) &~ DONTMASK;
(void) tsleep((caddr_t) ps, PPAUSE|PCATCH, "i-pause", 0);
*retval = -1;
return EINTR;
}
static int
ibcs2_signal(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
struct sigaction tmp;
int sig_bsd = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
tmp.sa_mask = sigmask(sig_bsd);
tmp.sa_handler = ibcs2_to_bsd_sigfunc(args->func);
tmp.sa_flags = 0;
*retval = (int)bsd_to_ibcs2_sigfunc(p->p_sigacts->ps_sigact[sig_bsd]);
setsigvec(p, sig_bsd, &tmp);
return 0;
}
int
ibcs2_sigsys(struct proc *p, struct ibcs2_signal_args *args, int *retval)
{
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'sigsys' signo=%d(%s) ",
args->signo & IBCS2_SIGMASK,
ibcs2_sig_to_str(args->signo & IBCS2_SIGMASK));
switch (args->signo & ~IBCS2_SIGMASK ) {
case 0x0000:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("signal() func=%x\n", args->func);
return ibcs2_signal(p, args, retval);
case 0x0100:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("sigset() func=%x\n", args->func);
return ibcs2_sigset(p, args, retval);
case 0x0200:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("sighold()\n");
return ibcs2_sighold(p, args, retval);
case 0x0400:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("sigrelse()\n");
return ibcs2_sigrelse(p, args, retval);
case 0x0800:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("sigignore()\n");
return ibcs2_sigignore(p, args, retval);
case 0x1000:
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("sigpause()\n");
return ibcs2_sigpause(p, args, retval);
default:
printf("IBCS2: unknown signal action\n"); break;
}
*retval = -1;
return EINVAL;
}
struct ibcs2_sigaction_args {
int signo;
struct sigaction *osa, *nsa;
};
int
ibcs2_sigaction(struct proc *p, struct ibcs2_sigaction_args *args, int *retval)
{
struct sigaction vec;
register struct sigaction *sa;
register struct sigacts *ps = p->p_sigacts;
register int sig;
int bit, error;
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'sigaction' signo=%d(%s)\n",
args->signo, ibcs2_sig_to_str(args->signo));
sig = ibcs2_to_bsd_signal[LEGAL_SIG(args->signo)];
if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
*retval = -1;
return EINVAL;
}
sa = &vec;
if (args->osa) {
sa->sa_handler = ps->ps_sigact[sig];
sa->sa_mask = ps->ps_catchmask[sig];
bit = sigmask(sig);
sa->sa_flags = 0;
if (p->p_flag & SA_NOCLDSTOP)
sa->sa_flags = IBCS2_SA_NOCLDSTOP;
if (error = copyout((caddr_t)sa, (caddr_t)args->osa,
sizeof(vec))) {
*retval = -1;
return error;
}
}
if (args->nsa) {
if (error = copyin((caddr_t)args->nsa, (caddr_t)sa,
sizeof(vec))) {
*retval = -1;
return error;
}
/*
* iBCS2 only defines one SA_ flag right now
*/
if (vec.sa_flags & IBCS2_SA_NOCLDSTOP)
vec.sa_flags = SA_NOCLDSTOP;
setsigvec(p, sig, sa);
}
*retval = 0;
return 0;
}
struct ibcs2_sigprocmask_args {
int how;
unsigned long *mask;
unsigned long *omask;
};
int
ibcs2_sigprocmask(struct proc *p, struct ibcs2_sigprocmask_args *args, int *retval)
{
int error;
sigset_t umask;
sigset_t omask = bsd_to_ibcs2_sigmask(p->p_sigmask);
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'sigprocmask' how=%d\n", args->how);
if (error = copyin(args->mask, &umask, sizeof(args->mask))) {
*retval = -1;
return error;
}
umask = ibcs2_to_bsd_sigmask(umask);
if (args->omask)
if (error = copyout(&omask, args->omask, sizeof(args->omask))) {
*retval = -1;
return error;
}
(void) splhigh();
switch (args->how) {
case 0: /* SIG_SETMASK */
p->p_sigmask = umask &~ DONTMASK;
break;
case 1: /* SIG_BLOCK */
p->p_sigmask |= (umask &~ DONTMASK);
break;
case 2: /* SIG_UNBLOCK */
p->p_sigmask &= ~umask;
break;
default:
error = EINVAL;
break;
}
(void) spl0();
if (error)
*retval = -1;
else
*retval = 0;
return error;
}
struct ibcs2_sigpending_args {
unsigned long *sigs;
};
int
ibcs2_sigpending(struct proc *p, struct ibcs2_sigpending_args *args, int *retval)
{
int error;
sigset_t mask = bsd_to_ibcs2_sigmask(p->p_siglist);
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'sigpending' which=%x\n", args->sigs);
if (error = copyout(&mask, args->sigs, sizeof(unsigned long)))
*retval = -1;
else
*retval = 0;
return error;
}
struct ibcs2_sigsuspend_args {
sigset_t *mask;
};
int
ibcs2_sigsuspend(struct proc *p, struct ibcs2_sigsuspend_args *args, int *retval)
{
sigset_t mask = ibcs2_to_bsd_sigmask((sigset_t)args->mask);
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'sigsuspend'\n");
return sigsuspend(p, &mask, retval);
}
struct kill_args {
int pid;
int signo;
};
int
ibcs2_kill(struct proc *p, struct kill_args *args, int *retval)
{
struct kill_args tmp;
if (ibcs2_trace & IBCS2_TRACE_SIGNAL)
printf("IBCS2: 'kill' pid=%d, sig=%d(%s)\n", args->pid,
args->signo, ibcs2_sig_to_str(args->signo));
tmp.pid = args->pid;
tmp.signo = (args->signo < IBCS2_NSIG) ?
ibcs2_to_bsd_signal[args->signo] : IBCS2_NSIG;
return kill(p, &tmp, retval);
}

File diff suppressed because it is too large Load Diff

View File

@ -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 */
};

View File

@ -0,0 +1,285 @@
/*-
* Copyright (c) 1994 Sean Eric Fagan
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ibcs2_stats.c,v 1.11 1994/10/13 23:10:58 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
struct ibcs2_stat {
ibcs2_dev_t stat_dev;
ibcs2_ino_t stat_ino;
ibcs2_mode_t stat_mode;
ibcs2_nlink_t stat_nlink;
ibcs2_uid_t stat_uid;
ibcs2_gid_t stat_gid;
ibcs2_dev_t stat_rdev;
ibcs2_size_t stat_size;
ibcs2_time_t stat_atime;
ibcs2_time_t stat_mtime;
ibcs2_time_t stat_ctime;
};
struct ibcs2_stat_args {
char *path;
struct ibcs2_stat *buf;
};
static int
stat_copyout(struct stat *buf, void *ubuf)
{
struct ibcs2_stat tbuf;
tbuf.stat_dev = buf->st_dev;
tbuf.stat_ino = buf->st_ino;
tbuf.stat_mode = buf->st_mode;
tbuf.stat_nlink = buf->st_nlink;
tbuf.stat_uid = buf->st_uid;
tbuf.stat_gid = buf->st_gid;
tbuf.stat_rdev = buf->st_rdev;
tbuf.stat_size = buf->st_size;
tbuf.stat_atime = buf->st_atime;
tbuf.stat_mtime = buf->st_mtime;
tbuf.stat_ctime = buf->st_ctime;
return copyout(&tbuf, ubuf, sizeof(tbuf));
}
int
ibcs2_stat(struct proc *p, struct ibcs2_stat_args *args, int *retval)
{
struct stat buf;
struct ibcs2_stat tbuf;
struct nameidata nd;
int error;
if (ibcs2_trace & IBCS2_TRACE_STATS)
printf("IBCS2: 'stat' path=%s\n", args->path);
nd.ni_cnd.cn_nameiop = LOOKUP;
nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW;
nd.ni_cnd.cn_proc = curproc;
nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
nd.ni_segflg = UIO_USERSPACE;
nd.ni_dirp = args->path;
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = stat_copyout(&buf, args->buf);
return error;
}
int
ibcs2_lstat(struct proc *p, struct ibcs2_stat_args *args, int *retval)
{
struct stat buf;
struct ibcs2_stat tbuf;
struct nameidata nd;
int error;
if (ibcs2_trace & IBCS2_TRACE_STATS)
printf("IBCS2: 'lstat' path=%s\n", args->path);
nd.ni_cnd.cn_nameiop = LOOKUP;
nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW;
nd.ni_cnd.cn_proc = curproc;
nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
nd.ni_segflg = UIO_USERSPACE;
nd.ni_dirp = args->path;
error = namei(&nd);
if (!error) {
error = vn_stat(nd.ni_vp, &buf, p);
vput(nd.ni_vp);
}
if (!error)
error = stat_copyout(&buf, args->buf);
return error;
}
struct ibcs2_fstat_args {
int fd;
struct ibcs2_stat *buf;
};
int
ibcs2_fstat(struct proc *p, struct ibcs2_fstat_args *args, int *retval)
{
struct ibcs2_stat tbuf;
struct filedesc *fdp = p->p_fd;
struct file *fp;
struct stat buf;
int error;
if (ibcs2_trace & IBCS2_TRACE_STATS)
printf("IBCS2: 'fstat' fd=%d\n", args->fd);
if ((unsigned)args->fd >= fdp->fd_nfiles
|| (fp = fdp->fd_ofiles[args->fd]) == NULL)
return EBADF;
switch (fp->f_type) {
case DTYPE_VNODE:
error = vn_stat((struct vnode *)fp->f_data, &buf, p);
break;
case DTYPE_SOCKET:
error = soo_stat((struct socket *)fp->f_data, &buf);
break;
default:
panic("IBCS2 fstat");
/*NOTREACHED*/
}
if (!error)
error = stat_copyout(&buf, args->buf);
return error;
}
struct ibcs2_statfs {
short f_fstyp;
long f_bsize;
long f_frsize;
long f_blocks;
long f_bfree;
long f_files;
long f_ffree;
char f_fname[6];
char f_fpack[6];
};
struct ibcs2_statfs_args {
char *path;
struct statfs *buf;
int len;
int fstyp;
};
int
ibcs2_statfs(struct proc *p, struct ibcs2_statfs_args *args, int *retval)
{
struct mount *mp;
struct nameidata *ndp;
struct statfs *sp;
struct nameidata nd;
struct ibcs2_statfs tmp;
int error;
if (ibcs2_trace & IBCS2_TRACE_STATS)
printf("IBCS2: 'statfs' path=%s\n", args->path);
ndp = &nd;
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = FOLLOW;
ndp->ni_cnd.cn_proc = curproc;
ndp->ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
ndp->ni_segflg = UIO_USERSPACE;
ndp->ni_dirp = args->path;
if (error = namei(ndp))
return error;
mp = ndp->ni_vp->v_mount;
sp = &mp->mnt_stat;
vrele(ndp->ni_vp);
if (error = VFS_STATFS(mp, sp, p))
return error;
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
tmp.f_fstyp = sp->f_type;
tmp.f_bsize = sp->f_bsize;
tmp.f_frsize = sp->f_iosize;
tmp.f_blocks = sp->f_blocks;
tmp.f_bfree = sp->f_bfree;
tmp.f_ffree = sp->f_ffree;
tmp.f_files = sp->f_files;
bcopy (sp->f_mntonname, tmp.f_fname, 6);
bcopy (sp->f_mntfromname, tmp.f_fpack, 6);
return copyout((caddr_t)&tmp, (caddr_t)args->buf, args->len);
}
struct ibcs2_fstatfs_args {
int fd;
struct statfs *buf;
};
int
ibcs2_fstatfs(struct proc *p, struct ibcs2_fstatfs_args *args, int *retval)
{
struct file *fp;
struct mount *mp;
struct statfs *sp;
struct ibcs2_statfs tmp;
int error;
if (ibcs2_trace & IBCS2_TRACE_STATS)
printf("IBCS2: 'fstatfs' fd=%d\n", args->fd);
if (error = getvnode(p->p_fd, args->fd, &fp))
return error;
mp = ((struct vnode *)fp->f_data)->v_mount;
sp = &mp->mnt_stat;
if (error = VFS_STATFS(mp, sp, p))
return error;
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
tmp.f_fstyp = sp->f_type;
tmp.f_bsize = sp->f_bsize;
tmp.f_frsize = sp->f_iosize;
tmp.f_blocks = sp->f_blocks;
tmp.f_bfree = sp->f_bfree;
tmp.f_ffree = sp->f_ffree;
tmp.f_files = sp->f_files;
bcopy (sp->f_mntonname, tmp.f_fname, 6);
bcopy (sp->f_mntfromname, tmp.f_fpack, 6);
return copyout((caddr_t)&tmp, (caddr_t)args->buf,
sizeof(struct statfs));
}

View File

@ -0,0 +1,500 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* Copyright (c) 1994 Sean Eric Fagan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_sysent.c,v 1.14 1994/10/13 23:10:58 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/signal.h>
#include <sys/sysent.h>
#define NERR 80 /* XXX must match sys/errno.h */
/* errno conversion tables */
int bsd_to_svr3_errno[NERR] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 45, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 11, 91, 92, 93, 94,
95, 96,118, 97, 98, 99,100,101,102,103,
104,105,106,107,108, 63,110,111,112,113,
114,115, 31, 78,116,117,145, 11, 11, 11,
0, 66, 0, 0, 0, 0, 0, 46, 89, 0,
};
/* function defines */
int ibcs2_access();
int ibcs2_advfs();
int ibcs2_alarm();
int ibcs2_break();
int ibcs2_chdir();
int ibcs2_chmod();
int ibcs2_chown();
int ibcs2_chroot();
int ibcs2_cisc();
int ibcs2_clocal();
int ibcs2_close();
int ibcs2_creat();
int ibcs2_cxenix();
int ibcs2_dup();
int ibcs2_exec();
int ibcs2_exece();
int ibcs2_exit();
int ibcs2_fcntl();
int ibcs2_fork();
int ibcs2_fstat();
int ibcs2_fstatfs();
int ibcs2_fsync();
int ibcs2_getdents();
int ibcs2_getgid();
int ibcs2_getmsg();
int ibcs2_getpid();
int ibcs2_getuid();
int ibcs2_gtime();
int ibcs2_gtty();
int ibcs2_ioctl();
int ibcs2_kill();
int ibcs2_libattach();
int ibcs2_libdetach();
int ibcs2_link();
int ibcs2_lstat();
int ibcs2_mkdir();
int ibcs2_mknod();
int ibcs2_msgsys();
int ibcs2_nice();
int ibcs2_nosys();
int ibcs2_open();
int ibcs2_pause();
int ibcs2_pipe();
int ibcs2_plock();
int ibcs2_poll();
int ibcs2_procids();
int ibcs2_profil();
int ibcs2_ptrace();
int ibcs2_putmsg();
int ibcs2_read();
int ibcs2_readlink();
int ibcs2_rfdebug();
int ibcs2_rfstart();
int ibcs2_rfstop();
int ibcs2_rfsys();
int ibcs2_rmdir();
int ibcs2_rmount();
int ibcs2_rumount();
int ibcs2_secure();
int ibcs2_seek();
int ibcs2_semsys();
int ibcs2_setgid();
int ibcs2_setuid();
int ibcs2_shmsys();
int ibcs2_sigsys();
int ibcs2_smount();
int ibcs2_stat();
int ibcs2_statfs();
int ibcs2_stime();
int ibcs2_stty();
int ibcs2_sumount();
int ibcs2_symlink();
int ibcs2_sync();
int ibcs2_sysacct();
int ibcs2_sysfs();
int ibcs2_sysi86();
int ibcs2_times();
int ibcs2_uadmin();
int ibcs2_ulimit();
int ibcs2_umask();
int ibcs2_unadvfs();
int ibcs2_unlink();
int ibcs2_utime();
int ibcs2_utssys();
int ibcs2_wait();
int ibcs2_write();
int ibcs2_traceemu(); /* XXX */
int sigreturn(); /* XXX */
/* ibcs2 svr3 sysent table */
struct sysent svr3_sysent[] =
{
0, ibcs2_nosys, /* 0 = indir */
1, ibcs2_exit, /* 1 = exit */
0, ibcs2_fork, /* 2 = fork */
3, ibcs2_read, /* 3 = read */
3, ibcs2_write, /* 4 = write */
3, ibcs2_open, /* 5 = open */
1, ibcs2_close, /* 6 = close */
3, ibcs2_wait, /* 7 = wait */
2, ibcs2_creat, /* 8 = creat */
2, ibcs2_link, /* 9 = link */
1, ibcs2_unlink, /* 10 = unlink */
2, ibcs2_exec, /* 11 = exec */
1, ibcs2_chdir, /* 12 = chdir */
0, ibcs2_gtime, /* 13 = time */
3, ibcs2_mknod, /* 14 = mknod */
2, ibcs2_chmod, /* 15 = chmod */
3, ibcs2_chown, /* 16 = chown */
1, ibcs2_break, /* 17 = break */
2, ibcs2_stat, /* 18 = stat */
3, ibcs2_seek, /* 19 = seek */
0, ibcs2_getpid, /* 20 = getpid */
6, ibcs2_smount, /* 21 = mount */
1, ibcs2_sumount, /* 22 = umount */
1, ibcs2_setuid, /* 23 = setuid */
0, ibcs2_getuid, /* 24 = getuid */
1, ibcs2_stime, /* 25 = stime */
4, ibcs2_ptrace, /* 26 = ptrace */
1, ibcs2_alarm, /* 27 = alarm */
2, ibcs2_fstat, /* 28 = fstat */
0, ibcs2_pause, /* 29 = pause */
2, ibcs2_utime, /* 30 = utime */
2, ibcs2_stty, /* 31 = stty */
2, ibcs2_gtty, /* 32 = gtty */
2, ibcs2_access, /* 33 = access */
1, ibcs2_nice, /* 34 = nice */
4, ibcs2_statfs, /* 35 = statfs */
0, ibcs2_sync, /* 36 = sync */
2, ibcs2_kill, /* 37 = kill */
4, ibcs2_fstatfs, /* 38 = fstatfs */
1, ibcs2_procids, /* 39 = procids */
5, ibcs2_cxenix, /* 40 = XENIX special system call */
1, ibcs2_dup, /* 41 = dup */
1, ibcs2_pipe, /* 42 = pipe */
1, ibcs2_times, /* 43 = times */
4, ibcs2_profil, /* 44 = prof */
1, ibcs2_plock, /* 45 = proc lock */
1, ibcs2_setgid, /* 46 = setgid */
0, ibcs2_getgid, /* 47 = getgid */
2, ibcs2_sigsys, /* 48 = signal */
6, ibcs2_msgsys, /* 49 = IPC message */
4, ibcs2_sysi86, /* 50 = i386-specific system call */
1, ibcs2_sysacct, /* 51 = turn acct off/on */
4, ibcs2_shmsys, /* 52 = shared memory */
5, ibcs2_semsys, /* 53 = IPC semaphores */
3, ibcs2_ioctl, /* 54 = ioctl */
3, ibcs2_uadmin, /* 55 = uadmin */
0, ibcs2_nosys, /* 56 = reserved for exch */
3, ibcs2_utssys, /* 57 = utssys */
1, ibcs2_fsync, /* 58 = fsync */
3, ibcs2_exece, /* 59 = exece */
1, ibcs2_umask, /* 60 = umask */
1, ibcs2_chroot, /* 61 = chroot */
3, ibcs2_fcntl, /* 62 = fcntl */
2, ibcs2_ulimit, /* 63 = ulimit */
0, ibcs2_nosys, /* 64 = nosys */
0, ibcs2_nosys, /* 65 = nosys */
0, ibcs2_nosys, /* 66 = nosys */
0, ibcs2_nosys, /* 67 = file locking call */
0, ibcs2_nosys, /* 68 = local system calls */
0, ibcs2_nosys, /* 69 = inode open */
4, ibcs2_advfs, /* 70 = advfs */
1, ibcs2_unadvfs, /* 71 = unadvfs */
4, ibcs2_rmount, /* 72 = rmount */
1, ibcs2_rumount, /* 73 = rumount */
5, ibcs2_rfstart, /* 74 = rfstart */
0, ibcs2_nosys, /* 75 = not used */
1, ibcs2_rfdebug, /* 76 = rfdebug */
0, ibcs2_rfstop, /* 77 = rfstop */
6, ibcs2_rfsys, /* 78 = rfsys */
1, ibcs2_rmdir, /* 79 = rmdir */
2, ibcs2_mkdir, /* 80 = mkdir */
4, ibcs2_getdents, /* 81 = getdents */
3, ibcs2_libattach, /* 82 = libattach */
1, ibcs2_libdetach, /* 83 = libdetach */
3, ibcs2_sysfs, /* 84 = sysfs */
4, ibcs2_getmsg, /* 85 = getmsg */
4, ibcs2_putmsg, /* 86 = putmsg */
3, ibcs2_poll, /* 87 = poll */
0, ibcs2_nosys, /* 88 = not used */
6, ibcs2_secure, /* 89 = secureware */
2, ibcs2_symlink, /* 90 = symlink */
2, ibcs2_lstat, /* 91 = lstat */
3, ibcs2_readlink, /* 92 = readlink */
0, ibcs2_nosys, /* 93 = not used */
0, ibcs2_nosys, /* 94 = not used */
0, ibcs2_nosys, /* 95 = not used */
0, ibcs2_nosys, /* 96 = not used */
0, ibcs2_nosys, /* 97 = not used */
0, ibcs2_nosys, /* 98 = not used */
0, ibcs2_nosys, /* 99 = not used */
0, ibcs2_nosys, /* 100 = not used */
0, ibcs2_nosys, /* 101 = not used */
0, ibcs2_nosys, /* 102 = not used */
1, sigreturn, /* 103 = BSD sigreturn XXX */
0, ibcs2_nosys, /* 104 = not used */
5, ibcs2_cisc, /* 105 = ISC special */
0, ibcs2_nosys, /* 106 = not used */
0, ibcs2_nosys, /* 107 = not used */
0, ibcs2_nosys, /* 108 = not used */
0, ibcs2_nosys, /* 109 = not used */
0, ibcs2_nosys, /* 110 = not used */
0, ibcs2_nosys, /* 111 = not used */
0, ibcs2_nosys, /* 112 = not used */
0, ibcs2_nosys, /* 113 = not used */
0, ibcs2_nosys, /* 114 = not used */
0, ibcs2_nosys, /* 115 = not used */
0, ibcs2_nosys, /* 116 = not used */
0, ibcs2_nosys, /* 117 = not used */
0, ibcs2_nosys, /* 118 = not used */
0, ibcs2_nosys, /* 119 = not used */
0, ibcs2_nosys, /* 120 = not used */
0, ibcs2_nosys, /* 121 = not used */
0, ibcs2_nosys, /* 122 = not used */
0, ibcs2_nosys, /* 123 = not used */
0, ibcs2_nosys, /* 124 = not used */
0, ibcs2_nosys, /* 125 = not used */
1, ibcs2_traceemu, /* 126 = ibcs2 emulator trace cntl */
5, ibcs2_clocal, /* 127 = local system calls */
};
struct sysentvec ibcs2_svr3_sysvec = {
sizeof (svr3_sysent) / sizeof (svr3_sysent[0]),
svr3_sysent,
0x7F,
NSIG,
bsd_to_ibcs2_signal,
NERR,
bsd_to_svr3_errno
};
#if 0
int ibcs2_acancel();
int ibcs2_adjtime();
int ibcs2_context();
int ibcs2_evsys();
int ibcs2_evtrapret();
int ibcs2_fchdir();
int ibcs2_fchmod();
int ibcs2_fchown();
int ibcs2_fstatvfs();
int ibcs2_fxstat();
int ibcs2_getgroups();
int ibcs2_getpmsg();
int ibcs2_getrlimit();
int ibcs2_hrtsys();
int ibcs2_lchown();
int ibcs2_lxstat();
int ibcs2_memcntl();
int ibcs2_mincore();
int ibcs2_mmap();
int ibcs2_mprotect();
int ibcs2_munmap();
int ibcs2_pathconf();
int ibcs2_priocntlsys();
int ibcs2_putgmsg();
int ibcs2_readv();
int ibcs2_rename();
int ibcs2_setegid();
int ibcs2_seteuid();
int ibcs2_setgroups();
int ibcs2_setrlimit();
int ibcs2_sigaction();
int ibcs2_sigaltstack();
int ibcs2_sigpending();
int ibcs2_sigprocmask();
int ibcs2_sigsendsys();
int ibcs2_sigsuspend();
int ibcs2_statvfs();
int ibcs2_sysconfig();
int ibcs2_systeminfo();
int ibcs2_vfork();
int ibcs2_waitsys();
int ibcs2_writev();
int ibcs2_xmknod();
int ibcs2_xstat();
int bsd_to_svr4_errno[NERR] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 45, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 11,150,149, 95, 96,
97, 98, 99,120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,143,144,
145,146, 90, 78,147,148, 93, 11, 94, 11,
0, 0, 0, 0, 0, 0, 0, 46, 89, 0,
};
/* ibcs2 svr4 sysent table */
struct sysent svr4_sysent[] =
{
0, ibcs2_nosys, /* 0 = indir */
1, ibcs2_exit, /* 1 = exit */
0, ibcs2_fork, /* 2 = fork */
3, ibcs2_read, /* 3 = read */
3, ibcs2_write, /* 4 = write */
3, ibcs2_open, /* 5 = open */
1, ibcs2_close, /* 6 = close */
3, ibcs2_wait, /* 7 = wait */
2, ibcs2_creat, /* 8 = creat */
2, ibcs2_link, /* 9 = link */
1, ibcs2_unlink, /* 10 = unlink */
2, ibcs2_exec, /* 11 = exec */
1, ibcs2_chdir, /* 12 = chdir */
0, ibcs2_gtime, /* 13 = time */
3, ibcs2_mknod, /* 14 = mknod */
2, ibcs2_chmod, /* 15 = chmod */
3, ibcs2_chown, /* 16 = chown */
1, ibcs2_break, /* 17 = break */
2, ibcs2_stat, /* 18 = stat */
3, ibcs2_seek, /* 19 = seek */
0, ibcs2_getpid, /* 20 = getpid */
6, ibcs2_smount, /* 21 = mount */
1, ibcs2_sumount, /* 22 = umount */
1, ibcs2_setuid, /* 23 = setuid */
0, ibcs2_getuid, /* 24 = getuid */
1, ibcs2_stime, /* 25 = stime */
4, ibcs2_ptrace, /* 26 = ptrace */
1, ibcs2_alarm, /* 27 = alarm */
2, ibcs2_fstat, /* 28 = fstat */
0, ibcs2_pause, /* 29 = pause */
2, ibcs2_utime, /* 30 = utime */
2, ibcs2_stty, /* 31 = stty */
2, ibcs2_gtty, /* 32 = gtty */
2, ibcs2_access, /* 33 = access */
1, ibcs2_nice, /* 34 = nice */
4, ibcs2_statfs, /* 35 = statfs */
0, ibcs2_sync, /* 36 = sync */
2, ibcs2_kill, /* 37 = kill */
4, ibcs2_fstatfs, /* 38 = fstatfs */
1, ibcs2_procids, /* 39 = procids */
5, ibcs2_cxenix, /* 40 = XENIX special system call */
1, ibcs2_dup, /* 41 = dup */
1, ibcs2_pipe, /* 42 = pipe */
1, ibcs2_times, /* 43 = times */
4, ibcs2_profil, /* 44 = prof */
1, ibcs2_plock, /* 45 = proc lock */
1, ibcs2_setgid, /* 46 = setgid */
0, ibcs2_getgid, /* 47 = getgid */
2, ibcs2_sigsys, /* 48 = signal */
6, ibcs2_msgsys, /* 49 = IPC message */
4, ibcs2_sysi86, /* 50 = i386-specific system call */
1, ibcs2_sysacct, /* 51 = turn acct off/on */
4, ibcs2_shmsys, /* 52 = shared memory */
5, ibcs2_semsys, /* 53 = IPC semaphores */
3, ibcs2_ioctl, /* 54 = ioctl */
3, ibcs2_uadmin, /* 55 = uadmin */
0, ibcs2_nosys, /* 56 = reserved for exch */
3, ibcs2_utssys, /* 57 = utssys */
1, ibcs2_fsync, /* 58 = fsync */
3, ibcs2_exece, /* 59 = exece */
1, ibcs2_umask, /* 60 = umask */
1, ibcs2_chroot, /* 61 = chroot */
3, ibcs2_fcntl, /* 62 = fcntl */
2, ibcs2_ulimit, /* 63 = ulimit */
0, ibcs2_nosys, /* 64 = nosys */
0, ibcs2_nosys, /* 65 = nosys */
0, ibcs2_nosys, /* 66 = nosys */
0, ibcs2_nosys, /* 67 = file locking call */
0, ibcs2_nosys, /* 68 = local system calls */
0, ibcs2_nosys, /* 69 = inode open */
4, ibcs2_advfs, /* 70 = advfs */
1, ibcs2_unadvfs, /* 71 = unadvfs */
4, ibcs2_rmount, /* 72 = rmount */
1, ibcs2_rumount, /* 73 = rumount */
5, ibcs2_rfstart, /* 74 = rfstart */
0, ibcs2_nosys, /* 75 = not used */
1, ibcs2_rfdebug, /* 76 = rfdebug */
0, ibcs2_rfstop, /* 77 = rfstop */
6, ibcs2_rfsys, /* 78 = rfsys */
1, ibcs2_rmdir, /* 79 = rmdir */
2, ibcs2_mkdir, /* 80 = mkdir */
4, ibcs2_getdents, /* 81 = getdents */
3, ibcs2_libattach, /* 82 = libattach */
1, ibcs2_libdetach, /* 83 = libdetach */
3, ibcs2_sysfs, /* 84 = sysfs */
4, ibcs2_getmsg, /* 85 = getmsg */
4, ibcs2_putmsg, /* 86 = putmsg */
3, ibcs2_poll, /* 87 = poll */
6, ibcs2_lstat, /* 88 = lstat */
2, ibcs2_symlink, /* 89 = symlink */
3, ibcs2_readlink, /* 90 = readlink */
2, ibcs2_setgroups, /* 91 = setgroups */
2, ibcs2_getgroups, /* 92 = getgroups */
2, ibcs2_fchmod, /* 93 = fchmod */
3, ibcs2_fchown, /* 94 = fchown */
3, ibcs2_sigprocmask, /* 95 = sigprocmask */
0, ibcs2_sigsuspend, /* 96 = sigsuspend */
2, ibcs2_sigaltstack, /* 97 = sigaltstack */
3, ibcs2_sigaction, /* 98 = sigaction */
1, ibcs2_sigpending, /* 99 = sigpending */
0, ibcs2_context, /* 100 = context */
0, ibcs2_evsys, /* 101 = evsys */
0, ibcs2_evtrapret, /* 102 = evtrapret */
0, ibcs2_statvfs, /* 103 = statvfs */
0, ibcs2_fstatvfs, /* 104 = fstatvfs */
5, ibcs2_cisc, /* 105 = ISC special */
0, ibcs2_nfssys, /* 106 = nfssys */
0, ibcs2_waitsys, /* 107 = waitsys */
0, ibcs2_sigsendsys, /* 108 = sigsendsys */
0, ibcs2_hrtsys, /* 109 = hrtsys */
0, ibcs2_acancel, /* 110 = acancel */
0, ibcs2_async, /* 111 = async */
0, ibcs2_priocntlsys, /* 112 = priocntlsys */
0, ibcs2_pathconf, /* 113 = pathconf */
0, ibcs2_mincore, /* 114 = mincore */
6, ibcs2_mmap, /* 115 = mmap */
3, ibcs2_mprotect, /* 116 = mprotect */
2, ibcs2_munmap, /* 117 = munmap */
0, ibcs2_pathconf, /* 118 = fpathconf */
0, ibcs2_vfork, /* 119 = vfork */
0, ibcs2_fchdir, /* 120 = fchdir */
0, ibcs2_readv, /* 121 = readv */
0, ibcs2_writev, /* 122 = writev */
3, ibcs2_xstat, /* 123 = xstat */
3, ibcs2_lxstat, /* 124 = lxstat */
3, ibcs2_fxstat, /* 125 = fxstat */
4, ibcs2_xmknod, /* 126 = xmknod */
5, ibcs2_clocal, /* 127 = local system calls */
0, ibcs2_setrlimit, /* 128 = setrlimit */
0, ibcs2_getrlimit, /* 129 = getrlimit */
0, ibcs2_lchown, /* 130 = lchown */
0, ibcs2_memcntl, /* 131 = memcntl */
0, ibcs2_getpmsg, /* 132 = getpmsg */
0, ibcs2_putgmsg, /* 133 = putgmsg */
2, ibcs2_rename, /* 134 = rename */
1, ibcs2_uname, /* 135 = uname */
0, ibcs2_setegid, /* 136 = setegid */
0, ibcs2_sysconfig, /* 137 = sysconfig */
0, ibcs2_adjtime, /* 138 = adjtime */
0, ibcs2_systeminfo, /* 139 = systeminfo */
0, ibcs2_nosys, /* 140 = not used */
0, ibcs2_seteuid, /* 141 = seteuid */
};
struct sysentvec ibcs2_svr4_sysvec = {
sizeof (svr4_sysent) / sizeof (svr4_sysent[0]),
svr4_sysent,
0xFF,
NSIG,
bsd_to_ibcs2_signal,
NERR,
bsd_to_svr4_errno
};
#endif

View File

@ -0,0 +1,68 @@
/*-
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_sysi86.c,v 1.4 1994/10/12 19:38:38 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
struct ibcs2_sysi86_args {
int cmd;
int *arg;
};
int
ibcs2_sysi86(struct proc *p, struct ibcs2_sysi86_args *args, int *retval)
{
switch (args->cmd) {
case 0x28: { /* SI86_FPHW */
int val, error;
extern int hw_float;
if (hw_float) val = IBCS2_FP_387; /* FPU hardware */
else val = IBCS2_FP_SW; /* FPU emulator */
if (error = copyout(&val, args->arg, sizeof(val)))
return error;
return 0;
}
case 0x33: /* SI86_MEM */
*retval = ctob(physmem);
return 0;
default:
printf("IBCS2: 'sysi86' function %d(0x%x) "
"not implemented yet\n", args->cmd, args->cmd);
return EINVAL;
}
}

View File

@ -0,0 +1,367 @@
/*-
* Copyright (c) 1994 Sean Eric Fagan
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ibcs2_xenix.c,v 1.10 1994/10/12 19:38:38 sos Exp $
*/
#include <i386/ibcs2/ibcs2.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/syslimits.h>
#include <sys/unistd.h>
#include <sys/timeb.h>
#include <vm/vm.h>
#include <machine/cpu.h>
#include <machine/psl.h>
#include <machine/reg.h>
struct ibcs2_sco_chsize_args {
int fd;
ibcs2_off_t size;
};
static int
sco_chsize(struct proc *p, struct ibcs2_sco_chsize_args *args, int *retval)
{
struct ftruncate_args {
int fd;
int pad;
off_t length;
} tmp;
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix chsize'\n");
tmp.fd = args->fd;
tmp.pad = 0;
tmp.length = args->size;
return ftruncate(p, &tmp, retval);
}
struct ibcs2_sco_ftime_args {
struct timeb *tp;
};
static int
sco_ftime(struct proc *p, struct ibcs2_sco_ftime_args *args, int *retval)
{
struct timeval atv;
extern struct timezone tz;
struct timeb tb;
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix ftime'\n");
microtime(&atv);
tb.time = atv.tv_sec;
tb.millitm = atv.tv_usec / 1000;
tb.timezone = tz.tz_minuteswest;
tb.dstflag = tz.tz_dsttime != DST_NONE;
return copyout((caddr_t)&tb, (caddr_t)args->tp, sizeof(struct timeb));
}
struct ibcs2_sco_nap_args {
long time;
};
static int
sco_nap(struct proc *p, struct ibcs2_sco_nap_args *args, int *retval)
{
long period;
extern int hz;
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix nap %d ms'\n", args->time);
period = (long)args->time / (1000/hz);
if (period)
while (tsleep(&period, PUSER, "nap", period)
!= EWOULDBLOCK) ;
return 0;
}
struct ibcs2_sco_rdchk_args {
int fd;
};
static int
sco_rdchk(struct proc *p, struct ibcs2_sco_rdchk_args *args, int *retval)
{
struct ioctl_arg {
int fd;
int cmd;
caddr_t arg;
} tmp;
int error;
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix rdchk'\n");
tmp.fd = args->fd;
tmp.cmd = FIONREAD;
tmp.arg = (caddr_t)UA_ALLOC();
error = ioctl(p, &tmp, retval);
if (!error)
*retval = *retval <= 0 ? 0 : 1;
return error;
}
struct ibcs2_sco_utsname_args {
long addr;
};
static int
sco_utsname(struct proc *p, struct ibcs2_sco_utsname_args *args, int *retval)
{
struct ibcs2_sco_utsname {
char sysname[9];
char nodename[9];
char release[16];
char kernelid[20];
char machine[9];
char bustype[9];
char sysserial[10];
unsigned short sysorigin;
unsigned short sysoem;
char numusers[9];
unsigned short numcpu;
} ibcs2_sco_uname;
extern char ostype[], hostname[], osrelease[], version[], machine[];
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sco_utsname'\n");
bzero(&ibcs2_sco_uname, sizeof(struct ibcs2_sco_utsname));
strncpy(ibcs2_sco_uname.sysname, ostype, 8);
strncpy(ibcs2_sco_uname.nodename, hostname, 8);
strncpy(ibcs2_sco_uname.release, osrelease, 15);
strncpy(ibcs2_sco_uname.kernelid, version, 19);
strncpy(ibcs2_sco_uname.machine, machine, 8);
bcopy("ISA/EISA", ibcs2_sco_uname.bustype, 8);
bcopy("no charge", ibcs2_sco_uname.sysserial, 9);
bcopy("unlim", ibcs2_sco_uname.numusers, 8);
ibcs2_sco_uname.sysorigin = 0xFFFF;
ibcs2_sco_uname.sysoem = 0xFFFF;
ibcs2_sco_uname.numcpu = 1;
return copyout((caddr_t)&ibcs2_sco_uname, (caddr_t)args->addr,
sizeof(struct ibcs2_sco_utsname));
}
int
ibcs2_cxenix(struct proc *p, void *args, int *retval)
{
struct trapframe *tf = (struct trapframe *)p->p_md.md_regs;
switch ((tf->tf_eax & 0xff00) >> 8) {
case 0x07: /* rdchk */
return sco_rdchk(p, args, retval);
case 0x0a: /* chsize */
return sco_chsize(p, args, retval);
case 0x0b: /* ftime */
return sco_ftime(p, args, retval);
case 0x0c: /* nap */
return sco_nap(p, args, retval);
case 0x15: /* scoinfo (not documented) */
*retval = 0;
return 0;
case 0x24: /* select */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix select'\n");
return select(p, args, retval);
case 0x25: /* eaccess */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix eaccess'\n");
return ibcs2_access(p, args, retval);
case 0x27: /* sigaction */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sigaction'\n");
return ibcs2_sigaction (p, args, retval);
case 0x28: /* sigprocmask */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sigprocmask'\n");
return ibcs2_sigprocmask (p, args, retval);
case 0x29: /* sigpending */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sigpending'\n");
return ibcs2_sigpending (p, args, retval);
case 0x2a: /* sigsuspend */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sigsuspend'\n");
return ibcs2_sigsuspend (p, args, retval);
case 0x2b: /* getgroups */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix getgroups'\n");
return ibcs2_getgroups(p, args, retval);
case 0x2c: /* setgroups */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix setgroups'\n");
return ibcs2_setgroups(p, args, retval);
case 0x2d: { /* sysconf */
struct ibcs2_sysconf_args {
int num;
} *sysconf_args = args;
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix sysconf'");
switch (sysconf_args->num) {
case 0: /* _SC_ARG_MAX */
*retval = (ARG_MAX);
break;
case 1: /* _SC_CHILD_MAX */
*retval = (CHILD_MAX);
break;
case 2: /* _SC_CLK_TCK */
*retval = (CLK_TCK);
break;
case 3: /* _SC_NGROUPS_MAX */
*retval = (NGROUPS_MAX);
break;
case 4: /* _SC_OPEN_MAX */
*retval = (OPEN_MAX);
break;
case 5: /* _SC_JOB_CONTROL */
#ifdef _POSIX_JOB_CONTORL
*retval = _POSIX_JOB_CONTORL;
#else
*retval = (0);
#endif
break;
case 6: /* _SC_SAVED_IDS */
#ifdef _POSIX_SAVED_IDS
*retval = (_POSIX_SAVED_IDS);
#else
*retval = (0);
#endif
break;
case 7: /* _SC_VERSION */
*retval = (_POSIX_VERSION);
break;
default:
*retval = -1;
return EINVAL;
}
return 0;
}
case 0x2e: /* pathconf */
case 0x2f: /* fpathconf */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix (f)pathconf'\n");
return ibcs2_pathconf(p, args, retval);
case 0x30: /* rename */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix rename'\n");
return ibcs2_rename(p, args, retval);
case 0x32: /* sco_utsname */
return sco_utsname(p, args, retval);
case 0x37: /* getitimer */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix getitimer'\n");
return getitimer(p, args, retval);
case 0x38: /* setitimer */
if (ibcs2_trace & IBCS2_TRACE_XENIX)
printf("IBCS2: 'cxenix setitimer'\n");
return setitimer(p, args, retval);
/* Not implemented yet SORRY */
case 0x01: /* xlocking */
printf("IBCS2: 'cxenix xlocking'");
break;
case 0x02: /* creatsem */
printf("IBCS2: 'cxenix creatsem'");
break;
case 0x03: /* opensem */
printf("IBCS2: 'cxenix opensem'");
break;
case 0x04: /* sigsem */
printf("IBCS2: 'cxenix sigsem'");
break;
case 0x05: /* waitsem */
printf("IBCS2: 'cxenix waitsem'");
break;
case 0x06: /* nbwaitsem */
printf("IBCS2: 'cxenix nbwaitsem'");
break;
case 0x0d: /* sdget */
printf("IBCS2: 'cxenix sdget'");
break;
case 0x0e: /* sdfree */
printf("IBCS2: 'cxenix sdfree'");
break;
case 0x0f: /* sdenter */
printf("IBCS2: 'cxenix sdenter'");
break;
case 0x10: /* sdleave */
printf("IBCS2: 'cxenix sdleave'");
break;
case 0x11: /* sdgetv */
printf("IBCS2: 'cxenix sdgetv'");
break;
case 0x12: /* sdwaitv */
printf("IBCS2: 'cxenix sdwaitv'");
break;
case 0x20: /* proctl */
printf("IBCS2: 'cxenix proctl'");
break;
case 0x21: /* execseg */
printf("IBCS2: 'cxenix execseg'");
break;
case 0x22: /* unexecseg */
printf("IBCS2: 'cxenix unexecseg'");
break;
case 0x26: /* paccess */
printf("IBCS2: 'cxenix paccess'");
break;
default:
printf("IBCS2: 'cxenix' function %d(0x%x)",
tf->tf_eax>>8, tf->tf_eax>>8);
break;
}
printf(" not implemented yet\n");
return EINVAL;
}

View File

@ -0,0 +1,457 @@
/*-
* Copyright (c) 1994 Sean Eric Fagan
* Copyright (c) 1994 Søren Schmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer
* in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: imgact_coff.c,v 1.11 1994/10/12 19:38:03 sos Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
#include <sys/exec.h>
#include <sys/mman.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/sysent.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include "coff.h"
#include "ibcs2.h"
static int
load_coff_section(vmspace, vp, offset, vmaddr, memsz, filsz, prot)
struct vmspace *vmspace;
struct vnode *vp;
vm_offset_t offset;
caddr_t vmaddr;
size_t memsz, filsz;
vm_prot_t prot;
{
size_t map_len;
vm_offset_t map_offset;
caddr_t map_addr;
int error;
unsigned char *data_buf = 0;
size_t copy_len;
map_offset = trunc_page(offset);
map_addr = (caddr_t)trunc_page(vmaddr);
if (memsz > filsz) {
/*
* We have the stupid situation that
* the section is longer than it is on file,
* which means it has zero-filled areas, and
* we have to work for it. Stupid iBCS!
*/
map_len = trunc_page(offset + filsz) - trunc_page(map_offset);
} else {
/*
* The only stuff we care about is on disk, and we
* don't care if we map in more than is really there.
*/
map_len = round_page(offset + filsz) - trunc_page(map_offset);
}
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): vm_mmap(&vmspace->vm_map, &0x%08lx, 0x%x, 0x%x, "
"VM_PROT_ALL, MAP_FILE | MAP_PRIVATE | MAP_FIXED, vp, 0x%x)\n",
__FILE__, __LINE__, map_addr, map_len, prot, map_offset);
}
if (error = vm_mmap(&vmspace->vm_map,
&map_addr,
map_len,
prot,
VM_PROT_ALL,
MAP_FILE | MAP_PRIVATE | MAP_FIXED,
vp,
map_offset))
return error;
if (memsz == filsz) {
/* We're done! */
return 0;
}
/*
* Now we have screwball stuff, to accomodate stupid COFF.
* We have to map the remaining bit of the file into the kernel's
* memory map, allocate some anonymous memory, copy that last
* bit into it, and then we're done. *sigh*
* For clean-up reasons, we actally map in the file last.
*/
copy_len = (offset + filsz) - trunc_page(offset + filsz);
map_addr = (caddr_t)trunc_page(vmaddr + filsz);
map_len = round_page(memsz) - trunc_page(filsz);
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): vm_allocate(&vmspace->vm_map, &0x%08lx, 0x%x, FALSE)\n",
__FILE__, __LINE__, map_addr, map_len);
}
if (error = vm_allocate(&vmspace->vm_map, &map_addr, map_len, FALSE))
return error;
if (error = vm_mmap(kernel_map, &data_buf, PAGE_SIZE,
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
vp, trunc_page(offset + filsz)))
return error;
bcopy(data_buf, map_addr, copy_len);
if (vm_deallocate(kernel_map, data_buf, PAGE_SIZE))
panic("load_coff_section vm_deallocate failed");
return 0;
}
int
coff_load_file(struct proc *p, char *name)
{
struct vmspace *vmspace = p->p_vmspace;
int error;
struct nameidata nd;
struct vnode *vnodep;
struct vattr attr;
struct filehdr *fhdr;
struct aouthdr *ahdr;
struct scnhdr *scns;
char *ptr = 0;
int nscns;
unsigned long text_offset = 0, text_address = 0, text_size = 0;
unsigned long data_offset = 0, data_address = 0, data_size = 0;
unsigned long bss_size = 0;
int i;
nd.ni_cnd.cn_nameiop = LOOKUP;
nd.ni_cnd.cn_flags = LOCKLEAF | FOLLOW | SAVENAME;
nd.ni_cnd.cn_proc = curproc;
nd.ni_cnd.cn_cred = curproc->p_cred->pc_ucred;
nd.ni_segflg = UIO_SYSSPACE;
nd.ni_dirp = name;
error = namei(&nd);
if (error)
return error;
vnodep = nd.ni_vp;
if (vnodep == NULL)
return ENOEXEC;
if (vnodep->v_writecount) {
error = ETXTBSY;
goto fail;
}
if (error = VOP_GETATTR(vnodep, &attr, p->p_ucred, p))
goto fail;
if ((vnodep->v_mount->mnt_flag & MNT_NOEXEC)
|| ((attr.va_mode & 0111) == 0)
|| (attr.va_type != VREG))
goto fail;
if (attr.va_size == 0) {
error = ENOEXEC;
goto fail;
}
if (error = VOP_ACCESS(vnodep, VEXEC, p->p_ucred, p))
goto fail;
if (error = VOP_OPEN(vnodep, FREAD, p->p_ucred, p))
goto fail;
if (error = vm_mmap(kernel_map, &ptr, PAGE_SIZE, VM_PROT_READ,
VM_PROT_READ, MAP_FILE, vnodep, 0))
goto fail;
fhdr = (struct filehdr *)ptr;
if (fhdr->f_magic != I386_COFF) {
error = ENOEXEC;
goto dealloc_and_fail;
}
nscns = fhdr->f_nscns;
if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
/*
* XXX -- just fail. I'm so lazy.
*/
error = ENOEXEC;
goto dealloc_and_fail;
}
ahdr = (struct aouthdr*)(ptr + sizeof(struct filehdr));
scns = (struct scnhdr*)(ptr + sizeof(struct filehdr)
+ sizeof(struct aouthdr));
for (i = 0; i < nscns; i++) {
if (scns[i].s_flags & STYP_NOLOAD)
continue;
else if (scns[i].s_flags & STYP_TEXT) {
text_address = scns[i].s_vaddr;
text_size = scns[i].s_size;
text_offset = scns[i].s_scnptr;
}
else if (scns[i].s_flags & STYP_DATA) {
data_address = scns[i].s_vaddr;
data_size = scns[i].s_size;
data_offset = scns[i].s_scnptr;
} else if (scns[i].s_flags & STYP_BSS) {
bss_size = scns[i].s_size;
}
}
if (error = load_coff_section(vmspace, vnodep, text_offset,
(caddr_t)text_address,
text_size, text_size,
VM_PROT_READ | VM_PROT_EXECUTE)) {
goto dealloc_and_fail;
}
if (error = load_coff_section(vmspace, vnodep, data_offset,
(caddr_t)data_address,
data_size + bss_size, data_size,
VM_PROT_ALL)) {
goto dealloc_and_fail;
}
error = 0;
dealloc_and_fail:
if (vm_deallocate(kernel_map, ptr, PAGE_SIZE))
panic(__FUNCTION__ " vm_deallocate failed");
fail:
vput(nd.ni_vp);
FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
return error;
}
int
exec_coff_imgact(iparams)
struct image_params *iparams;
{
struct filehdr *fhdr = (struct filehdr*)iparams->image_header;
struct aouthdr *ahdr;
struct scnhdr *scns;
int i;
struct vmspace *vmspace = iparams->proc->p_vmspace;
unsigned long vmaddr;
int nscns;
int error, len;
extern struct sysentvec ibcs2_svr3_sysvec;
unsigned long text_offset = 0, text_address = 0, text_size = 0;
unsigned long data_offset = 0, data_address = 0, data_size = 0;
unsigned long bss_size = 0;
int need_hack_p;
unsigned long data_end;
unsigned long data_map_start, data_map_len, data_map_addr = 0;
unsigned long bss_address, bss_map_start, data_copy_len, bss_map_len;
unsigned char *data_buf = 0;
caddr_t hole;
if (fhdr->f_magic != I386_COFF ||
!(fhdr->f_flags & F_EXEC)) {
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): return -1\n", __FILE__, __LINE__);
}
return -1;
}
nscns = fhdr->f_nscns;
if ((nscns * sizeof(struct scnhdr)) > PAGE_SIZE) {
/*
* For now, return an error -- need to be able to
* read in all of the section structures.
*/
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): return -1\n", __FILE__, __LINE__);
}
return -1;
}
ahdr = (struct aouthdr*)((char*)(iparams->image_header) +
sizeof(struct filehdr));
iparams->entry_addr = ahdr->entry;
scns = (struct scnhdr*)((char*)(iparams->image_header) +
sizeof(struct filehdr) +
sizeof(struct aouthdr));
if (error = exec_extract_strings(iparams)) {
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): return %d\n", __FILE__, __LINE__, error);
}
return error;
}
exec_new_vmspace(iparams);
for (i = 0; i < nscns; i++) {
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("i = %d, scns[i].s_name = %s, scns[i].s_vaddr = %08lx, "
"scns[i].s_scnptr = %d\n", i, scns[i].s_name,
scns[i].s_vaddr, scns[i].s_scnptr);
}
if (scns[i].s_flags & STYP_NOLOAD) {
/*
* A section that is not loaded, for whatever
* reason. It takes precedance over other flag
* bits...
*/
continue;
} else if (scns[i].s_flags & STYP_TEXT) {
text_address = scns[i].s_vaddr;
text_size = scns[i].s_size;
text_offset = scns[i].s_scnptr;
} else if (scns[i].s_flags & STYP_DATA) {
/* .data section */
data_address = scns[i].s_vaddr;
data_size = scns[i].s_size;
data_offset = scns[i].s_scnptr;
} else if (scns[i].s_flags & STYP_BSS) {
/* .bss section */
bss_size = scns[i].s_size;
} else if (scns[i].s_flags & STYP_LIB) {
char *buf = 0, *ptr;
int foff = trunc_page(scns[i].s_scnptr);
int off = scns[i].s_scnptr - foff;
int len = round_page(scns[i].s_size + PAGE_SIZE);
int j;
if (error = vm_mmap(kernel_map, &buf, len,
VM_PROT_READ, VM_PROT_READ, MAP_FILE,
iparams->vnodep, foff)) {
return ENOEXEC;
}
for (j = off; j < scns[i].s_size + off; j++) {
char *libname;
libname = buf + j + 4 * *(long*)(buf + j + 4);
j += 4* *(long*)(buf + j);
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): shared library %s\n", __FILE__, __LINE__, libname);
}
error = coff_load_file(iparams->proc, libname);
if (error)
break;
}
if (vm_deallocate(kernel_map, buf, len))
panic("exec_coff_imgact vm_deallocate failed");
if (error)
return error;
}
}
/*
* Map in .text now
*/
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): load_coff_section(vmspace, "
"iparams->vnodep, %08lx, %08lx, 0x%x, 0x%x, 0x%x)\n",
__FILE__, __LINE__, text_offset, text_address,
text_size, text_size, VM_PROT_READ | VM_PROT_EXECUTE);
}
if (error = load_coff_section(vmspace, iparams->vnodep,
text_offset, (caddr_t)text_address,
text_size, text_size,
VM_PROT_READ | VM_PROT_EXECUTE)) {
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
}
return error;
}
/*
* Map in .data and .bss now
*/
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): load_coff_section(vmspace, "
"iparams->vnodep, 0x%08lx, 0x%08lx, 0x%x, 0x%x, 0x%x)\n",
__FILE__, __LINE__, data_offset, data_address,
data_size + bss_size, data_size, VM_PROT_ALL);
}
if (error = load_coff_section(vmspace, iparams->vnodep,
data_offset, (caddr_t)data_address,
data_size + bss_size, data_size,
VM_PROT_ALL)) {
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
}
return error;
}
iparams->interpreted = 0;
iparams->proc->p_sysent = &ibcs2_svr3_sysvec;
vmspace->vm_tsize = round_page(text_size) >> PAGE_SHIFT;
vmspace->vm_dsize = round_page(data_size + bss_size) >> PAGE_SHIFT;
vmspace->vm_taddr = (caddr_t)text_address;
vmspace->vm_daddr = (caddr_t)data_address;
hole = (caddr_t)trunc_page(vmspace->vm_daddr) + ctob(vmspace->vm_dsize);
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("%s(%d): vm_allocate(&vmspace->vm_map, &0x%08lx, 1, FALSE)\n",
__FILE__, __LINE__, hole);
printf("imgact: error = %d\n", error);
}
error = vm_allocate(&vmspace->vm_map, &hole, 1, FALSE);
if (ibcs2_trace & IBCS2_TRACE_COFF) {
printf("IBCS2: start vm_dsize = 0x%x, vm_daddr = 0x%x end = 0x%x\n",
ctob(vmspace->vm_dsize), vmspace->vm_daddr,
ctob(vmspace->vm_dsize) + vmspace->vm_daddr );
printf("%s(%d): returning successfully!\n", __FILE__, __LINE__);
}
return 0;
}
/*
* Tell kern_execve.c about it, with a little help from the linker.
* Since `const' objects end up in the text segment, TEXT_SET is the
* correct directive to use.
*/
const struct execsw coff_execsw = { exec_coff_imgact, "coff" };
TEXT_SET(execsw_set, coff_execsw);