diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 8bdb3a7c5c23..0918f221fd3f 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1,454 +1,452 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_file.c,v 1.3 1995/10/10 23:13:27 swallace Exp $ + * $Id: linux_file.c,v 1.4 1995/11/22 07:43:45 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_creat_args { char *path; int mode; }; int linux_creat(struct proc *p, struct linux_creat_args *args, int *retval) { - struct { + struct open_args /* { char *path; int flags; int mode; - } bsd_open_args; + } */ bsd_open_args; #ifdef DEBUG printf("Linux-emul(%d): creat(%s, %d)\n", p->p_pid, args->path, args->mode); #endif bsd_open_args.path = args->path; bsd_open_args.mode = args->mode; bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC; return open(p, &bsd_open_args, retval); } struct linux_open_args { char *path; int flags; int mode; }; int linux_open(struct proc *p, struct linux_open_args *args, int *retval) { - struct { + struct open_args /* { char *path; int flags; int mode; - } bsd_open_args; + } */ bsd_open_args; int error; #ifdef DEBUG printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n", p->p_pid, args->path, args->flags, args->mode); #endif bsd_open_args.flags = 0; if (args->flags & LINUX_O_RDONLY) bsd_open_args.flags |= O_RDONLY; if (args->flags & LINUX_O_WRONLY) bsd_open_args.flags |= O_WRONLY; if (args->flags & LINUX_O_RDWR) bsd_open_args.flags |= O_RDWR; if (args->flags & LINUX_O_NDELAY) bsd_open_args.flags |= O_NONBLOCK; if (args->flags & LINUX_O_APPEND) bsd_open_args.flags |= O_APPEND; if (args->flags & LINUX_O_SYNC) bsd_open_args.flags |= O_FSYNC; if (args->flags & LINUX_O_NONBLOCK) bsd_open_args.flags |= O_NONBLOCK; if (args->flags & LINUX_FASYNC) bsd_open_args.flags |= O_ASYNC; if (args->flags & LINUX_O_CREAT) bsd_open_args.flags |= O_CREAT; if (args->flags & LINUX_O_TRUNC) bsd_open_args.flags |= O_TRUNC; if (args->flags & LINUX_O_EXCL) bsd_open_args.flags |= O_EXCL; if (args->flags & LINUX_O_NOCTTY) bsd_open_args.flags |= O_NOCTTY; bsd_open_args.path = args->path; bsd_open_args.mode = args->mode; error = open(p, &bsd_open_args, retval); if (!error && !(bsd_open_args.flags & O_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 linux_flock { short l_type; short l_whence; linux_off_t l_start; linux_off_t l_len; linux_pid_t l_pid; }; static void linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; } static void bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (linux_off_t)bsd_flock->l_start; linux_flock->l_len = (linux_off_t)bsd_flock->l_len; linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid; } struct linux_fcntl_args { int fd; int cmd; int arg; }; int linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval) { int error, result; - struct fcntl_args { + struct fcntl_args /* { int fd; int cmd; int arg; - } fcntl_args; + } */ fcntl_args; struct linux_flock linux_flock; struct flock *bsd_flock = (struct flock *)ua_alloc_init(sizeof(struct flock)); #ifdef DEBUG printf("Linux-emul(%d): fcntl(%d, %08x, *)\n", p->p_pid, args->fd, args->cmd); #endif fcntl_args.fd = args->fd; fcntl_args.arg = 0; switch (args->cmd) { case LINUX_F_DUPFD: fcntl_args.cmd = F_DUPFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETFD: fcntl_args.cmd = F_GETFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETFD: fcntl_args.cmd = F_SETFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETFL: fcntl_args.cmd = F_GETFL; error = fcntl(p, &fcntl_args, &result); *retval = 0; if (result & O_RDONLY) *retval |= LINUX_O_RDONLY; if (result & O_WRONLY) *retval |= LINUX_O_WRONLY; if (result & O_RDWR) *retval |= LINUX_O_RDWR; if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK; if (result & O_APPEND) *retval |= LINUX_O_APPEND; if (result & O_FSYNC) *retval |= LINUX_O_SYNC; return error; case LINUX_F_SETFL: if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND; if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC; fcntl_args.cmd = F_SETFL; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETLK: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_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_linux_flock(bsd_flock, &linux_flock); return copyout((caddr_t)&linux_flock, (caddr_t)args->arg, sizeof(struct linux_flock)); case LINUX_F_SETLK: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_flock, bsd_flock); fcntl_args.cmd = F_SETLK; fcntl_args.arg = (int)bsd_flock; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETLKW: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_flock, bsd_flock); fcntl_args.cmd = F_SETLKW; fcntl_args.arg = (int)bsd_flock; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETOWN: fcntl_args.cmd = F_SETOWN; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETOWN: fcntl_args.cmd = F_GETOWN; return fcntl(p, &fcntl_args, retval); } return EINVAL; } struct linux_lseek_args { int fdes; unsigned long off; int whence; }; int linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval) { - struct lseek_args { - int fdes; + struct lseek_args /* { + int fd; int pad; - off_t off; + off_t offset; int whence; - } tmp_args; - off_t tmp_retval; + } */ tmp_args; int error; #ifdef DEBUG printf("Linux-emul(%d): lseek(%d, %d, %d)\n", p->p_pid, args->fdes, args->off, args->whence); #endif - tmp_args.fdes = args->fdes; - tmp_args.off = (off_t)args->off; + tmp_args.fd = args->fdes; + tmp_args.offset = (off_t)args->off; tmp_args.whence = args->whence; - error = lseek(p, &tmp_args, &tmp_retval); - *retval = (int)tmp_retval; + error = lseek(p, &tmp_args, retval); return error; } struct linux_dirent { long dino; linux_off_t doff; unsigned short dreclen; char dname[LINUX_NAME_MAX + 1]; }; #define LINUX_RECLEN(de,namlen) \ ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1)) struct linux_readdir_args { int fd; struct linux_dirent *dent; unsigned int count; }; int linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval) { register struct dirent *bdp; struct vnode *vp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ int resid, linuxreclen=0; /* Linux-format */ struct file *fp; struct uio auio; struct iovec aiov; struct vattr va; off_t off; struct linux_dirent linux_dirent; int buflen, error, eofflag, nbytes, justone, blockoff; #ifdef DEBUG printf("Linux-emul(%d): readdir(%d, *, %d)\n", p->p_pid, args->fd, args->count); #endif if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) { return (error); } if ((fp->f_flag & FREAD) == 0) return (EBADF); vp = (struct vnode *) fp->f_data; if (vp->v_type != VDIR) return (EINVAL); if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) { return error; } nbytes = args->count; if (nbytes == 1) { nbytes = sizeof (struct linux_dirent); justone = 1; } else justone = 0; off = fp->f_offset; blockoff = off % DIRBLKSIZ; buflen = max(DIRBLKSIZ, nbytes + blockoff); buflen = min(buflen, MAXBSIZE); buf = malloc(buflen, M_TEMP, M_WAITOK); VOP_LOCK(vp); 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 - (off_t)blockoff; error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (int *) NULL, (u_int **) NULL); if (error) { goto out; } inp = buf; inp += blockoff; outp = (caddr_t) args->dent; resid = nbytes; if ((len = buflen - auio.uio_resid - blockoff) == 0) { goto eof; } while (len > 0) { bdp = (struct dirent *) inp; reclen = bdp->d_reclen; if (reclen & 3) { printf("linux_readdir: reclen=%d\n", reclen); error = EFAULT; goto out; } if (bdp->d_fileno == 0) { inp += reclen; off += reclen; len -= reclen; continue; } linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); if (reclen > len || resid < linuxreclen) { outp++; break; } linux_dirent.dino = (long) bdp->d_fileno; linux_dirent.doff = (linux_off_t) linuxreclen; linux_dirent.dreclen = (u_short) bdp->d_namlen; strcpy(linux_dirent.dname, bdp->d_name); if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { goto out; } inp += reclen; off += reclen; outp += linuxreclen; resid -= linuxreclen; len -= reclen; if (justone) break; } if (outp == (caddr_t) args->dent) goto again; fp->f_offset = off; if (justone) nbytes = resid + linuxreclen; eof: *retval = nbytes - resid; out: VOP_UNLOCK(vp); free(buf, M_TEMP); return error; } diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index e018051ada2c..ebdc850c9e31 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -1,498 +1,498 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.1 1995/06/25 17:32:35 sos Exp $ + * $Id: linux_ioctl.c,v 1.2 1995/11/22 07:43:46 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_termios { unsigned long c_iflag; unsigned long c_oflag; unsigned long c_cflag; unsigned long c_lflag; unsigned char c_line; unsigned char c_cc[LINUX_NCCS]; }; struct linux_winsize { unsigned short ws_row, ws_col; unsigned short ws_xpixel, ws_ypixel; }; 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, 4097 }, { 115200, 4098 }, {-1, -1 } }; static int linux_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_linux_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_to_linux_termios(struct termios *bsd_termios, struct linux_termios *linux_termios) { int i, speed; #ifdef DEBUG printf("LINUX: BSD termios structure (input):\n"); printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif linux_termios->c_iflag = 0; if (bsd_termios->c_iflag & IGNBRK) linux_termios->c_iflag |= LINUX_IGNBRK; if (bsd_termios->c_iflag & BRKINT) linux_termios->c_iflag |= LINUX_BRKINT; if (bsd_termios->c_iflag & IGNPAR) linux_termios->c_iflag |= LINUX_IGNPAR; if (bsd_termios->c_iflag & PARMRK) linux_termios->c_iflag |= LINUX_PARMRK; if (bsd_termios->c_iflag & INPCK) linux_termios->c_iflag |= LINUX_INPCK; if (bsd_termios->c_iflag & ISTRIP) linux_termios->c_iflag |= LINUX_ISTRIP; if (bsd_termios->c_iflag & INLCR) linux_termios->c_iflag |= LINUX_INLCR; if (bsd_termios->c_iflag & IGNCR) linux_termios->c_iflag |= LINUX_IGNCR; if (bsd_termios->c_iflag & ICRNL) linux_termios->c_iflag |= LINUX_ICRNL; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |= LINUX_IXANY; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |= LINUX_IXON; if (bsd_termios->c_iflag & IXOFF) linux_termios->c_iflag |= LINUX_IXOFF; if (bsd_termios->c_iflag & IMAXBEL) linux_termios->c_iflag |= LINUX_IMAXBEL; linux_termios->c_oflag = 0; if (bsd_termios->c_oflag & OPOST) linux_termios->c_oflag |= LINUX_OPOST; if (bsd_termios->c_oflag & ONLCR) linux_termios->c_oflag |= LINUX_ONLCR; if (bsd_termios->c_oflag & OXTABS) linux_termios->c_oflag |= LINUX_XTABS; linux_termios->c_cflag = bsd_to_linux_speed(bsd_termios->c_ispeed, sptab); linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; if (bsd_termios->c_cflag & CSTOPB) linux_termios->c_cflag |= LINUX_CSTOPB; if (bsd_termios->c_cflag & CREAD) linux_termios->c_cflag |= LINUX_CREAD; if (bsd_termios->c_cflag & PARENB) linux_termios->c_cflag |= LINUX_PARENB; if (bsd_termios->c_cflag & PARODD) linux_termios->c_cflag |= LINUX_PARODD; if (bsd_termios->c_cflag & HUPCL) linux_termios->c_cflag |= LINUX_HUPCL; if (bsd_termios->c_cflag & CLOCAL) linux_termios->c_cflag |= LINUX_CLOCAL; if (bsd_termios->c_cflag & CRTSCTS) linux_termios->c_cflag |= LINUX_CRTSCTS; linux_termios->c_lflag = 0; if (bsd_termios->c_lflag & ISIG) linux_termios->c_lflag |= LINUX_ISIG; if (bsd_termios->c_lflag & ICANON) linux_termios->c_lflag |= LINUX_ICANON; if (bsd_termios->c_lflag & ECHO) linux_termios->c_lflag |= LINUX_ECHO; if (bsd_termios->c_lflag & ECHOE) linux_termios->c_lflag |= LINUX_ECHOE; if (bsd_termios->c_lflag & ECHOK) linux_termios->c_lflag |= LINUX_ECHOK; if (bsd_termios->c_lflag & ECHONL) linux_termios->c_lflag |= LINUX_ECHONL; if (bsd_termios->c_lflag & NOFLSH) linux_termios->c_lflag |= LINUX_NOFLSH; if (bsd_termios->c_lflag & TOSTOP) linux_termios->c_lflag |= LINUX_TOSTOP; if (bsd_termios->c_lflag & ECHOCTL) linux_termios->c_lflag |= LINUX_ECHOCTL; if (bsd_termios->c_lflag & ECHOPRT) linux_termios->c_lflag |= LINUX_ECHOPRT; if (bsd_termios->c_lflag & ECHOKE) linux_termios->c_lflag |= LINUX_ECHOKE; if (bsd_termios->c_lflag & FLUSHO) linux_termios->c_lflag |= LINUX_FLUSHO; if (bsd_termios->c_lflag & PENDIN) linux_termios->c_lflag |= LINUX_PENDIN; if (bsd_termios->c_lflag & IEXTEN) linux_termios->c_lflag |= LINUX_IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL]; linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF]; linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL]; linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN]; linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME]; linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2]; linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE; linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP]; linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART]; linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP]; linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT]; linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD]; linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; linux_termios->c_line = 0; #ifdef DEBUG printf("LINUX: LINUX termios structure (output):\n"); printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif } static void linux_to_bsd_termios(struct linux_termios *linux_termios, struct termios *bsd_termios) { int i, speed; #ifdef DEBUG printf("LINUX: LINUX termios structure (input):\n"); printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif bsd_termios->c_iflag = 0; if (linux_termios->c_iflag & LINUX_IGNBRK) bsd_termios->c_iflag |= IGNBRK; if (linux_termios->c_iflag & LINUX_BRKINT) bsd_termios->c_iflag |= BRKINT; if (linux_termios->c_iflag & LINUX_IGNPAR) bsd_termios->c_iflag |= IGNPAR; if (linux_termios->c_iflag & LINUX_PARMRK) bsd_termios->c_iflag |= PARMRK; if (linux_termios->c_iflag & LINUX_INPCK) bsd_termios->c_iflag |= INPCK; if (linux_termios->c_iflag & LINUX_ISTRIP) bsd_termios->c_iflag |= ISTRIP; if (linux_termios->c_iflag & LINUX_INLCR) bsd_termios->c_iflag |= INLCR; if (linux_termios->c_iflag & LINUX_IGNCR) bsd_termios->c_iflag |= IGNCR; if (linux_termios->c_iflag & LINUX_ICRNL) bsd_termios->c_iflag |= ICRNL; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |= IXANY; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |= IXON; if (linux_termios->c_iflag & LINUX_IXOFF) bsd_termios->c_iflag |= IXOFF; if (linux_termios->c_iflag & LINUX_IMAXBEL) bsd_termios->c_iflag |= IMAXBEL; bsd_termios->c_oflag = 0; if (linux_termios->c_oflag & LINUX_OPOST) bsd_termios->c_oflag |= OPOST; if (linux_termios->c_oflag & LINUX_ONLCR) bsd_termios->c_oflag |= ONLCR; if (linux_termios->c_oflag & LINUX_XTABS) bsd_termios->c_oflag |= OXTABS; bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4; if (linux_termios->c_cflag & LINUX_CSTOPB) bsd_termios->c_cflag |= CSTOPB; if (linux_termios->c_cflag & LINUX_PARENB) bsd_termios->c_cflag |= PARENB; if (linux_termios->c_cflag & LINUX_PARODD) bsd_termios->c_cflag |= PARODD; if (linux_termios->c_cflag & LINUX_HUPCL) bsd_termios->c_cflag |= HUPCL; if (linux_termios->c_cflag & LINUX_CLOCAL) bsd_termios->c_cflag |= CLOCAL; if (linux_termios->c_cflag & LINUX_CRTSCTS) bsd_termios->c_cflag |= CRTSCTS; bsd_termios->c_lflag = 0; if (linux_termios->c_lflag & LINUX_ISIG) bsd_termios->c_lflag |= ISIG; if (linux_termios->c_lflag & LINUX_ICANON) bsd_termios->c_lflag |= ICANON; if (linux_termios->c_lflag & LINUX_ECHO) bsd_termios->c_lflag |= ECHO; if (linux_termios->c_lflag & LINUX_ECHOE) bsd_termios->c_lflag |= ECHOE; if (linux_termios->c_lflag & LINUX_ECHOK) bsd_termios->c_lflag |= ECHOK; if (linux_termios->c_lflag & LINUX_ECHONL) bsd_termios->c_lflag |= ECHONL; if (linux_termios->c_lflag & LINUX_NOFLSH) bsd_termios->c_lflag |= NOFLSH; if (linux_termios->c_lflag & LINUX_TOSTOP) bsd_termios->c_lflag |= TOSTOP; if (linux_termios->c_lflag & LINUX_ECHOCTL) bsd_termios->c_lflag |= ECHOCTL; if (linux_termios->c_lflag & LINUX_ECHOPRT) bsd_termios->c_lflag |= ECHOPRT; if (linux_termios->c_lflag & LINUX_ECHOKE) bsd_termios->c_lflag |= ECHOKE; if (linux_termios->c_lflag & LINUX_FLUSHO) bsd_termios->c_lflag |= FLUSHO; if (linux_termios->c_lflag & LINUX_PENDIN) bsd_termios->c_lflag |= PENDIN; if (linux_termios->c_lflag & IEXTEN) bsd_termios->c_lflag |= IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR]; bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT]; bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE]; bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL]; bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF]; bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL]; bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN]; bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME]; bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2]; bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP]; bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART]; bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP]; bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT]; bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD]; bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; bsd_termios->c_ispeed = bsd_termios->c_ospeed = linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); #ifdef DEBUG printf("LINUX: BSD termios structure (output):\n"); printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif } struct linux_ioctl_args { int fd; int cmd; int arg; }; int linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) { struct termios bsd_termios; struct winsize bsd_winsize; struct linux_termios linux_termios; struct linux_winsize linux_winsize; struct filedesc *fdp = p->p_fd; struct file *fp; int (*func)(struct file *fp, int com, caddr_t data, struct proc *p); int bsd_line, linux_line; int error; #ifdef DEBUG printf("Linux-emul(%d): ioctl(%d, %04x, *)\n", p->p_pid, args->fd, args->cmd); #endif 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 (args->cmd) { case LINUX_TCGETS: if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) return error; bsd_to_linux_termios(&bsd_termios, &linux_termios); return copyout((caddr_t)&linux_termios, (caddr_t)args->arg, sizeof(linux_termios)); case LINUX_TCSETS: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); case LINUX_TCSETSW: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); case LINUX_TCSETSF: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); case LINUX_TIOCGPGRP: args->cmd = TIOCGPGRP; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSPGRP: args->cmd = TIOCSPGRP; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCGWINSZ: args->cmd = TIOCGWINSZ; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSWINSZ: args->cmd = TIOCSWINSZ; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONREAD: args->cmd = FIONREAD; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONBIO: args->cmd = FIONBIO; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIOASYNC: args->cmd = FIOASYNC; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONCLEX: args->cmd = FIONCLEX; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIOCLEX: args->cmd = FIOCLEX; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCEXCL: args->cmd = TIOCEXCL; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCNXCL: args->cmd = TIOCNXCL; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCCONS: args->cmd = TIOCCONS; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCNOTTY: args->cmd = TIOCNOTTY; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSETD: switch (args->arg) { case LINUX_N_TTY: bsd_line = TTYDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_SLIP: bsd_line = SLIPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_PPP: bsd_line = PPPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); default: return EINVAL; } break; case LINUX_TIOCGETD: bsd_line = TTYDISC; if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p)) return error; switch (bsd_line) { case TTYDISC: linux_line = LINUX_N_TTY; break; case SLIPDISC: linux_line = LINUX_N_SLIP; break; case PPPDISC: linux_line = LINUX_N_PPP; break; default: return EINVAL; } return copyout(&linux_line, (caddr_t)args->arg, sizeof(int)); } uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n", args->fd, (args->cmd&0xffff00)>>8, (args->cmd&0xffff00)>>8, args->cmd&0xff); return EINVAL; } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 31995c5a64e2..cce887e4e8af 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,677 +1,676 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.6 1995/12/09 08:17:24 peter Exp $ + * $Id: linux_misc.c,v 1.7 1995/12/14 22:35:45 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_alarm_args { unsigned int secs; }; int linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval) { struct itimerval it, old_it; + struct timeval tv; int s; #ifdef DEBUG printf("Linux-emul(%d): alarm(%d)\n", p->p_pid, args->secs); #endif 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(); old_it = p->p_realtimer; + tv = time; if (timerisset(&old_it.it_value)) - if (timercmp(&old_it.it_value, &time, <)) + if (timercmp(&old_it.it_value, &tv, <)) timerclear(&old_it.it_value); else - timevalsub(&old_it.it_value, &time); + timevalsub(&old_it.it_value, &tv); splx(s); if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) return EINVAL; s = splclock(); untimeout(realitexpire, (caddr_t)p); + tv = time; if (timerisset(&it.it_value)) { - timevaladd(&it.it_value, &time); + timevaladd(&it.it_value, &tv); timeout(realitexpire, (caddr_t)p, hzto(&it.it_value)); } p->p_realtimer = it; splx(s); if (old_it.it_value.tv_usec) old_it.it_value.tv_sec++; *retval = old_it.it_value.tv_sec; return 0; } struct linux_brk_args { linux_caddr_t dsend; }; int linux_brk(struct proc *p, struct linux_brk_args *args, int *retval) { #if 0 struct vmspace *vm = p->p_vmspace; vm_offset_t new, old; int error; 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); *retval = old; if ((new-old) > 0) { if (swap_pager_full) return ENOMEM; error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE); if (error) return error; vm->vm_dsize += btoc((new-old)); *retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); } return 0; #else struct vmspace *vm = p->p_vmspace; vm_offset_t new, old; - struct obreak_args { - vm_offset_t newsize; - } tmp; + struct obreak_args /* { + char * nsize; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend); #endif old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); new = (vm_offset_t)args->dsend; - tmp.newsize = new; + tmp.nsize = (char *) new; if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval)) retval[0] = (int)new; else retval[0] = (int)old; return 0; #endif } struct linux_uselib_args { char *library; }; int linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) { struct nameidata ni; struct vnode *vp; struct exec *a_out = 0; struct vattr attr; unsigned long vmaddr, virtual_offset, file_offset; unsigned long buffer, bss_size; char *ptr; char path[MAXPATHLEN]; const char *prefix = "/compat/linux"; size_t sz, len; int error; #ifdef DEBUG printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library); #endif for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ; sz = MAXPATHLEN - (ptr - path); if (error = copyinstr(args->library, ptr, sz, &len)) return error; if (*ptr != '/') return EINVAL; #ifdef DEBUG printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); #endif NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); if (error = namei(&ni)) return error; vp = ni.ni_vp; if (vp == NULL) return ENOEXEC; if (vp->v_writecount) { VOP_UNLOCK(vp); return ETXTBSY; } if (error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { VOP_UNLOCK(vp); return ENOEXEC; } if (attr.va_size == 0) { VOP_UNLOCK(vp); return ENOEXEC; } if (error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } if (error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } VOP_UNLOCK(vp); /* lock no longer needed */ error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); if (error) return (error); /* * Is it a Linux binary ? */ if (((a_out->a_magic >> 16) & 0xff) != 0x64) return ENOEXEC; /* * Set file/virtual offset based on a.out variant. */ switch ((int)(a_out->a_magic & 0xffff)) { case 0413: /* ZMAGIC */ virtual_offset = 0; file_offset = 1024; break; case 0314: /* QMAGIC */ virtual_offset = 4096; file_offset = 0; break; default: return ENOEXEC; } vp->v_flag |= VTEXT; bss_size = round_page(a_out->a_bss); /* * Check if file_offset page aligned,. * Currently we cannot handle misalinged file offsets, * and so we read in the entire image (what a waste). */ if (file_offset & PGOFSET) { #ifdef DEBUG printf("uselib: Non page aligned binary %d\n", file_offset); #endif /* * Map text+data read/write/execute */ vmaddr = virtual_offset + round_page(a_out->a_entry); error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, round_page(a_out->a_text + a_out->a_data), FALSE); if (error) return error; error = vm_mmap(kernel_map, &buffer, round_page(a_out->a_text + a_out->a_data + file_offset), VM_PROT_READ, VM_PROT_READ, MAP_FILE, (caddr_t)vp, trunc_page(file_offset)); if (error) return error; error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr, a_out->a_text + a_out->a_data); if (error) return error; vm_map_remove(kernel_map, trunc_page(vmaddr), round_page(a_out->a_text + a_out->a_data + file_offset)); error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, round_page(a_out->a_text + a_out->a_data), VM_PROT_ALL, TRUE); if (error) return error; } else { #ifdef DEBUG printf("uselib: Page aligned binary %d\n", file_offset); #endif vmaddr = virtual_offset + round_page(a_out->a_entry); error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, a_out->a_text + a_out->a_data, VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, (caddr_t)vp, file_offset); if (error) return (error); } #ifdef DEBUG printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); #endif if (bss_size != 0) { vmaddr = virtual_offset + round_page(a_out->a_entry) + round_page(a_out->a_text + a_out->a_data); error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, bss_size, FALSE); if (error) return error; error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size, VM_PROT_ALL, TRUE); if (error) return error; } return 0; } struct linux_select_args { void *ptr; }; int linux_select(struct proc *p, struct linux_select_args *args, int *retval) { struct { int nfds; fd_set *readfds; fd_set *writefds; fd_set *exceptfds; struct timeval *timeout; } linux_args; - struct { + struct select_args /* { unsigned int nd; fd_set *in; fd_set *ou; fd_set *ex; struct timeval *tv; - } bsd_args; + } */ bsd_args; int error; if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, sizeof(linux_args)))) return error; #ifdef DEBUG printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n", p->p_pid, linux_args.nfds, linux_args.readfds, linux_args.writefds, linux_args.exceptfds, linux_args.timeout); #endif bsd_args.nd = linux_args.nfds; bsd_args.in = linux_args.readfds; bsd_args.ou = linux_args.writefds; bsd_args.ex = linux_args.exceptfds; bsd_args.tv = linux_args.timeout; return select(p, &bsd_args, retval); } struct linux_getpgid_args { int pid; }; int linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval) { struct proc *curproc; #ifdef DEBUG printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); #endif if (args->pid != p->p_pid) { if (!(curproc = pfind(args->pid))) return ESRCH; } else curproc = p; *retval = curproc->p_pgid; return 0; } int linux_fork(struct proc *p, void *args, int *retval) { int error; #ifdef DEBUG printf("Linux-emul(%d): fork()\n", p->p_pid); #endif if (error = fork(p, args, retval)) return error; if (retval[1] == 1) retval[0] = 0; return 0; } struct linux_mmap_args { void *ptr; }; int linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval) { struct { linux_caddr_t addr; int len; int prot; int flags; int fd; int pos; } linux_args; - struct { + struct mmap_args /* { caddr_t addr; size_t len; int prot; int flags; int fd; long pad; off_t pos; - } bsd_args; + } */ bsd_args; int error; if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, sizeof(linux_args)))) return error; #ifdef DEBUG printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n", p->p_pid, linux_args.addr, linux_args.len, linux_args.prot, linux_args.flags, linux_args.fd, linux_args.pos); #endif bsd_args.flags = 0; if (linux_args.flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; if (linux_args.flags & LINUX_MAP_PRIVATE) bsd_args.flags |= MAP_PRIVATE; if (linux_args.flags & LINUX_MAP_FIXED) bsd_args.flags |= MAP_FIXED; if (linux_args.flags & LINUX_MAP_ANON) bsd_args.flags |= MAP_ANON; bsd_args.addr = linux_args.addr; bsd_args.len = linux_args.len; bsd_args.prot = linux_args.prot; bsd_args.fd = linux_args.fd; bsd_args.pos = linux_args.pos; bsd_args.pad = 0; return mmap(p, &bsd_args, retval); } struct linux_pipe_args { int *pipefds; }; int linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval) { int error; #ifdef DEBUG printf("Linux-emul(%d): pipe(*)\n", p->p_pid); #endif if (error = pipe(p, 0, retval)) return error; if (error = copyout(retval, args->pipefds, 2*sizeof(int))) return error; *retval = 0; return 0; } struct linux_time_args { linux_time_t *tm; }; int linux_time(struct proc *p, struct linux_time_args *args, int *retval) { struct timeval tv; linux_time_t tm; int error; #ifdef DEBUG printf("Linux-emul(%d): time(*)\n", p->p_pid); #endif microtime(&tv); tm = tv.tv_sec; if (error = copyout(&tm, args->tm, sizeof(linux_time_t))) return error; *retval = tv.tv_sec; return 0; } struct linux_tms { long tms_utime; long tms_stime; long tms_cutime; long tms_cstime; }; struct linux_tms_args { char *buf; }; int linux_times(struct proc *p, struct linux_tms_args *args, int *retval) { struct timeval tv; struct linux_tms tms; #ifdef DEBUG printf("Linux-emul(%d): times(*)\n", p->p_pid); #endif 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->buf, sizeof(struct linux_tms))); } struct linux_newuname_t { char sysname[65]; char nodename[65]; char release[65]; char version[65]; char machine[65]; char domainname[65]; }; struct linux_newuname_args { char *buf; }; int linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval) { struct linux_newuname_t linux_newuname; #ifdef DEBUG printf("Linux-emul(%d): newuname(*)\n", p->p_pid); #endif bzero(&linux_newuname, sizeof(struct linux_newuname_args)); strncpy(linux_newuname.sysname, ostype, 64); strncpy(linux_newuname.nodename, hostname, 64); strncpy(linux_newuname.release, osrelease, 64); strncpy(linux_newuname.version, version, 64); strncpy(linux_newuname.machine, machine, 64); strncpy(linux_newuname.domainname, domainname, 64); return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf, sizeof(struct linux_newuname_t))); } struct linux_utime_args { char *fname; linux_time_t *timeptr; }; int linux_utime(struct proc *p, struct linux_utime_args *args, int *retval) { - struct bsd_utimes_args { - char *fname; + struct utimes_args /* { + char *path; struct timeval *tptr; - } bsdutimes; + } */ bsdutimes; struct timeval tv; #ifdef DEBUG printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname); #endif tv.tv_sec = (long)args->timeptr; tv.tv_usec = 0; bsdutimes.tptr = &tv; - bsdutimes.fname = args->fname; + bsdutimes.path = args->fname; return utimes(p, &bsdutimes, retval); } struct linux_waitpid_args { int pid; int *status; int options; }; int linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval) { - struct wait4_args { + struct wait_args /* { int pid; int *status; int options; struct rusage *rusage; - int compat; - } tmp; + } */ tmp; int error, tmpstat; #ifdef DEBUG printf("Linux-emul(%d): waitpid(%d, *, %d)\n", p->p_pid, args->pid, args->options); #endif tmp.pid = args->pid; tmp.status = args->status; tmp.options = args->options; tmp.rusage = NULL; - tmp.compat = 0; if (error = wait4(p, &tmp, retval)) return error; if (error = copyin(args->status, &tmpstat, sizeof(int))) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | bsd_to_linux_signal[WTERMSIG(tmpstat)]; else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); return copyout(&tmpstat, args->status, sizeof(int)); } struct linux_wait4_args { int pid; int *status; int options; struct rusage *rusage; }; int linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval) { - struct wait4_args { + struct wait_args /* { int pid; int *status; int options; struct rusage *rusage; - int compat; - } tmp; + } */ tmp; int error, tmpstat; #ifdef DEBUG printf("Linux-emul(%d): wait4(%d, *, %d, *)\n", p->p_pid, args->pid, args->options); #endif tmp.pid = args->pid; tmp.status = args->status; tmp.options = args->options; tmp.rusage = args->rusage; - tmp.compat = 0; if (error = wait4(p, &tmp, retval)) return error; if (error = copyin(args->status, &tmpstat, sizeof(int))) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | bsd_to_linux_signal[WTERMSIG(tmpstat)]; else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); return copyout(&tmpstat, args->status, sizeof(int)); } diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c index 1c63681e6e12..fc5c2cd7c274 100644 --- a/sys/compat/linux/linux_signal.c +++ b/sys/compat/linux/linux_signal.c @@ -1,259 +1,261 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_signal.c,v 1.1 1995/06/25 17:32:40 sos Exp $ + * $Id: linux_signal.c,v 1.2 1995/11/22 07:43:50 bde Exp $ */ #include #include #include #include #include #include #include #include #include #define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD)) static sigset_t linux_to_bsd_sigmask(linux_sigset_t mask) { int i; sigset_t new = 0; for (i = 1; i <= LINUX_NSIG; i++) if (mask & (1 << i-1)) new |= (1 << (linux_to_bsd_signal[i]-1)); return new; } static linux_sigset_t bsd_to_linux_sigmask(sigset_t mask) { int i; sigset_t new = 0; for (i = 1; i <= NSIG; i++) if (mask & (1 << i-1)) new |= (1 << (bsd_to_linux_signal[i]-1)); return new; } struct linux_sigaction_args { int sig; linux_sigaction_t *nsa; linux_sigaction_t *osa; }; int linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval) { linux_sigaction_t linux_sa; struct sigaction *nsa = NULL, *osa = NULL, bsd_sa; - struct sigaction_args { - int sig; + struct sigaction_args /* { + int signum; struct sigaction *nsa; struct sigaction *osa; - } sa; + } */ sa; int error; #ifdef DEBUG printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig); #endif if (args->osa) osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction)); if (args->nsa) { nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction)); if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t))) return error; bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask); bsd_sa.sa_handler = linux_sa.sa_handler; bsd_sa.sa_flags = 0; if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP) bsd_sa.sa_flags |= SA_NOCLDSTOP; if (linux_sa.sa_flags & LINUX_SA_ONSTACK) bsd_sa.sa_flags |= SA_ONSTACK; if (linux_sa.sa_flags & LINUX_SA_RESTART) bsd_sa.sa_flags |= SA_RESTART; if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction))) return error; } - sa.sig = linux_to_bsd_signal[args->sig]; + sa.signum = linux_to_bsd_signal[args->sig]; sa.nsa = nsa; sa.osa = osa; if ((error = sigaction(p, &sa, retval))) return error; if (args->osa) { if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction))) return error; linux_sa.sa_handler = bsd_sa.sa_handler; linux_sa.sa_restorer = NULL; linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask); linux_sa.sa_flags = 0; if (bsd_sa.sa_flags & SA_NOCLDSTOP) linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP; if (bsd_sa.sa_flags & SA_ONSTACK) linux_sa.sa_flags |= LINUX_SA_ONSTACK; if (bsd_sa.sa_flags & SA_RESTART) linux_sa.sa_flags |= LINUX_SA_RESTART; if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t))) return error; } return 0; } struct linux_sigprocmask_args { int how; linux_sigset_t *mask; linux_sigset_t *omask; }; int linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args, int *retval) { int error, s; sigset_t mask; sigset_t omask; #ifdef DEBUG printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); #endif if (args->omask != NULL) { omask = bsd_to_linux_sigmask(p->p_sigmask); if (error = copyout(&omask, args->omask, sizeof(sigset_t))) return error; } if (!(args->mask)) return 0; if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t))) return error; mask = linux_to_bsd_sigmask(mask); s = splhigh(); switch (args->how) { case LINUX_SIG_BLOCK: p->p_sigmask |= (mask & ~DONTMASK); break; case LINUX_SIG_UNBLOCK: p->p_sigmask &= ~mask; break; case LINUX_SIG_SETMASK: p->p_sigmask = (mask & ~DONTMASK); break; default: error = EINVAL; break; } splx(s); return error; } int linux_siggetmask(struct proc *p, void *args, int *retval) { #ifdef DEBUG printf("Linux-emul(%d): siggetmask()\n", p->p_pid); #endif *retval = bsd_to_linux_sigmask(p->p_sigmask); return 0; } struct linux_sigsetmask_args { linux_sigset_t mask; }; int linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval) { int s; #ifdef DEBUG printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask); #endif s = splhigh(); p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK); splx(s); *retval = bsd_to_linux_sigmask(p->p_sigmask); return 0; } struct linux_sigpending_args { linux_sigset_t *mask; }; int linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval) { linux_sigset_t linux_sig; #ifdef DEBUG printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); #endif linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask); return copyout(&linux_sig, args->mask, sizeof(linux_sig)); } struct linux_sigsuspend_args { linux_sigset_t mask; }; int linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval) { - sigset_t tmp; + struct sigsuspend_args /* { + int mask; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask); #endif - tmp = linux_to_bsd_sigmask(args->mask); + tmp.mask = linux_to_bsd_sigmask(args->mask); return sigsuspend(p, &tmp , retval); } struct linux_kill_args { int pid; int signum; }; int linux_kill(struct proc *p, struct linux_kill_args *args, int *retval) { - struct { + struct kill_args /* { int pid; int signum; - } tmp; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): kill(%d, %d)\n", p->p_pid, args->pid, args->signum); #endif tmp.pid = args->pid; tmp.signum = linux_to_bsd_signal[args->signum]; return kill(p, &tmp, retval); } diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index b803111acb53..da4668c674e1 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1,601 +1,601 @@ /*- * Copyright (c) 1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_socket.c,v 1.1 1995/06/25 17:32:41 sos Exp $ + * $Id: linux_socket.c,v 1.2 1995/11/22 07:43:50 bde Exp $ */ /* XXX we use functions that might not exist. */ #define COMPAT_43 1 #include #include #include #include #include #include #include #include #include static int linux_to_bsd_domain(int domain) { switch (domain) { case LINUX_AF_UNSPEC: return AF_UNSPEC; case LINUX_AF_UNIX: return AF_LOCAL; case LINUX_AF_INET: return AF_INET; case LINUX_AF_AX25: return AF_CCITT; case LINUX_AF_IPX: return AF_IPX; case LINUX_AF_APPLETALK: return AF_APPLETALK; default: return -1; } } static int linux_to_bsd_sockopt_level(int level) { switch (level) { case LINUX_SOL_SOCKET: return SOL_SOCKET; default: return level; } } static int linux_to_bsd_ip_sockopt(int opt) { switch (opt) { case LINUX_IP_TOS: return IP_TOS; case LINUX_IP_TTL: return IP_TTL; default: return -1; } } static int linux_to_bsd_so_sockopt(int opt) { switch (opt) { case LINUX_SO_DEBUG: return SO_DEBUG; case LINUX_SO_REUSEADDR: return SO_REUSEADDR; case LINUX_SO_TYPE: return SO_TYPE; case LINUX_SO_ERROR: return SO_ERROR; case LINUX_SO_DONTROUTE: return SO_DONTROUTE; case LINUX_SO_BROADCAST: return SO_BROADCAST; case LINUX_SO_SNDBUF: return SO_SNDBUF; case LINUX_SO_RCVBUF: return SO_RCVBUF; case LINUX_SO_KEEPALIVE: return SO_KEEPALIVE; case LINUX_SO_OOBINLINE: return SO_OOBINLINE; case LINUX_SO_LINGER: return SO_LINGER; case LINUX_SO_PRIORITY: case LINUX_SO_NO_CHECK: default: return -1; } } struct linux_socket_args { int domain; int type; int protocol; }; static int linux_socket(struct proc *p, struct linux_socket_args *args, int *retval) { struct linux_socket_args linux_args; - struct { + struct socket_args /* { int domain; int type; int protocol; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.protocol = linux_args.protocol; bsd_args.type = linux_args.type; bsd_args.domain = linux_to_bsd_domain(linux_args.domain); if (bsd_args.domain == -1) return EINVAL; return socket(p, &bsd_args, retval); } struct linux_bind_args { int s; struct sockaddr *name; int namelen; }; static int linux_bind(struct proc *p, struct linux_bind_args *args, int *retval) { struct linux_bind_args linux_args; - struct { + struct bind_args /* { int s; caddr_t name; int namelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; bsd_args.namelen = linux_args.namelen; return bind(p, &bsd_args, retval); } struct linux_connect_args { int s; struct sockaddr * name; int namelen; }; static int linux_connect(struct proc *p, struct linux_connect_args *args, int *retval) { struct linux_connect_args linux_args; - struct { + struct connect_args /* { int s; caddr_t name; int namelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; bsd_args.namelen = linux_args.namelen; return connect(p, &bsd_args, retval); } struct linux_listen_args { int s; int backlog; }; static int linux_listen(struct proc *p, struct linux_listen_args *args, int *retval) { struct linux_listen_args linux_args; - struct { + struct listen_args /* { int s; int backlog; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.backlog = linux_args.backlog; return listen(p, &bsd_args, retval); } struct linux_accept_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_accept(struct proc *p, struct linux_accept_args *args, int *retval) { struct linux_accept_args linux_args; - struct accept_args { + struct accept_args /* { int s; caddr_t name; int *anamelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.addr; bsd_args.anamelen = linux_args.namelen; return oaccept(p, &bsd_args, retval); } struct linux_getsockname_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_getsockname(struct proc *p, struct linux_getsockname_args *args, int *retval) { struct linux_getsockname_args linux_args; - struct { + struct getsockname_args /* { int fdes; caddr_t asa; int *alen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.fdes = linux_args.s; bsd_args.asa = (caddr_t) linux_args.addr; bsd_args.alen = linux_args.namelen; return ogetsockname(p, &bsd_args, retval); } struct linux_getpeername_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_getpeername(struct proc *p, struct linux_getpeername_args *args, int *retval) { struct linux_getpeername_args linux_args; - struct getpeername_args { + struct ogetpeername_args /* { int fdes; caddr_t asa; int *alen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.fdes = linux_args.s; bsd_args.asa = (caddr_t) linux_args.addr; bsd_args.alen = linux_args.namelen; return ogetpeername(p, &bsd_args, retval); } struct linux_socketpair_args { int domain; int type; int protocol; int *rsv; }; static int linux_socketpair(struct proc *p, struct linux_socketpair_args *args, int *retval) { struct linux_socketpair_args linux_args; - struct { + struct socketpair_args /* { int domain; int type; int protocol; int *rsv; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.domain = linux_to_bsd_domain(linux_args.domain); if (bsd_args.domain == -1) return EINVAL; bsd_args.type = linux_args.type; bsd_args.protocol = linux_args.protocol; bsd_args.rsv = linux_args.rsv; return socketpair(p, &bsd_args, retval); } struct linux_send_args { int s; void *msg; int len; int flags; }; static int linux_send(struct proc *p, struct linux_send_args *args, int *retval) { struct linux_send_args linux_args; - struct { + struct osend_args /* { int s; caddr_t buf; int len; int flags; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; return osend(p, &bsd_args, retval); } struct linux_recv_args { int s; void *msg; int len; int flags; }; static int linux_recv(struct proc *p, struct linux_recv_args *args, int *retval) { struct linux_recv_args linux_args; - struct { + struct orecv_args /* { int s; caddr_t buf; int len; int flags; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; return orecv(p, &bsd_args, retval); } struct linux_sendto_args { int s; void *msg; int len; int flags; caddr_t to; int tolen; }; static int linux_sendto(struct proc *p, struct linux_sendto_args *args, int *retval) { struct linux_sendto_args linux_args; - struct { + struct sendto_args /* { int s; caddr_t buf; size_t len; int flags; caddr_t to; int tolen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.to = linux_args.to; bsd_args.tolen = linux_args.tolen; return sendto(p, &bsd_args, retval); } struct linux_recvfrom_args { int s; void *buf; int len; int flags; caddr_t from; int *fromlen; }; static int linux_recvfrom(struct proc *p, struct linux_recvfrom_args *args, int *retval) { struct linux_recvfrom_args linux_args; - struct { + struct recvfrom_args /* { int s; caddr_t buf; size_t len; int flags; caddr_t from; int *fromlenaddr; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.buf; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.from = linux_args.from; bsd_args.fromlenaddr = linux_args.fromlen; return orecvfrom(p, &bsd_args, retval); } struct linux_shutdown_args { int s; int how; }; static int linux_shutdown(struct proc *p, struct linux_shutdown_args *args, int *retval) { struct linux_shutdown_args linux_args; - struct { + struct shutdown_args /* { int s; int how; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.how = linux_args.how; return shutdown(p, &bsd_args, retval); } struct linux_setsockopt_args { int s; int level; int optname; void *optval; int optlen; }; static int linux_setsockopt(struct proc *p, struct linux_setsockopt_args *args, int *retval) { struct linux_setsockopt_args linux_args; - struct { + struct setsockopt_args /* { int s; int level; int name; caddr_t val; int valsize; - } bsd_args; + } */ bsd_args; int error, name; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(linux_args.optname); break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(linux_args.optname); break; default: return EINVAL; } if (name == -1) return EINVAL; bsd_args.name = name; bsd_args.val = linux_args.optval; bsd_args.valsize = linux_args.optlen; return setsockopt(p, &bsd_args, retval); } struct linux_getsockopt_args { int s; int level; int optname; void *optval; int *optlen; }; static int linux_getsockopt(struct proc *p, struct linux_getsockopt_args *args, int *retval) { struct linux_getsockopt_args linux_args; - struct { + struct getsockopt_args /* { int s; int level; int name; caddr_t val; int *avalsize; - } bsd_args; + } */ bsd_args; int error, name; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(linux_args.optname); break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(linux_args.optname); break; default: return EINVAL; } if (name == -1) return EINVAL; bsd_args.val = linux_args.optval; bsd_args.avalsize = linux_args.optlen; return getsockopt(p, &bsd_args, retval); } struct linux_socketcall_args { int what; void *args; }; int linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval) { switch (args->what) { case LINUX_SOCKET: return linux_socket(p, args->args, retval); case LINUX_BIND: return linux_bind(p, args->args, retval); case LINUX_CONNECT: return linux_connect(p, args->args, retval); case LINUX_LISTEN: return linux_listen(p, args->args, retval); case LINUX_ACCEPT: return linux_accept(p, args->args, retval); case LINUX_GETSOCKNAME: return linux_getsockname(p, args->args, retval); case LINUX_GETPEERNAME: return linux_getpeername(p, args->args, retval); case LINUX_SOCKETPAIR: return linux_socketpair(p, args->args, retval); case LINUX_SEND: return linux_send(p, args->args, retval); case LINUX_RECV: return linux_recv(p, args->args, retval); case LINUX_SENDTO: return linux_sendto(p, args->args, retval); case LINUX_RECVFROM: return linux_recvfrom(p, args->args, retval); case LINUX_SHUTDOWN: return linux_shutdown(p, args->args, retval); case LINUX_SETSOCKOPT: return linux_setsockopt(p, args->args, retval); case LINUX_GETSOCKOPT: return linux_getsockopt(p, args->args, retval); default: uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); return ENOSYS; } } diff --git a/sys/i386/linux/linux_file.c b/sys/i386/linux/linux_file.c index 8bdb3a7c5c23..0918f221fd3f 100644 --- a/sys/i386/linux/linux_file.c +++ b/sys/i386/linux/linux_file.c @@ -1,454 +1,452 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_file.c,v 1.3 1995/10/10 23:13:27 swallace Exp $ + * $Id: linux_file.c,v 1.4 1995/11/22 07:43:45 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_creat_args { char *path; int mode; }; int linux_creat(struct proc *p, struct linux_creat_args *args, int *retval) { - struct { + struct open_args /* { char *path; int flags; int mode; - } bsd_open_args; + } */ bsd_open_args; #ifdef DEBUG printf("Linux-emul(%d): creat(%s, %d)\n", p->p_pid, args->path, args->mode); #endif bsd_open_args.path = args->path; bsd_open_args.mode = args->mode; bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC; return open(p, &bsd_open_args, retval); } struct linux_open_args { char *path; int flags; int mode; }; int linux_open(struct proc *p, struct linux_open_args *args, int *retval) { - struct { + struct open_args /* { char *path; int flags; int mode; - } bsd_open_args; + } */ bsd_open_args; int error; #ifdef DEBUG printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n", p->p_pid, args->path, args->flags, args->mode); #endif bsd_open_args.flags = 0; if (args->flags & LINUX_O_RDONLY) bsd_open_args.flags |= O_RDONLY; if (args->flags & LINUX_O_WRONLY) bsd_open_args.flags |= O_WRONLY; if (args->flags & LINUX_O_RDWR) bsd_open_args.flags |= O_RDWR; if (args->flags & LINUX_O_NDELAY) bsd_open_args.flags |= O_NONBLOCK; if (args->flags & LINUX_O_APPEND) bsd_open_args.flags |= O_APPEND; if (args->flags & LINUX_O_SYNC) bsd_open_args.flags |= O_FSYNC; if (args->flags & LINUX_O_NONBLOCK) bsd_open_args.flags |= O_NONBLOCK; if (args->flags & LINUX_FASYNC) bsd_open_args.flags |= O_ASYNC; if (args->flags & LINUX_O_CREAT) bsd_open_args.flags |= O_CREAT; if (args->flags & LINUX_O_TRUNC) bsd_open_args.flags |= O_TRUNC; if (args->flags & LINUX_O_EXCL) bsd_open_args.flags |= O_EXCL; if (args->flags & LINUX_O_NOCTTY) bsd_open_args.flags |= O_NOCTTY; bsd_open_args.path = args->path; bsd_open_args.mode = args->mode; error = open(p, &bsd_open_args, retval); if (!error && !(bsd_open_args.flags & O_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 linux_flock { short l_type; short l_whence; linux_off_t l_start; linux_off_t l_len; linux_pid_t l_pid; }; static void linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock) { switch (linux_flock->l_type) { case LINUX_F_RDLCK: bsd_flock->l_type = F_RDLCK; break; case LINUX_F_WRLCK: bsd_flock->l_type = F_WRLCK; break; case LINUX_F_UNLCK: bsd_flock->l_type = F_UNLCK; break; } bsd_flock->l_whence = linux_flock->l_whence; bsd_flock->l_start = (off_t)linux_flock->l_start; bsd_flock->l_len = (off_t)linux_flock->l_len; bsd_flock->l_pid = (pid_t)linux_flock->l_pid; } static void bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock) { switch (bsd_flock->l_type) { case F_RDLCK: linux_flock->l_type = LINUX_F_RDLCK; break; case F_WRLCK: linux_flock->l_type = LINUX_F_WRLCK; break; case F_UNLCK: linux_flock->l_type = LINUX_F_UNLCK; break; } linux_flock->l_whence = bsd_flock->l_whence; linux_flock->l_start = (linux_off_t)bsd_flock->l_start; linux_flock->l_len = (linux_off_t)bsd_flock->l_len; linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid; } struct linux_fcntl_args { int fd; int cmd; int arg; }; int linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval) { int error, result; - struct fcntl_args { + struct fcntl_args /* { int fd; int cmd; int arg; - } fcntl_args; + } */ fcntl_args; struct linux_flock linux_flock; struct flock *bsd_flock = (struct flock *)ua_alloc_init(sizeof(struct flock)); #ifdef DEBUG printf("Linux-emul(%d): fcntl(%d, %08x, *)\n", p->p_pid, args->fd, args->cmd); #endif fcntl_args.fd = args->fd; fcntl_args.arg = 0; switch (args->cmd) { case LINUX_F_DUPFD: fcntl_args.cmd = F_DUPFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETFD: fcntl_args.cmd = F_GETFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETFD: fcntl_args.cmd = F_SETFD; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETFL: fcntl_args.cmd = F_GETFL; error = fcntl(p, &fcntl_args, &result); *retval = 0; if (result & O_RDONLY) *retval |= LINUX_O_RDONLY; if (result & O_WRONLY) *retval |= LINUX_O_WRONLY; if (result & O_RDWR) *retval |= LINUX_O_RDWR; if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK; if (result & O_APPEND) *retval |= LINUX_O_APPEND; if (result & O_FSYNC) *retval |= LINUX_O_SYNC; return error; case LINUX_F_SETFL: if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND; if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC; fcntl_args.cmd = F_SETFL; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETLK: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_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_linux_flock(bsd_flock, &linux_flock); return copyout((caddr_t)&linux_flock, (caddr_t)args->arg, sizeof(struct linux_flock)); case LINUX_F_SETLK: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_flock, bsd_flock); fcntl_args.cmd = F_SETLK; fcntl_args.arg = (int)bsd_flock; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETLKW: if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock, sizeof(struct linux_flock)))) return error; linux_to_bsd_flock(&linux_flock, bsd_flock); fcntl_args.cmd = F_SETLKW; fcntl_args.arg = (int)bsd_flock; return fcntl(p, &fcntl_args, retval); case LINUX_F_SETOWN: fcntl_args.cmd = F_SETOWN; return fcntl(p, &fcntl_args, retval); case LINUX_F_GETOWN: fcntl_args.cmd = F_GETOWN; return fcntl(p, &fcntl_args, retval); } return EINVAL; } struct linux_lseek_args { int fdes; unsigned long off; int whence; }; int linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval) { - struct lseek_args { - int fdes; + struct lseek_args /* { + int fd; int pad; - off_t off; + off_t offset; int whence; - } tmp_args; - off_t tmp_retval; + } */ tmp_args; int error; #ifdef DEBUG printf("Linux-emul(%d): lseek(%d, %d, %d)\n", p->p_pid, args->fdes, args->off, args->whence); #endif - tmp_args.fdes = args->fdes; - tmp_args.off = (off_t)args->off; + tmp_args.fd = args->fdes; + tmp_args.offset = (off_t)args->off; tmp_args.whence = args->whence; - error = lseek(p, &tmp_args, &tmp_retval); - *retval = (int)tmp_retval; + error = lseek(p, &tmp_args, retval); return error; } struct linux_dirent { long dino; linux_off_t doff; unsigned short dreclen; char dname[LINUX_NAME_MAX + 1]; }; #define LINUX_RECLEN(de,namlen) \ ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1)) struct linux_readdir_args { int fd; struct linux_dirent *dent; unsigned int count; }; int linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval) { register struct dirent *bdp; struct vnode *vp; caddr_t inp, buf; /* BSD-format */ int len, reclen; /* BSD-format */ caddr_t outp; /* Linux-format */ int resid, linuxreclen=0; /* Linux-format */ struct file *fp; struct uio auio; struct iovec aiov; struct vattr va; off_t off; struct linux_dirent linux_dirent; int buflen, error, eofflag, nbytes, justone, blockoff; #ifdef DEBUG printf("Linux-emul(%d): readdir(%d, *, %d)\n", p->p_pid, args->fd, args->count); #endif if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) { return (error); } if ((fp->f_flag & FREAD) == 0) return (EBADF); vp = (struct vnode *) fp->f_data; if (vp->v_type != VDIR) return (EINVAL); if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) { return error; } nbytes = args->count; if (nbytes == 1) { nbytes = sizeof (struct linux_dirent); justone = 1; } else justone = 0; off = fp->f_offset; blockoff = off % DIRBLKSIZ; buflen = max(DIRBLKSIZ, nbytes + blockoff); buflen = min(buflen, MAXBSIZE); buf = malloc(buflen, M_TEMP, M_WAITOK); VOP_LOCK(vp); 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 - (off_t)blockoff; error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (int *) NULL, (u_int **) NULL); if (error) { goto out; } inp = buf; inp += blockoff; outp = (caddr_t) args->dent; resid = nbytes; if ((len = buflen - auio.uio_resid - blockoff) == 0) { goto eof; } while (len > 0) { bdp = (struct dirent *) inp; reclen = bdp->d_reclen; if (reclen & 3) { printf("linux_readdir: reclen=%d\n", reclen); error = EFAULT; goto out; } if (bdp->d_fileno == 0) { inp += reclen; off += reclen; len -= reclen; continue; } linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen); if (reclen > len || resid < linuxreclen) { outp++; break; } linux_dirent.dino = (long) bdp->d_fileno; linux_dirent.doff = (linux_off_t) linuxreclen; linux_dirent.dreclen = (u_short) bdp->d_namlen; strcpy(linux_dirent.dname, bdp->d_name); if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) { goto out; } inp += reclen; off += reclen; outp += linuxreclen; resid -= linuxreclen; len -= reclen; if (justone) break; } if (outp == (caddr_t) args->dent) goto again; fp->f_offset = off; if (justone) nbytes = resid + linuxreclen; eof: *retval = nbytes - resid; out: VOP_UNLOCK(vp); free(buf, M_TEMP); return error; } diff --git a/sys/i386/linux/linux_ioctl.c b/sys/i386/linux/linux_ioctl.c index e018051ada2c..ebdc850c9e31 100644 --- a/sys/i386/linux/linux_ioctl.c +++ b/sys/i386/linux/linux_ioctl.c @@ -1,498 +1,498 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_ioctl.c,v 1.1 1995/06/25 17:32:35 sos Exp $ + * $Id: linux_ioctl.c,v 1.2 1995/11/22 07:43:46 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_termios { unsigned long c_iflag; unsigned long c_oflag; unsigned long c_cflag; unsigned long c_lflag; unsigned char c_line; unsigned char c_cc[LINUX_NCCS]; }; struct linux_winsize { unsigned short ws_row, ws_col; unsigned short ws_xpixel, ws_ypixel; }; 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, 4097 }, { 115200, 4098 }, {-1, -1 } }; static int linux_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_linux_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_to_linux_termios(struct termios *bsd_termios, struct linux_termios *linux_termios) { int i, speed; #ifdef DEBUG printf("LINUX: BSD termios structure (input):\n"); printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif linux_termios->c_iflag = 0; if (bsd_termios->c_iflag & IGNBRK) linux_termios->c_iflag |= LINUX_IGNBRK; if (bsd_termios->c_iflag & BRKINT) linux_termios->c_iflag |= LINUX_BRKINT; if (bsd_termios->c_iflag & IGNPAR) linux_termios->c_iflag |= LINUX_IGNPAR; if (bsd_termios->c_iflag & PARMRK) linux_termios->c_iflag |= LINUX_PARMRK; if (bsd_termios->c_iflag & INPCK) linux_termios->c_iflag |= LINUX_INPCK; if (bsd_termios->c_iflag & ISTRIP) linux_termios->c_iflag |= LINUX_ISTRIP; if (bsd_termios->c_iflag & INLCR) linux_termios->c_iflag |= LINUX_INLCR; if (bsd_termios->c_iflag & IGNCR) linux_termios->c_iflag |= LINUX_IGNCR; if (bsd_termios->c_iflag & ICRNL) linux_termios->c_iflag |= LINUX_ICRNL; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |= LINUX_IXANY; if (bsd_termios->c_iflag & IXON) linux_termios->c_iflag |= LINUX_IXON; if (bsd_termios->c_iflag & IXOFF) linux_termios->c_iflag |= LINUX_IXOFF; if (bsd_termios->c_iflag & IMAXBEL) linux_termios->c_iflag |= LINUX_IMAXBEL; linux_termios->c_oflag = 0; if (bsd_termios->c_oflag & OPOST) linux_termios->c_oflag |= LINUX_OPOST; if (bsd_termios->c_oflag & ONLCR) linux_termios->c_oflag |= LINUX_ONLCR; if (bsd_termios->c_oflag & OXTABS) linux_termios->c_oflag |= LINUX_XTABS; linux_termios->c_cflag = bsd_to_linux_speed(bsd_termios->c_ispeed, sptab); linux_termios->c_cflag |= (bsd_termios->c_cflag & CSIZE) >> 4; if (bsd_termios->c_cflag & CSTOPB) linux_termios->c_cflag |= LINUX_CSTOPB; if (bsd_termios->c_cflag & CREAD) linux_termios->c_cflag |= LINUX_CREAD; if (bsd_termios->c_cflag & PARENB) linux_termios->c_cflag |= LINUX_PARENB; if (bsd_termios->c_cflag & PARODD) linux_termios->c_cflag |= LINUX_PARODD; if (bsd_termios->c_cflag & HUPCL) linux_termios->c_cflag |= LINUX_HUPCL; if (bsd_termios->c_cflag & CLOCAL) linux_termios->c_cflag |= LINUX_CLOCAL; if (bsd_termios->c_cflag & CRTSCTS) linux_termios->c_cflag |= LINUX_CRTSCTS; linux_termios->c_lflag = 0; if (bsd_termios->c_lflag & ISIG) linux_termios->c_lflag |= LINUX_ISIG; if (bsd_termios->c_lflag & ICANON) linux_termios->c_lflag |= LINUX_ICANON; if (bsd_termios->c_lflag & ECHO) linux_termios->c_lflag |= LINUX_ECHO; if (bsd_termios->c_lflag & ECHOE) linux_termios->c_lflag |= LINUX_ECHOE; if (bsd_termios->c_lflag & ECHOK) linux_termios->c_lflag |= LINUX_ECHOK; if (bsd_termios->c_lflag & ECHONL) linux_termios->c_lflag |= LINUX_ECHONL; if (bsd_termios->c_lflag & NOFLSH) linux_termios->c_lflag |= LINUX_NOFLSH; if (bsd_termios->c_lflag & TOSTOP) linux_termios->c_lflag |= LINUX_TOSTOP; if (bsd_termios->c_lflag & ECHOCTL) linux_termios->c_lflag |= LINUX_ECHOCTL; if (bsd_termios->c_lflag & ECHOPRT) linux_termios->c_lflag |= LINUX_ECHOPRT; if (bsd_termios->c_lflag & ECHOKE) linux_termios->c_lflag |= LINUX_ECHOKE; if (bsd_termios->c_lflag & FLUSHO) linux_termios->c_lflag |= LINUX_FLUSHO; if (bsd_termios->c_lflag & PENDIN) linux_termios->c_lflag |= LINUX_PENDIN; if (bsd_termios->c_lflag & IEXTEN) linux_termios->c_lflag |= LINUX_IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; linux_termios->c_cc[LINUX_VINTR] = bsd_termios->c_cc[VINTR]; linux_termios->c_cc[LINUX_VQUIT] = bsd_termios->c_cc[VQUIT]; linux_termios->c_cc[LINUX_VERASE] = bsd_termios->c_cc[VERASE]; linux_termios->c_cc[LINUX_VKILL] = bsd_termios->c_cc[VKILL]; linux_termios->c_cc[LINUX_VEOF] = bsd_termios->c_cc[VEOF]; linux_termios->c_cc[LINUX_VEOL] = bsd_termios->c_cc[VEOL]; linux_termios->c_cc[LINUX_VMIN] = bsd_termios->c_cc[VMIN]; linux_termios->c_cc[LINUX_VTIME] = bsd_termios->c_cc[VTIME]; linux_termios->c_cc[LINUX_VEOL2] = bsd_termios->c_cc[VEOL2]; linux_termios->c_cc[LINUX_VSWTC] = _POSIX_VDISABLE; linux_termios->c_cc[LINUX_VSUSP] = bsd_termios->c_cc[VSUSP]; linux_termios->c_cc[LINUX_VSTART] = bsd_termios->c_cc[VSTART]; linux_termios->c_cc[LINUX_VSTOP] = bsd_termios->c_cc[VSTOP]; linux_termios->c_cc[LINUX_VREPRINT] = bsd_termios->c_cc[VREPRINT]; linux_termios->c_cc[LINUX_VDISCARD] = bsd_termios->c_cc[VDISCARD]; linux_termios->c_cc[LINUX_VWERASE] = bsd_termios->c_cc[VWERASE]; linux_termios->c_cc[LINUX_VLNEXT] = bsd_termios->c_cc[VLNEXT]; linux_termios->c_line = 0; #ifdef DEBUG printf("LINUX: LINUX termios structure (output):\n"); printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif } static void linux_to_bsd_termios(struct linux_termios *linux_termios, struct termios *bsd_termios) { int i, speed; #ifdef DEBUG printf("LINUX: LINUX termios structure (input):\n"); printf("i=%08x o=%08x c=%08x l=%08x line=%d\n", linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag, linux_termios->c_lflag, linux_termios->c_line); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif bsd_termios->c_iflag = 0; if (linux_termios->c_iflag & LINUX_IGNBRK) bsd_termios->c_iflag |= IGNBRK; if (linux_termios->c_iflag & LINUX_BRKINT) bsd_termios->c_iflag |= BRKINT; if (linux_termios->c_iflag & LINUX_IGNPAR) bsd_termios->c_iflag |= IGNPAR; if (linux_termios->c_iflag & LINUX_PARMRK) bsd_termios->c_iflag |= PARMRK; if (linux_termios->c_iflag & LINUX_INPCK) bsd_termios->c_iflag |= INPCK; if (linux_termios->c_iflag & LINUX_ISTRIP) bsd_termios->c_iflag |= ISTRIP; if (linux_termios->c_iflag & LINUX_INLCR) bsd_termios->c_iflag |= INLCR; if (linux_termios->c_iflag & LINUX_IGNCR) bsd_termios->c_iflag |= IGNCR; if (linux_termios->c_iflag & LINUX_ICRNL) bsd_termios->c_iflag |= ICRNL; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |= IXANY; if (linux_termios->c_iflag & LINUX_IXON) bsd_termios->c_iflag |= IXON; if (linux_termios->c_iflag & LINUX_IXOFF) bsd_termios->c_iflag |= IXOFF; if (linux_termios->c_iflag & LINUX_IMAXBEL) bsd_termios->c_iflag |= IMAXBEL; bsd_termios->c_oflag = 0; if (linux_termios->c_oflag & LINUX_OPOST) bsd_termios->c_oflag |= OPOST; if (linux_termios->c_oflag & LINUX_ONLCR) bsd_termios->c_oflag |= ONLCR; if (linux_termios->c_oflag & LINUX_XTABS) bsd_termios->c_oflag |= OXTABS; bsd_termios->c_cflag = (linux_termios->c_cflag & LINUX_CSIZE) << 4; if (linux_termios->c_cflag & LINUX_CSTOPB) bsd_termios->c_cflag |= CSTOPB; if (linux_termios->c_cflag & LINUX_PARENB) bsd_termios->c_cflag |= PARENB; if (linux_termios->c_cflag & LINUX_PARODD) bsd_termios->c_cflag |= PARODD; if (linux_termios->c_cflag & LINUX_HUPCL) bsd_termios->c_cflag |= HUPCL; if (linux_termios->c_cflag & LINUX_CLOCAL) bsd_termios->c_cflag |= CLOCAL; if (linux_termios->c_cflag & LINUX_CRTSCTS) bsd_termios->c_cflag |= CRTSCTS; bsd_termios->c_lflag = 0; if (linux_termios->c_lflag & LINUX_ISIG) bsd_termios->c_lflag |= ISIG; if (linux_termios->c_lflag & LINUX_ICANON) bsd_termios->c_lflag |= ICANON; if (linux_termios->c_lflag & LINUX_ECHO) bsd_termios->c_lflag |= ECHO; if (linux_termios->c_lflag & LINUX_ECHOE) bsd_termios->c_lflag |= ECHOE; if (linux_termios->c_lflag & LINUX_ECHOK) bsd_termios->c_lflag |= ECHOK; if (linux_termios->c_lflag & LINUX_ECHONL) bsd_termios->c_lflag |= ECHONL; if (linux_termios->c_lflag & LINUX_NOFLSH) bsd_termios->c_lflag |= NOFLSH; if (linux_termios->c_lflag & LINUX_TOSTOP) bsd_termios->c_lflag |= TOSTOP; if (linux_termios->c_lflag & LINUX_ECHOCTL) bsd_termios->c_lflag |= ECHOCTL; if (linux_termios->c_lflag & LINUX_ECHOPRT) bsd_termios->c_lflag |= ECHOPRT; if (linux_termios->c_lflag & LINUX_ECHOKE) bsd_termios->c_lflag |= ECHOKE; if (linux_termios->c_lflag & LINUX_FLUSHO) bsd_termios->c_lflag |= FLUSHO; if (linux_termios->c_lflag & LINUX_PENDIN) bsd_termios->c_lflag |= PENDIN; if (linux_termios->c_lflag & IEXTEN) bsd_termios->c_lflag |= IEXTEN; for (i=0; ic_cc[i] = _POSIX_VDISABLE; bsd_termios->c_cc[VINTR] = linux_termios->c_cc[LINUX_VINTR]; bsd_termios->c_cc[VQUIT] = linux_termios->c_cc[LINUX_VQUIT]; bsd_termios->c_cc[VERASE] = linux_termios->c_cc[LINUX_VERASE]; bsd_termios->c_cc[VKILL] = linux_termios->c_cc[LINUX_VKILL]; bsd_termios->c_cc[VEOF] = linux_termios->c_cc[LINUX_VEOF]; bsd_termios->c_cc[VEOL] = linux_termios->c_cc[LINUX_VEOL]; bsd_termios->c_cc[VMIN] = linux_termios->c_cc[LINUX_VMIN]; bsd_termios->c_cc[VTIME] = linux_termios->c_cc[LINUX_VTIME]; bsd_termios->c_cc[VEOL2] = linux_termios->c_cc[LINUX_VEOL2]; bsd_termios->c_cc[VSUSP] = linux_termios->c_cc[LINUX_VSUSP]; bsd_termios->c_cc[VSTART] = linux_termios->c_cc[LINUX_VSTART]; bsd_termios->c_cc[VSTOP] = linux_termios->c_cc[LINUX_VSTOP]; bsd_termios->c_cc[VREPRINT] = linux_termios->c_cc[LINUX_VREPRINT]; bsd_termios->c_cc[VDISCARD] = linux_termios->c_cc[LINUX_VDISCARD]; bsd_termios->c_cc[VWERASE] = linux_termios->c_cc[LINUX_VWERASE]; bsd_termios->c_cc[VLNEXT] = linux_termios->c_cc[LINUX_VLNEXT]; bsd_termios->c_ispeed = bsd_termios->c_ospeed = linux_to_bsd_speed(linux_termios->c_cflag & LINUX_CBAUD, sptab); #ifdef DEBUG printf("LINUX: BSD termios structure (output):\n"); printf("i=%08x o=%08x c=%08x l=%08x ispeed=%d ospeed=%d\n", bsd_termios->c_iflag, bsd_termios->c_oflag, bsd_termios->c_cflag, bsd_termios->c_lflag, bsd_termios->c_ispeed, bsd_termios->c_ospeed); printf("c_cc "); for (i=0; ic_cc[i]); printf("\n"); #endif } struct linux_ioctl_args { int fd; int cmd; int arg; }; int linux_ioctl(struct proc *p, struct linux_ioctl_args *args, int *retval) { struct termios bsd_termios; struct winsize bsd_winsize; struct linux_termios linux_termios; struct linux_winsize linux_winsize; struct filedesc *fdp = p->p_fd; struct file *fp; int (*func)(struct file *fp, int com, caddr_t data, struct proc *p); int bsd_line, linux_line; int error; #ifdef DEBUG printf("Linux-emul(%d): ioctl(%d, %04x, *)\n", p->p_pid, args->fd, args->cmd); #endif 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 (args->cmd) { case LINUX_TCGETS: if ((error = (*func)(fp, TIOCGETA, (caddr_t)&bsd_termios, p)) != 0) return error; bsd_to_linux_termios(&bsd_termios, &linux_termios); return copyout((caddr_t)&linux_termios, (caddr_t)args->arg, sizeof(linux_termios)); case LINUX_TCSETS: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETA, (caddr_t)&bsd_termios, p); case LINUX_TCSETSW: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAW, (caddr_t)&bsd_termios, p); case LINUX_TCSETSF: linux_to_bsd_termios((struct linux_termios *)args->arg, &bsd_termios); return (*func)(fp, TIOCSETAF, (caddr_t)&bsd_termios, p); case LINUX_TIOCGPGRP: args->cmd = TIOCGPGRP; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSPGRP: args->cmd = TIOCSPGRP; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCGWINSZ: args->cmd = TIOCGWINSZ; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSWINSZ: args->cmd = TIOCSWINSZ; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONREAD: args->cmd = FIONREAD; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONBIO: args->cmd = FIONBIO; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIOASYNC: args->cmd = FIOASYNC; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIONCLEX: args->cmd = FIONCLEX; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_FIOCLEX: args->cmd = FIOCLEX; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCEXCL: args->cmd = TIOCEXCL; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCNXCL: args->cmd = TIOCNXCL; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCCONS: args->cmd = TIOCCONS; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCNOTTY: args->cmd = TIOCNOTTY; - return ioctl(p, args, retval); + return ioctl(p, (struct ioctl_args *)args, retval); case LINUX_TIOCSETD: switch (args->arg) { case LINUX_N_TTY: bsd_line = TTYDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_SLIP: bsd_line = SLIPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); case LINUX_N_PPP: bsd_line = PPPDISC; return (*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p); default: return EINVAL; } break; case LINUX_TIOCGETD: bsd_line = TTYDISC; if (error =(*func)(fp, TIOCSETD, (caddr_t)&bsd_line, p)) return error; switch (bsd_line) { case TTYDISC: linux_line = LINUX_N_TTY; break; case SLIPDISC: linux_line = LINUX_N_SLIP; break; case PPPDISC: linux_line = LINUX_N_PPP; break; default: return EINVAL; } return copyout(&linux_line, (caddr_t)args->arg, sizeof(int)); } uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n", args->fd, (args->cmd&0xffff00)>>8, (args->cmd&0xffff00)>>8, args->cmd&0xff); return EINVAL; } diff --git a/sys/i386/linux/linux_misc.c b/sys/i386/linux/linux_misc.c index 31995c5a64e2..cce887e4e8af 100644 --- a/sys/i386/linux/linux_misc.c +++ b/sys/i386/linux/linux_misc.c @@ -1,677 +1,676 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_misc.c,v 1.6 1995/12/09 08:17:24 peter Exp $ + * $Id: linux_misc.c,v 1.7 1995/12/14 22:35:45 bde Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include struct linux_alarm_args { unsigned int secs; }; int linux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval) { struct itimerval it, old_it; + struct timeval tv; int s; #ifdef DEBUG printf("Linux-emul(%d): alarm(%d)\n", p->p_pid, args->secs); #endif 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(); old_it = p->p_realtimer; + tv = time; if (timerisset(&old_it.it_value)) - if (timercmp(&old_it.it_value, &time, <)) + if (timercmp(&old_it.it_value, &tv, <)) timerclear(&old_it.it_value); else - timevalsub(&old_it.it_value, &time); + timevalsub(&old_it.it_value, &tv); splx(s); if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) return EINVAL; s = splclock(); untimeout(realitexpire, (caddr_t)p); + tv = time; if (timerisset(&it.it_value)) { - timevaladd(&it.it_value, &time); + timevaladd(&it.it_value, &tv); timeout(realitexpire, (caddr_t)p, hzto(&it.it_value)); } p->p_realtimer = it; splx(s); if (old_it.it_value.tv_usec) old_it.it_value.tv_sec++; *retval = old_it.it_value.tv_sec; return 0; } struct linux_brk_args { linux_caddr_t dsend; }; int linux_brk(struct proc *p, struct linux_brk_args *args, int *retval) { #if 0 struct vmspace *vm = p->p_vmspace; vm_offset_t new, old; int error; 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); *retval = old; if ((new-old) > 0) { if (swap_pager_full) return ENOMEM; error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE); if (error) return error; vm->vm_dsize += btoc((new-old)); *retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); } return 0; #else struct vmspace *vm = p->p_vmspace; vm_offset_t new, old; - struct obreak_args { - vm_offset_t newsize; - } tmp; + struct obreak_args /* { + char * nsize; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend); #endif old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); new = (vm_offset_t)args->dsend; - tmp.newsize = new; + tmp.nsize = (char *) new; if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval)) retval[0] = (int)new; else retval[0] = (int)old; return 0; #endif } struct linux_uselib_args { char *library; }; int linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) { struct nameidata ni; struct vnode *vp; struct exec *a_out = 0; struct vattr attr; unsigned long vmaddr, virtual_offset, file_offset; unsigned long buffer, bss_size; char *ptr; char path[MAXPATHLEN]; const char *prefix = "/compat/linux"; size_t sz, len; int error; #ifdef DEBUG printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library); #endif for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ; sz = MAXPATHLEN - (ptr - path); if (error = copyinstr(args->library, ptr, sz, &len)) return error; if (*ptr != '/') return EINVAL; #ifdef DEBUG printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); #endif NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); if (error = namei(&ni)) return error; vp = ni.ni_vp; if (vp == NULL) return ENOEXEC; if (vp->v_writecount) { VOP_UNLOCK(vp); return ETXTBSY; } if (error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { VOP_UNLOCK(vp); return ENOEXEC; } if (attr.va_size == 0) { VOP_UNLOCK(vp); return ENOEXEC; } if (error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } if (error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) { VOP_UNLOCK(vp); return error; } VOP_UNLOCK(vp); /* lock no longer needed */ error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); if (error) return (error); /* * Is it a Linux binary ? */ if (((a_out->a_magic >> 16) & 0xff) != 0x64) return ENOEXEC; /* * Set file/virtual offset based on a.out variant. */ switch ((int)(a_out->a_magic & 0xffff)) { case 0413: /* ZMAGIC */ virtual_offset = 0; file_offset = 1024; break; case 0314: /* QMAGIC */ virtual_offset = 4096; file_offset = 0; break; default: return ENOEXEC; } vp->v_flag |= VTEXT; bss_size = round_page(a_out->a_bss); /* * Check if file_offset page aligned,. * Currently we cannot handle misalinged file offsets, * and so we read in the entire image (what a waste). */ if (file_offset & PGOFSET) { #ifdef DEBUG printf("uselib: Non page aligned binary %d\n", file_offset); #endif /* * Map text+data read/write/execute */ vmaddr = virtual_offset + round_page(a_out->a_entry); error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, round_page(a_out->a_text + a_out->a_data), FALSE); if (error) return error; error = vm_mmap(kernel_map, &buffer, round_page(a_out->a_text + a_out->a_data + file_offset), VM_PROT_READ, VM_PROT_READ, MAP_FILE, (caddr_t)vp, trunc_page(file_offset)); if (error) return error; error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr, a_out->a_text + a_out->a_data); if (error) return error; vm_map_remove(kernel_map, trunc_page(vmaddr), round_page(a_out->a_text + a_out->a_data + file_offset)); error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, round_page(a_out->a_text + a_out->a_data), VM_PROT_ALL, TRUE); if (error) return error; } else { #ifdef DEBUG printf("uselib: Page aligned binary %d\n", file_offset); #endif vmaddr = virtual_offset + round_page(a_out->a_entry); error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, a_out->a_text + a_out->a_data, VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, (caddr_t)vp, file_offset); if (error) return (error); } #ifdef DEBUG printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); #endif if (bss_size != 0) { vmaddr = virtual_offset + round_page(a_out->a_entry) + round_page(a_out->a_text + a_out->a_data); error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, bss_size, FALSE); if (error) return error; error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size, VM_PROT_ALL, TRUE); if (error) return error; } return 0; } struct linux_select_args { void *ptr; }; int linux_select(struct proc *p, struct linux_select_args *args, int *retval) { struct { int nfds; fd_set *readfds; fd_set *writefds; fd_set *exceptfds; struct timeval *timeout; } linux_args; - struct { + struct select_args /* { unsigned int nd; fd_set *in; fd_set *ou; fd_set *ex; struct timeval *tv; - } bsd_args; + } */ bsd_args; int error; if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, sizeof(linux_args)))) return error; #ifdef DEBUG printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n", p->p_pid, linux_args.nfds, linux_args.readfds, linux_args.writefds, linux_args.exceptfds, linux_args.timeout); #endif bsd_args.nd = linux_args.nfds; bsd_args.in = linux_args.readfds; bsd_args.ou = linux_args.writefds; bsd_args.ex = linux_args.exceptfds; bsd_args.tv = linux_args.timeout; return select(p, &bsd_args, retval); } struct linux_getpgid_args { int pid; }; int linux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval) { struct proc *curproc; #ifdef DEBUG printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); #endif if (args->pid != p->p_pid) { if (!(curproc = pfind(args->pid))) return ESRCH; } else curproc = p; *retval = curproc->p_pgid; return 0; } int linux_fork(struct proc *p, void *args, int *retval) { int error; #ifdef DEBUG printf("Linux-emul(%d): fork()\n", p->p_pid); #endif if (error = fork(p, args, retval)) return error; if (retval[1] == 1) retval[0] = 0; return 0; } struct linux_mmap_args { void *ptr; }; int linux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval) { struct { linux_caddr_t addr; int len; int prot; int flags; int fd; int pos; } linux_args; - struct { + struct mmap_args /* { caddr_t addr; size_t len; int prot; int flags; int fd; long pad; off_t pos; - } bsd_args; + } */ bsd_args; int error; if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, sizeof(linux_args)))) return error; #ifdef DEBUG printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n", p->p_pid, linux_args.addr, linux_args.len, linux_args.prot, linux_args.flags, linux_args.fd, linux_args.pos); #endif bsd_args.flags = 0; if (linux_args.flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; if (linux_args.flags & LINUX_MAP_PRIVATE) bsd_args.flags |= MAP_PRIVATE; if (linux_args.flags & LINUX_MAP_FIXED) bsd_args.flags |= MAP_FIXED; if (linux_args.flags & LINUX_MAP_ANON) bsd_args.flags |= MAP_ANON; bsd_args.addr = linux_args.addr; bsd_args.len = linux_args.len; bsd_args.prot = linux_args.prot; bsd_args.fd = linux_args.fd; bsd_args.pos = linux_args.pos; bsd_args.pad = 0; return mmap(p, &bsd_args, retval); } struct linux_pipe_args { int *pipefds; }; int linux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval) { int error; #ifdef DEBUG printf("Linux-emul(%d): pipe(*)\n", p->p_pid); #endif if (error = pipe(p, 0, retval)) return error; if (error = copyout(retval, args->pipefds, 2*sizeof(int))) return error; *retval = 0; return 0; } struct linux_time_args { linux_time_t *tm; }; int linux_time(struct proc *p, struct linux_time_args *args, int *retval) { struct timeval tv; linux_time_t tm; int error; #ifdef DEBUG printf("Linux-emul(%d): time(*)\n", p->p_pid); #endif microtime(&tv); tm = tv.tv_sec; if (error = copyout(&tm, args->tm, sizeof(linux_time_t))) return error; *retval = tv.tv_sec; return 0; } struct linux_tms { long tms_utime; long tms_stime; long tms_cutime; long tms_cstime; }; struct linux_tms_args { char *buf; }; int linux_times(struct proc *p, struct linux_tms_args *args, int *retval) { struct timeval tv; struct linux_tms tms; #ifdef DEBUG printf("Linux-emul(%d): times(*)\n", p->p_pid); #endif 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->buf, sizeof(struct linux_tms))); } struct linux_newuname_t { char sysname[65]; char nodename[65]; char release[65]; char version[65]; char machine[65]; char domainname[65]; }; struct linux_newuname_args { char *buf; }; int linux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval) { struct linux_newuname_t linux_newuname; #ifdef DEBUG printf("Linux-emul(%d): newuname(*)\n", p->p_pid); #endif bzero(&linux_newuname, sizeof(struct linux_newuname_args)); strncpy(linux_newuname.sysname, ostype, 64); strncpy(linux_newuname.nodename, hostname, 64); strncpy(linux_newuname.release, osrelease, 64); strncpy(linux_newuname.version, version, 64); strncpy(linux_newuname.machine, machine, 64); strncpy(linux_newuname.domainname, domainname, 64); return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf, sizeof(struct linux_newuname_t))); } struct linux_utime_args { char *fname; linux_time_t *timeptr; }; int linux_utime(struct proc *p, struct linux_utime_args *args, int *retval) { - struct bsd_utimes_args { - char *fname; + struct utimes_args /* { + char *path; struct timeval *tptr; - } bsdutimes; + } */ bsdutimes; struct timeval tv; #ifdef DEBUG printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname); #endif tv.tv_sec = (long)args->timeptr; tv.tv_usec = 0; bsdutimes.tptr = &tv; - bsdutimes.fname = args->fname; + bsdutimes.path = args->fname; return utimes(p, &bsdutimes, retval); } struct linux_waitpid_args { int pid; int *status; int options; }; int linux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval) { - struct wait4_args { + struct wait_args /* { int pid; int *status; int options; struct rusage *rusage; - int compat; - } tmp; + } */ tmp; int error, tmpstat; #ifdef DEBUG printf("Linux-emul(%d): waitpid(%d, *, %d)\n", p->p_pid, args->pid, args->options); #endif tmp.pid = args->pid; tmp.status = args->status; tmp.options = args->options; tmp.rusage = NULL; - tmp.compat = 0; if (error = wait4(p, &tmp, retval)) return error; if (error = copyin(args->status, &tmpstat, sizeof(int))) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | bsd_to_linux_signal[WTERMSIG(tmpstat)]; else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); return copyout(&tmpstat, args->status, sizeof(int)); } struct linux_wait4_args { int pid; int *status; int options; struct rusage *rusage; }; int linux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval) { - struct wait4_args { + struct wait_args /* { int pid; int *status; int options; struct rusage *rusage; - int compat; - } tmp; + } */ tmp; int error, tmpstat; #ifdef DEBUG printf("Linux-emul(%d): wait4(%d, *, %d, *)\n", p->p_pid, args->pid, args->options); #endif tmp.pid = args->pid; tmp.status = args->status; tmp.options = args->options; tmp.rusage = args->rusage; - tmp.compat = 0; if (error = wait4(p, &tmp, retval)) return error; if (error = copyin(args->status, &tmpstat, sizeof(int))) return error; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | bsd_to_linux_signal[WTERMSIG(tmpstat)]; else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); return copyout(&tmpstat, args->status, sizeof(int)); } diff --git a/sys/i386/linux/linux_signal.c b/sys/i386/linux/linux_signal.c index 1c63681e6e12..fc5c2cd7c274 100644 --- a/sys/i386/linux/linux_signal.c +++ b/sys/i386/linux/linux_signal.c @@ -1,259 +1,261 @@ /*- * Copyright (c) 1994-1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_signal.c,v 1.1 1995/06/25 17:32:40 sos Exp $ + * $Id: linux_signal.c,v 1.2 1995/11/22 07:43:50 bde Exp $ */ #include #include #include #include #include #include #include #include #include #define DONTMASK (sigmask(SIGKILL)|sigmask(SIGSTOP)|sigmask(SIGCHLD)) static sigset_t linux_to_bsd_sigmask(linux_sigset_t mask) { int i; sigset_t new = 0; for (i = 1; i <= LINUX_NSIG; i++) if (mask & (1 << i-1)) new |= (1 << (linux_to_bsd_signal[i]-1)); return new; } static linux_sigset_t bsd_to_linux_sigmask(sigset_t mask) { int i; sigset_t new = 0; for (i = 1; i <= NSIG; i++) if (mask & (1 << i-1)) new |= (1 << (bsd_to_linux_signal[i]-1)); return new; } struct linux_sigaction_args { int sig; linux_sigaction_t *nsa; linux_sigaction_t *osa; }; int linux_sigaction(struct proc *p, struct linux_sigaction_args *args, int *retval) { linux_sigaction_t linux_sa; struct sigaction *nsa = NULL, *osa = NULL, bsd_sa; - struct sigaction_args { - int sig; + struct sigaction_args /* { + int signum; struct sigaction *nsa; struct sigaction *osa; - } sa; + } */ sa; int error; #ifdef DEBUG printf("Linux-emul(%d): sigaction(%d, *, *)\n", p->p_pid, args->sig); #endif if (args->osa) osa = (struct sigaction *)ua_alloc_init(sizeof(struct sigaction)); if (args->nsa) { nsa = (struct sigaction *)ua_alloc(sizeof(struct sigaction)); if (error = copyin(args->nsa, &linux_sa, sizeof(linux_sigaction_t))) return error; bsd_sa.sa_mask = linux_to_bsd_sigmask(linux_sa.sa_mask); bsd_sa.sa_handler = linux_sa.sa_handler; bsd_sa.sa_flags = 0; if (linux_sa.sa_flags & LINUX_SA_NOCLDSTOP) bsd_sa.sa_flags |= SA_NOCLDSTOP; if (linux_sa.sa_flags & LINUX_SA_ONSTACK) bsd_sa.sa_flags |= SA_ONSTACK; if (linux_sa.sa_flags & LINUX_SA_RESTART) bsd_sa.sa_flags |= SA_RESTART; if (error = copyout(&bsd_sa, nsa, sizeof(struct sigaction))) return error; } - sa.sig = linux_to_bsd_signal[args->sig]; + sa.signum = linux_to_bsd_signal[args->sig]; sa.nsa = nsa; sa.osa = osa; if ((error = sigaction(p, &sa, retval))) return error; if (args->osa) { if (error = copyin(osa, &bsd_sa, sizeof(struct sigaction))) return error; linux_sa.sa_handler = bsd_sa.sa_handler; linux_sa.sa_restorer = NULL; linux_sa.sa_mask = bsd_to_linux_sigmask(bsd_sa.sa_mask); linux_sa.sa_flags = 0; if (bsd_sa.sa_flags & SA_NOCLDSTOP) linux_sa.sa_flags |= LINUX_SA_NOCLDSTOP; if (bsd_sa.sa_flags & SA_ONSTACK) linux_sa.sa_flags |= LINUX_SA_ONSTACK; if (bsd_sa.sa_flags & SA_RESTART) linux_sa.sa_flags |= LINUX_SA_RESTART; if (error = copyout(&linux_sa, args->osa, sizeof(linux_sigaction_t))) return error; } return 0; } struct linux_sigprocmask_args { int how; linux_sigset_t *mask; linux_sigset_t *omask; }; int linux_sigprocmask(struct proc *p, struct linux_sigprocmask_args *args, int *retval) { int error, s; sigset_t mask; sigset_t omask; #ifdef DEBUG printf("Linux-emul(%d): sigprocmask(%d, *, *)\n", p->p_pid, args->how); #endif if (args->omask != NULL) { omask = bsd_to_linux_sigmask(p->p_sigmask); if (error = copyout(&omask, args->omask, sizeof(sigset_t))) return error; } if (!(args->mask)) return 0; if (error = copyin(args->mask, &mask, sizeof(linux_sigset_t))) return error; mask = linux_to_bsd_sigmask(mask); s = splhigh(); switch (args->how) { case LINUX_SIG_BLOCK: p->p_sigmask |= (mask & ~DONTMASK); break; case LINUX_SIG_UNBLOCK: p->p_sigmask &= ~mask; break; case LINUX_SIG_SETMASK: p->p_sigmask = (mask & ~DONTMASK); break; default: error = EINVAL; break; } splx(s); return error; } int linux_siggetmask(struct proc *p, void *args, int *retval) { #ifdef DEBUG printf("Linux-emul(%d): siggetmask()\n", p->p_pid); #endif *retval = bsd_to_linux_sigmask(p->p_sigmask); return 0; } struct linux_sigsetmask_args { linux_sigset_t mask; }; int linux_sigsetmask(struct proc *p, struct linux_sigsetmask_args *args,int *retval) { int s; #ifdef DEBUG printf("Linux-emul(%d): sigsetmask(%08x)\n", p->p_pid, args->mask); #endif s = splhigh(); p->p_sigmask = (linux_to_bsd_sigmask(args->mask) & ~DONTMASK); splx(s); *retval = bsd_to_linux_sigmask(p->p_sigmask); return 0; } struct linux_sigpending_args { linux_sigset_t *mask; }; int linux_sigpending(struct proc *p, struct linux_sigpending_args *args,int *retval) { linux_sigset_t linux_sig; #ifdef DEBUG printf("Linux-emul(%d): sigpending(*)\n", p->p_pid); #endif linux_sig = bsd_to_linux_sigmask(p->p_siglist & p->p_sigmask); return copyout(&linux_sig, args->mask, sizeof(linux_sig)); } struct linux_sigsuspend_args { linux_sigset_t mask; }; int linux_sigsuspend(struct proc *p, struct linux_sigsuspend_args *args,int *retval) { - sigset_t tmp; + struct sigsuspend_args /* { + int mask; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): sigsuspend(%08x)\n", p->p_pid, args->mask); #endif - tmp = linux_to_bsd_sigmask(args->mask); + tmp.mask = linux_to_bsd_sigmask(args->mask); return sigsuspend(p, &tmp , retval); } struct linux_kill_args { int pid; int signum; }; int linux_kill(struct proc *p, struct linux_kill_args *args, int *retval) { - struct { + struct kill_args /* { int pid; int signum; - } tmp; + } */ tmp; #ifdef DEBUG printf("Linux-emul(%d): kill(%d, %d)\n", p->p_pid, args->pid, args->signum); #endif tmp.pid = args->pid; tmp.signum = linux_to_bsd_signal[args->signum]; return kill(p, &tmp, retval); } diff --git a/sys/i386/linux/linux_socket.c b/sys/i386/linux/linux_socket.c index b803111acb53..da4668c674e1 100644 --- a/sys/i386/linux/linux_socket.c +++ b/sys/i386/linux/linux_socket.c @@ -1,601 +1,601 @@ /*- * Copyright (c) 1995 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_socket.c,v 1.1 1995/06/25 17:32:41 sos Exp $ + * $Id: linux_socket.c,v 1.2 1995/11/22 07:43:50 bde Exp $ */ /* XXX we use functions that might not exist. */ #define COMPAT_43 1 #include #include #include #include #include #include #include #include #include static int linux_to_bsd_domain(int domain) { switch (domain) { case LINUX_AF_UNSPEC: return AF_UNSPEC; case LINUX_AF_UNIX: return AF_LOCAL; case LINUX_AF_INET: return AF_INET; case LINUX_AF_AX25: return AF_CCITT; case LINUX_AF_IPX: return AF_IPX; case LINUX_AF_APPLETALK: return AF_APPLETALK; default: return -1; } } static int linux_to_bsd_sockopt_level(int level) { switch (level) { case LINUX_SOL_SOCKET: return SOL_SOCKET; default: return level; } } static int linux_to_bsd_ip_sockopt(int opt) { switch (opt) { case LINUX_IP_TOS: return IP_TOS; case LINUX_IP_TTL: return IP_TTL; default: return -1; } } static int linux_to_bsd_so_sockopt(int opt) { switch (opt) { case LINUX_SO_DEBUG: return SO_DEBUG; case LINUX_SO_REUSEADDR: return SO_REUSEADDR; case LINUX_SO_TYPE: return SO_TYPE; case LINUX_SO_ERROR: return SO_ERROR; case LINUX_SO_DONTROUTE: return SO_DONTROUTE; case LINUX_SO_BROADCAST: return SO_BROADCAST; case LINUX_SO_SNDBUF: return SO_SNDBUF; case LINUX_SO_RCVBUF: return SO_RCVBUF; case LINUX_SO_KEEPALIVE: return SO_KEEPALIVE; case LINUX_SO_OOBINLINE: return SO_OOBINLINE; case LINUX_SO_LINGER: return SO_LINGER; case LINUX_SO_PRIORITY: case LINUX_SO_NO_CHECK: default: return -1; } } struct linux_socket_args { int domain; int type; int protocol; }; static int linux_socket(struct proc *p, struct linux_socket_args *args, int *retval) { struct linux_socket_args linux_args; - struct { + struct socket_args /* { int domain; int type; int protocol; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.protocol = linux_args.protocol; bsd_args.type = linux_args.type; bsd_args.domain = linux_to_bsd_domain(linux_args.domain); if (bsd_args.domain == -1) return EINVAL; return socket(p, &bsd_args, retval); } struct linux_bind_args { int s; struct sockaddr *name; int namelen; }; static int linux_bind(struct proc *p, struct linux_bind_args *args, int *retval) { struct linux_bind_args linux_args; - struct { + struct bind_args /* { int s; caddr_t name; int namelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; bsd_args.namelen = linux_args.namelen; return bind(p, &bsd_args, retval); } struct linux_connect_args { int s; struct sockaddr * name; int namelen; }; static int linux_connect(struct proc *p, struct linux_connect_args *args, int *retval) { struct linux_connect_args linux_args; - struct { + struct connect_args /* { int s; caddr_t name; int namelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.name; bsd_args.namelen = linux_args.namelen; return connect(p, &bsd_args, retval); } struct linux_listen_args { int s; int backlog; }; static int linux_listen(struct proc *p, struct linux_listen_args *args, int *retval) { struct linux_listen_args linux_args; - struct { + struct listen_args /* { int s; int backlog; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.backlog = linux_args.backlog; return listen(p, &bsd_args, retval); } struct linux_accept_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_accept(struct proc *p, struct linux_accept_args *args, int *retval) { struct linux_accept_args linux_args; - struct accept_args { + struct accept_args /* { int s; caddr_t name; int *anamelen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.name = (caddr_t)linux_args.addr; bsd_args.anamelen = linux_args.namelen; return oaccept(p, &bsd_args, retval); } struct linux_getsockname_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_getsockname(struct proc *p, struct linux_getsockname_args *args, int *retval) { struct linux_getsockname_args linux_args; - struct { + struct getsockname_args /* { int fdes; caddr_t asa; int *alen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.fdes = linux_args.s; bsd_args.asa = (caddr_t) linux_args.addr; bsd_args.alen = linux_args.namelen; return ogetsockname(p, &bsd_args, retval); } struct linux_getpeername_args { int s; struct sockaddr *addr; int *namelen; }; static int linux_getpeername(struct proc *p, struct linux_getpeername_args *args, int *retval) { struct linux_getpeername_args linux_args; - struct getpeername_args { + struct ogetpeername_args /* { int fdes; caddr_t asa; int *alen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.fdes = linux_args.s; bsd_args.asa = (caddr_t) linux_args.addr; bsd_args.alen = linux_args.namelen; return ogetpeername(p, &bsd_args, retval); } struct linux_socketpair_args { int domain; int type; int protocol; int *rsv; }; static int linux_socketpair(struct proc *p, struct linux_socketpair_args *args, int *retval) { struct linux_socketpair_args linux_args; - struct { + struct socketpair_args /* { int domain; int type; int protocol; int *rsv; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.domain = linux_to_bsd_domain(linux_args.domain); if (bsd_args.domain == -1) return EINVAL; bsd_args.type = linux_args.type; bsd_args.protocol = linux_args.protocol; bsd_args.rsv = linux_args.rsv; return socketpair(p, &bsd_args, retval); } struct linux_send_args { int s; void *msg; int len; int flags; }; static int linux_send(struct proc *p, struct linux_send_args *args, int *retval) { struct linux_send_args linux_args; - struct { + struct osend_args /* { int s; caddr_t buf; int len; int flags; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; return osend(p, &bsd_args, retval); } struct linux_recv_args { int s; void *msg; int len; int flags; }; static int linux_recv(struct proc *p, struct linux_recv_args *args, int *retval) { struct linux_recv_args linux_args; - struct { + struct orecv_args /* { int s; caddr_t buf; int len; int flags; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; return orecv(p, &bsd_args, retval); } struct linux_sendto_args { int s; void *msg; int len; int flags; caddr_t to; int tolen; }; static int linux_sendto(struct proc *p, struct linux_sendto_args *args, int *retval) { struct linux_sendto_args linux_args; - struct { + struct sendto_args /* { int s; caddr_t buf; size_t len; int flags; caddr_t to; int tolen; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.msg; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.to = linux_args.to; bsd_args.tolen = linux_args.tolen; return sendto(p, &bsd_args, retval); } struct linux_recvfrom_args { int s; void *buf; int len; int flags; caddr_t from; int *fromlen; }; static int linux_recvfrom(struct proc *p, struct linux_recvfrom_args *args, int *retval) { struct linux_recvfrom_args linux_args; - struct { + struct recvfrom_args /* { int s; caddr_t buf; size_t len; int flags; caddr_t from; int *fromlenaddr; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.buf = linux_args.buf; bsd_args.len = linux_args.len; bsd_args.flags = linux_args.flags; bsd_args.from = linux_args.from; bsd_args.fromlenaddr = linux_args.fromlen; return orecvfrom(p, &bsd_args, retval); } struct linux_shutdown_args { int s; int how; }; static int linux_shutdown(struct proc *p, struct linux_shutdown_args *args, int *retval) { struct linux_shutdown_args linux_args; - struct { + struct shutdown_args /* { int s; int how; - } bsd_args; + } */ bsd_args; int error; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.how = linux_args.how; return shutdown(p, &bsd_args, retval); } struct linux_setsockopt_args { int s; int level; int optname; void *optval; int optlen; }; static int linux_setsockopt(struct proc *p, struct linux_setsockopt_args *args, int *retval) { struct linux_setsockopt_args linux_args; - struct { + struct setsockopt_args /* { int s; int level; int name; caddr_t val; int valsize; - } bsd_args; + } */ bsd_args; int error, name; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(linux_args.optname); break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(linux_args.optname); break; default: return EINVAL; } if (name == -1) return EINVAL; bsd_args.name = name; bsd_args.val = linux_args.optval; bsd_args.valsize = linux_args.optlen; return setsockopt(p, &bsd_args, retval); } struct linux_getsockopt_args { int s; int level; int optname; void *optval; int *optlen; }; static int linux_getsockopt(struct proc *p, struct linux_getsockopt_args *args, int *retval) { struct linux_getsockopt_args linux_args; - struct { + struct getsockopt_args /* { int s; int level; int name; caddr_t val; int *avalsize; - } bsd_args; + } */ bsd_args; int error, name; if ((error=copyin((caddr_t)args, (caddr_t)&linux_args, sizeof(linux_args)))) return error; bsd_args.s = linux_args.s; bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level); switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(linux_args.optname); break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(linux_args.optname); break; default: return EINVAL; } if (name == -1) return EINVAL; bsd_args.val = linux_args.optval; bsd_args.avalsize = linux_args.optlen; return getsockopt(p, &bsd_args, retval); } struct linux_socketcall_args { int what; void *args; }; int linux_socketcall(struct proc *p, struct linux_socketcall_args *args,int *retval) { switch (args->what) { case LINUX_SOCKET: return linux_socket(p, args->args, retval); case LINUX_BIND: return linux_bind(p, args->args, retval); case LINUX_CONNECT: return linux_connect(p, args->args, retval); case LINUX_LISTEN: return linux_listen(p, args->args, retval); case LINUX_ACCEPT: return linux_accept(p, args->args, retval); case LINUX_GETSOCKNAME: return linux_getsockname(p, args->args, retval); case LINUX_GETPEERNAME: return linux_getpeername(p, args->args, retval); case LINUX_SOCKETPAIR: return linux_socketpair(p, args->args, retval); case LINUX_SEND: return linux_send(p, args->args, retval); case LINUX_RECV: return linux_recv(p, args->args, retval); case LINUX_SENDTO: return linux_sendto(p, args->args, retval); case LINUX_RECVFROM: return linux_recvfrom(p, args->args, retval); case LINUX_SHUTDOWN: return linux_shutdown(p, args->args, retval); case LINUX_SETSOCKOPT: return linux_setsockopt(p, args->args, retval); case LINUX_GETSOCKOPT: return linux_getsockopt(p, args->args, retval); default: uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what); return ENOSYS; } }