diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /sys/compat/common |
initial import of NetBSD tree
Diffstat (limited to 'sys/compat/common')
-rw-r--r-- | sys/compat/common/Makefile | 23 | ||||
-rw-r--r-- | sys/compat/common/Makefile.inc | 37 | ||||
-rw-r--r-- | sys/compat/common/compat_tty.c | 451 | ||||
-rw-r--r-- | sys/compat/common/compat_util.c | 177 | ||||
-rw-r--r-- | sys/compat/common/compat_util.h | 71 | ||||
-rw-r--r-- | sys/compat/common/kern_exit_43.c | 113 | ||||
-rw-r--r-- | sys/compat/common/kern_info_09.c | 130 | ||||
-rw-r--r-- | sys/compat/common/kern_info_43.c | 228 | ||||
-rw-r--r-- | sys/compat/common/kern_ipc_10.c | 243 | ||||
-rw-r--r-- | sys/compat/common/kern_prot_43.c | 125 | ||||
-rw-r--r-- | sys/compat/common/kern_resource_43.c | 102 | ||||
-rw-r--r-- | sys/compat/common/kern_sig_43.c | 213 | ||||
-rw-r--r-- | sys/compat/common/uipc_syscalls_43.c | 306 | ||||
-rw-r--r-- | sys/compat/common/vfs_syscalls_43.c | 510 |
14 files changed, 2729 insertions, 0 deletions
diff --git a/sys/compat/common/Makefile b/sys/compat/common/Makefile new file mode 100644 index 00000000000..63bc7ec2d36 --- /dev/null +++ b/sys/compat/common/Makefile @@ -0,0 +1,23 @@ +# $NetBSD: Makefile,v 1.3 1995/06/28 03:00:20 cgd Exp $ + +LIB= compat +NOPIC= + +.PATH: ${COMPATREL}${COMPATDIR} + +CC= ${COMPATCC} +CFLAGS+= ${COMPATCFLAGS:S@-I.@-I${COMPATREL}.@g} + +SRCS= compat_tty.c compat_util.c kern_exit_43.c kern_info_09.c \ + kern_info_43.c kern_prot_43.c kern_resource_43.c kern_sig_43.c \ + uipc_syscalls_43.c vfs_syscalls_43.c + +# really, all machines were sizeof(int) != sizeof(long) +.if (${MACHINE_ARCH} != "alpha") +SRCS+= kern_ipc_10.c +.endif + +install: + + +.include <bsd.lib.mk> diff --git a/sys/compat/common/Makefile.inc b/sys/compat/common/Makefile.inc new file mode 100644 index 00000000000..db613f2cb81 --- /dev/null +++ b/sys/compat/common/Makefile.inc @@ -0,0 +1,37 @@ +# $NetBSD: Makefile.inc,v 1.2 1995/06/26 03:27:15 christos Exp $ +# +# NOTE: $S must correspond to the top of the 'sys' tree + +COMPATDIR= $S/compat/common + +COMPATDST?= lib/compat +COMPATREL?= ../../ +COMPATLIB= ${COMPATDST}/libcompat.a +COMPATLIB_PROF= ${COMPATDST}/libcompat_p.a + +${COMPATLIB}: .NOTMAIN __always_make_compatlib + @echo making sure the compat library is up to date... + @(cd ${COMPATDST} && ${MAKE} -f ${COMPATREL}${COMPATDIR}/Makefile \ + COMPATCC="${CC}" \ + COMPATCFLAGS="${CFLAGS}" \ + COMPATREL="${COMPATREL}" \ + COMPATDIR="${COMPATDIR}" libcompat.a) + +${COMPATLIB_PROF}: .NOTMAIN __always_make_compatlib + @echo making sure the profiled compat library is up to date... + @(cd ${COMPATDST} && ${MAKE} -f ${COMPATREL}${COMPATDIR}/Makefile \ + COMPATCC="${CC}" \ + COMPATCFLAGS="${CFLAGS}" \ + COMPATREL="${COMPATREL}" \ + COMPATDIR="${COMPATDIR}" libcompat_p.a) + +clean:: .NOTMAIN __always_make_compatlib + @echo cleaning the compat library objects + @(cd ${COMPATDST} && ${MAKE} -f ${COMPATREL}${COMPATDIR}/Makefile \ + COMPATCC="${CC}" \ + COMPATCFLAGS="${CFLAGS}" \ + COMPATREL="${COMPATREL}" \ + COMPATDIR="${COMPATDIR}" clean) + +__always_make_compatlib: .NOTMAIN + @([ -d ${COMPATDST} ] || mkdir -p ${COMPATDST}) diff --git a/sys/compat/common/compat_tty.c b/sys/compat/common/compat_tty.c new file mode 100644 index 00000000000..485c21379f4 --- /dev/null +++ b/sys/compat/common/compat_tty.c @@ -0,0 +1,451 @@ +/* $NetBSD: compat_tty.c,v 1.1 1995/06/24 20:16:01 christos Exp $ */ + +/*- + * Copyright (c) 1982, 1986, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tty_compat.c 8.1 (Berkeley) 6/10/93 + */ + +/* + * mapping routines for old line discipline (yuck) + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/ioctl.h> +#include <sys/proc.h> +#include <sys/tty.h> +#include <sys/termios.h> +#include <sys/file.h> +#include <sys/conf.h> +#include <sys/kernel.h> +#include <sys/syslog.h> +#include <sys/ioctl_compat.h> + +int ttydebug = 0; + +static struct speedtab compatspeeds[] = { +#define MAX_SPEED 17 + { 115200, 17 }, + { 57600, 16 }, + { 38400, 15 }, + { 19200, 14 }, + { 9600, 13 }, + { 4800, 12 }, + { 2400, 11 }, + { 1800, 10 }, + { 1200, 9 }, + { 600, 8 }, + { 300, 7 }, + { 200, 6 }, + { 150, 5 }, + { 134, 4 }, + { 110, 3 }, + { 75, 2 }, + { 50, 1 }, + { 0, 0 }, + { -1, -1 }, +}; +static int compatspcodes[] = { + 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, + 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200 +}; + +/*ARGSUSED*/ +ttcompat(tp, com, data, flag, p) + register struct tty *tp; + u_long com; + caddr_t data; + int flag; + struct proc *p; +{ + + switch (com) { + case TIOCGETP: { + register struct sgttyb *sg = (struct sgttyb *)data; + register u_char *cc = tp->t_cc; + register speed; + + speed = ttspeedtab(tp->t_ospeed, compatspeeds); + sg->sg_ospeed = (speed == -1) ? MAX_SPEED : speed; + if (tp->t_ispeed == 0) + sg->sg_ispeed = sg->sg_ospeed; + else { + speed = ttspeedtab(tp->t_ispeed, compatspeeds); + sg->sg_ispeed = (speed == -1) ? MAX_SPEED : speed; + } + sg->sg_erase = cc[VERASE]; + sg->sg_kill = cc[VKILL]; + sg->sg_flags = ttcompatgetflags(tp); + break; + } + + case TIOCSETP: + case TIOCSETN: { + register struct sgttyb *sg = (struct sgttyb *)data; + struct termios term; + int speed; + + term = tp->t_termios; + if ((speed = sg->sg_ispeed) > MAX_SPEED || speed < 0) + term.c_ispeed = speed; + else + term.c_ispeed = compatspcodes[speed]; + if ((speed = sg->sg_ospeed) > MAX_SPEED || speed < 0) + term.c_ospeed = speed; + else + term.c_ospeed = compatspcodes[speed]; + term.c_cc[VERASE] = sg->sg_erase; + term.c_cc[VKILL] = sg->sg_kill; + tp->t_flags = (ttcompatgetflags(tp)&0xffff0000) | (sg->sg_flags&0xffff); + ttcompatsetflags(tp, &term); + return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, + (caddr_t)&term, flag, p)); + } + + case TIOCGETC: { + struct tchars *tc = (struct tchars *)data; + register u_char *cc = tp->t_cc; + + tc->t_intrc = cc[VINTR]; + tc->t_quitc = cc[VQUIT]; + tc->t_startc = cc[VSTART]; + tc->t_stopc = cc[VSTOP]; + tc->t_eofc = cc[VEOF]; + tc->t_brkc = cc[VEOL]; + break; + } + case TIOCSETC: { + struct tchars *tc = (struct tchars *)data; + register u_char *cc = tp->t_cc; + + cc[VINTR] = tc->t_intrc; + cc[VQUIT] = tc->t_quitc; + cc[VSTART] = tc->t_startc; + cc[VSTOP] = tc->t_stopc; + cc[VEOF] = tc->t_eofc; + cc[VEOL] = tc->t_brkc; + if (tc->t_brkc == -1) + cc[VEOL2] = _POSIX_VDISABLE; + break; + } + case TIOCSLTC: { + struct ltchars *ltc = (struct ltchars *)data; + register u_char *cc = tp->t_cc; + + cc[VSUSP] = ltc->t_suspc; + cc[VDSUSP] = ltc->t_dsuspc; + cc[VREPRINT] = ltc->t_rprntc; + cc[VDISCARD] = ltc->t_flushc; + cc[VWERASE] = ltc->t_werasc; + cc[VLNEXT] = ltc->t_lnextc; + break; + } + case TIOCGLTC: { + struct ltchars *ltc = (struct ltchars *)data; + register u_char *cc = tp->t_cc; + + ltc->t_suspc = cc[VSUSP]; + ltc->t_dsuspc = cc[VDSUSP]; + ltc->t_rprntc = cc[VREPRINT]; + ltc->t_flushc = cc[VDISCARD]; + ltc->t_werasc = cc[VWERASE]; + ltc->t_lnextc = cc[VLNEXT]; + break; + } + case TIOCLBIS: + case TIOCLBIC: + case TIOCLSET: { + struct termios term; + long flags; + + term = tp->t_termios; + flags = ttcompatgetflags(tp); + switch (com) { + case TIOCLSET: + tp->t_flags = (flags&0xffff) | (*(int *)data<<16); + break; + case TIOCLBIS: + tp->t_flags = flags | (*(int *)data<<16); + break; + case TIOCLBIC: + tp->t_flags = flags & ~(*(int *)data<<16); + break; + } + ttcompatsetlflags(tp, &term); + return (ttioctl(tp, TIOCSETA, (caddr_t)&term, flag, p)); + } + case TIOCLGET: + *(int *)data = ttcompatgetflags(tp)>>16; + if (ttydebug) + printf("CLGET: returning %x\n", *(int *)data); + break; + + case OTIOCGETD: + *(int *)data = tp->t_line ? tp->t_line : 2; + break; + + case OTIOCSETD: { + int ldisczero = 0; + + return (ttioctl(tp, TIOCSETD, + *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag, + p)); + } + + case OTIOCCONS: + *(int *)data = 1; + return (ttioctl(tp, TIOCCONS, data, flag, p)); + + case TIOCHPCL: + tp->t_cflag |= HUPCL; + break; + + case TIOCGSID: + if (tp->t_session == NULL) + return ENOTTY; + + if (tp->t_session->s_leader == NULL) + return ENOTTY; + + *(int *) data = tp->t_session->s_leader->p_pid; + break; + + default: + return (-1); + } + return (0); +} + +ttcompatgetflags(tp) + register struct tty *tp; +{ + register long iflag = tp->t_iflag; + register long lflag = tp->t_lflag; + register long oflag = tp->t_oflag; + register long cflag = tp->t_cflag; + register flags = 0; + + if (iflag & IXOFF) + flags |= TANDEM; + if (iflag & ICRNL || oflag & ONLCR) + flags |= CRMOD; + if (cflag & PARENB) { + if (iflag & INPCK) { + if (cflag & PARODD) + flags |= ODDP; + else + flags |= EVENP; + } else + flags |= EVENP | ODDP; + } else { + if ((tp->t_flags & LITOUT) && !(oflag & OPOST)) + flags |= LITOUT; + if (tp->t_flags & PASS8) + flags |= PASS8; + } + + if ((lflag & ICANON) == 0) { + /* fudge */ + if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) + flags |= CBREAK; + else + flags |= RAW; + } + if (cflag & MDMBUF) + flags |= MDMBUF; + if ((cflag & HUPCL) == 0) + flags |= NOHANG; + if (oflag & OXTABS) + flags |= XTABS; + if (lflag & ECHOE) + flags |= CRTERA|CRTBS; + if (lflag & ECHOKE) + flags |= CRTKIL|CRTBS; + if (lflag & ECHOPRT) + flags |= PRTERA; + if (lflag & ECHOCTL) + flags |= CTLECH; + if ((iflag & IXANY) == 0) + flags |= DECCTQ; + flags |= lflag & (ECHO|TOSTOP|FLUSHO|PENDIN|NOFLSH); + if (ttydebug) + printf("getflags: %x\n", flags); + return (flags); +} + +ttcompatsetflags(tp, t) + register struct tty *tp; + register struct termios *t; +{ + register flags = tp->t_flags; + register long iflag = t->c_iflag; + register long oflag = t->c_oflag; + register long lflag = t->c_lflag; + register long cflag = t->c_cflag; + + if (flags & TANDEM) + iflag |= IXOFF; + else + iflag &= ~IXOFF; + if (flags & ECHO) + lflag |= ECHO; + else + lflag &= ~ECHO; + if (flags & CRMOD) { + iflag |= ICRNL; + oflag |= ONLCR; + } else { + iflag &= ~ICRNL; + oflag &= ~ONLCR; + } + if (flags & XTABS) + oflag |= OXTABS; + else + oflag &= ~OXTABS; + + + if (flags & RAW) { + iflag &= IXOFF; + lflag &= ~(ISIG|ICANON|IEXTEN); + } else { + iflag |= BRKINT|IXON|IMAXBEL; + lflag |= ISIG|IEXTEN; + if (flags & CBREAK) + lflag &= ~ICANON; + else + lflag |= ICANON; + } + + switch (flags & ANYP) { + case EVENP: + iflag |= INPCK; + cflag &= ~PARODD; + break; + case ODDP: + iflag |= INPCK; + cflag |= PARODD; + break; + default: + iflag &= ~INPCK; + break; + } + + if (flags & (RAW|LITOUT|PASS8)) { + cflag &= ~(CSIZE|PARENB); + cflag |= CS8; + if ((flags & (RAW|PASS8)) == 0) + iflag |= ISTRIP; + else + iflag &= ~ISTRIP; + if ((flags & (RAW|LITOUT)) == 0) + oflag |= OPOST; + else + oflag &= ~OPOST; + } else { + cflag &= ~CSIZE; + cflag |= CS7|PARENB; + iflag |= ISTRIP; + oflag |= OPOST; + } + + t->c_iflag = iflag; + t->c_oflag = oflag; + t->c_lflag = lflag; + t->c_cflag = cflag; +} + +ttcompatsetlflags(tp, t) + register struct tty *tp; + register struct termios *t; +{ + register flags = tp->t_flags; + register long iflag = t->c_iflag; + register long oflag = t->c_oflag; + register long lflag = t->c_lflag; + register long cflag = t->c_cflag; + + /* Nothing we can do with CRTBS. */ + if (flags & PRTERA) + lflag |= ECHOPRT; + else + lflag &= ~ECHOPRT; + if (flags & CRTERA) + lflag |= ECHOE; + else + lflag &= ~ECHOE; + /* Nothing we can do with TILDE. */ + if (flags & MDMBUF) + cflag |= MDMBUF; + else + cflag &= ~MDMBUF; + if (flags & NOHANG) + cflag &= ~HUPCL; + else + cflag |= HUPCL; + if (flags & CRTKIL) + lflag |= ECHOKE; + else + lflag &= ~ECHOKE; + if (flags & CTLECH) + lflag |= ECHOCTL; + else + lflag &= ~ECHOCTL; + if ((flags & DECCTQ) == 0) + iflag |= IXANY; + else + iflag &= ~IXANY; + lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH); + lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH); + + if (flags & (RAW|LITOUT|PASS8)) { + cflag &= ~(CSIZE|PARENB); + cflag |= CS8; + if ((flags & (RAW|PASS8)) == 0) + iflag |= ISTRIP; + else + iflag &= ~ISTRIP; + if ((flags & (RAW|LITOUT)) == 0) + oflag |= OPOST; + else + oflag &= ~OPOST; + } else { + cflag &= ~CSIZE; + cflag |= CS7|PARENB; + iflag |= ISTRIP; + oflag |= OPOST; + } + + t->c_iflag = iflag; + t->c_oflag = oflag; + t->c_lflag = lflag; + t->c_cflag = cflag; +} diff --git a/sys/compat/common/compat_util.c b/sys/compat/common/compat_util.c new file mode 100644 index 00000000000..0f42413ef00 --- /dev/null +++ b/sys/compat/common/compat_util.c @@ -0,0 +1,177 @@ +/* $NetBSD: compat_util.c,v 1.2 1995/06/26 19:27:17 christos Exp $ */ + +/* + * Copyright (c) 1994 Christos Zoulas + * Copyright (c) 1995 Frank van der Linden + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/namei.h> +#include <sys/proc.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/filedesc.h> +#include <sys/ioctl.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/vnode.h> + +#include <compat/common/compat_util.h> + +/* + * Search an alternate path before passing pathname arguments on + * to system calls. Useful for keeping a separate 'emulation tree'. + * + * If cflag is set, we check if an attempt can be made to create + * the named file, i.e. we check if the directory it should + * be in exists. + */ +int +emul_find(p, sgp, prefix, path, pbuf, cflag) + struct proc *p; + caddr_t *sgp; /* Pointer to stackgap memory */ + const char *prefix; + char *path; + char **pbuf; + int cflag; +{ + struct nameidata nd; + struct nameidata ndroot; + struct vattr vat; + struct vattr vatroot; + int error; + char *ptr, *buf, *cp; + const char *pr; + size_t sz, len; + + buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + *pbuf = path; + + for (ptr = buf, pr = prefix; (*ptr = *pr) != '\0'; ptr++, pr++) + continue; + + sz = MAXPATHLEN - (ptr - buf); + + /* + * If sgp is not given then the path is already in kernel space + */ + if (sgp == NULL) + error = copystr(path, ptr, sz, &len); + else + error = copyinstr(path, ptr, sz, &len); + + if (error) { + free(buf, M_TEMP); + return error; + } + + if (*ptr != '/') { + free(buf, M_TEMP); + return EINVAL; + } + + /* + * We know that there is a / somewhere in this pathname. + * Search backwards for it, to find the file's parent dir + * to see if it exists in the alternate tree. If it does, + * and we want to create a file (cflag is set). We don't + * need to worry about the root comparison in this case. + */ + + if (cflag) { + for (cp = &ptr[len] - 1; *cp != '/'; cp--); + *cp = '\0'; + + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); + + if ((error = namei(&nd)) != 0) { + free(buf, M_TEMP); + return error; + } + + *cp = '/'; + } + else { + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p); + + if ((error = namei(&nd)) != 0) { + free(buf, M_TEMP); + return error; + } + + /* + * We now compare the vnode of the emulation root to the one + * vnode asked. If they resolve to be the same, then we + * ignore the match so that the real root gets used. + * This avoids the problem of traversing "../.." to find the + * root directory and never finding it, because "/" resolves + * to the emulation root directory. This is expensive :-( + */ + /* XXX: prototype should have const here for NDINIT */ + NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, + (char *) prefix, p); + + if ((error = namei(&ndroot)) != 0) { + /* Cannot happen! */ + free(buf, M_TEMP); + vrele(nd.ni_vp); + return error; + } + + if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) { + goto done; + } + + if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p)) + != 0) { + goto done; + } + + if (vat.va_fsid == vatroot.va_fsid && + vat.va_fileid == vatroot.va_fileid) { + error = ENOENT; + goto done; + } + + } + if (sgp == NULL) + *pbuf = buf; + else { + sz = &ptr[len] - buf; + *pbuf = stackgap_alloc(sgp, sz + 1); + error = copyout(buf, *pbuf, sz); + free(buf, M_TEMP); + } + + +done: + vrele(nd.ni_vp); + if (!cflag) + vrele(ndroot.ni_vp); + return error; +} diff --git a/sys/compat/common/compat_util.h b/sys/compat/common/compat_util.h new file mode 100644 index 00000000000..b1d1e96515c --- /dev/null +++ b/sys/compat/common/compat_util.h @@ -0,0 +1,71 @@ +/* $NetBSD: compat_util.h,v 1.1 1995/06/24 20:16:05 christos Exp $ */ + +/* + * Copyright (c) 1994 Christos Zoulas + * Copyright (c) 1995 Frank van der Linden + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _COMPAT_UTIL_H_ +#define _COMPAT_UTIL_H_ + +#include <machine/vmparam.h> +#include <sys/exec.h> +#include <sys/cdefs.h> +#include <sys/proc.h> + +static __inline caddr_t stackgap_init __P((struct emul *)); +static __inline void *stackgap_alloc __P((caddr_t *, size_t)); + +static __inline caddr_t +stackgap_init(e) + struct emul *e; +{ +#define szsigcode ((caddr_t)(e->e_esigcode - e->e_sigcode)) + return STACKGAPBASE; +} + + +static __inline void * +stackgap_alloc(sgp, sz) + caddr_t *sgp; + size_t sz; +{ + void *p = (void *) *sgp; + *sgp += ALIGN(sz); + return p; +} + +int emul_find __P((struct proc *, caddr_t *, const char *, char *, + char **, int)); + +#define CHECK_ALT_EXIST(p, sgp, root, path) \ + emul_find(p, sgp, root, path, &(path), 0) + +#define CHECK_ALT_CREAT(p, sgp, root, path) \ + emul_find(p, sgp, root, path, &(path), 1) + +#endif /* !_COMPAT_UTIL_H_ */ diff --git a/sys/compat/common/kern_exit_43.c b/sys/compat/common/kern_exit_43.c new file mode 100644 index 00000000000..cbfd9a84141 --- /dev/null +++ b/sys/compat/common/kern_exit_43.c @@ -0,0 +1,113 @@ +/* $NetBSD: kern_exit_43.c,v 1.3 1995/10/07 06:26:20 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/map.h> +#include <sys/ioctl.h> +#include <sys/proc.h> +#include <sys/tty.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/buf.h> +#include <sys/wait.h> +#include <sys/file.h> +#include <sys/vnode.h> +#include <sys/syslog.h> +#include <sys/malloc.h> +#include <sys/resourcevar.h> +#include <sys/ptrace.h> +#include <sys/acct.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#include <machine/cpu.h> +#include <machine/reg.h> +#include <machine/psl.h> +#include <compat/common/compat_util.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#ifdef m68k +#include <machine/frame.h> +#define GETPS(rp) ((struct frame *)(rp))->f_sr +#else +#define GETPS(rp) (rp)[PS] +#endif + +int +compat_43_sys_wait(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + caddr_t sg = stackgap_init(p->p_emul); + int error; + + struct sys_wait4_args /* { + syscallarg(int) pid; + syscallarg(int *) status; + syscallarg(int) options; + syscallarg(struct rusage *) rusage; + } */ a; + +#ifdef PSL_ALLCC + if ((GETPS(p->p_md.md_regs) & PSL_ALLCC) != PSL_ALLCC) { + SCARG(&a, options) = 0; + SCARG(&a, rusage) = NULL; + } else { + SCARG(&a, options) = p->p_md.md_regs[R0]; + SCARG(&a, rusage) = (struct rusage *)p->p_md.md_regs[R1]; + } +#else + SCARG(&a, options) = 0; + SCARG(&a, rusage) = NULL; +#endif + SCARG(&a, pid) = WAIT_ANY; + SCARG(&a, status) = stackgap_alloc(&sg, sizeof(SCARG(&a, status))); + if ((error = sys_wait4(p, &a, retval)) != 0) + return error; + return copyin(SCARG(&a, status), &retval[1], sizeof(retval[1])); +} diff --git a/sys/compat/common/kern_info_09.c b/sys/compat/common/kern_info_09.c new file mode 100644 index 00000000000..0d04cae2475 --- /dev/null +++ b/sys/compat/common/kern_info_09.c @@ -0,0 +1,130 @@ +/* $NetBSD: kern_info_09.c,v 1.3 1995/10/07 06:26:23 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_xxx.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/syslog.h> +#include <sys/unistd.h> +#include <vm/vm.h> +#include <sys/sysctl.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +/* ARGSUSED */ +int +compat_09_sys_getdomainname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_09_sys_getdomainname_args /* { + syscallarg(char *) domainname; + syscallarg(int) len; + } */ *uap = v; + int name; + + name = KERN_DOMAINNAME; + return (kern_sysctl(&name, 1, SCARG(uap, domainname), + &SCARG(uap, len), 0, 0)); +} + + +/* ARGSUSED */ +int +compat_09_sys_setdomainname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_09_sys_setdomainname_args /* { + syscallarg(char *) domainname; + syscallarg(int) len; + } */ *uap = v; + int name; + int error; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + name = KERN_DOMAINNAME; + return (kern_sysctl(&name, 1, 0, 0, SCARG(uap, domainname), + SCARG(uap, len))); +} + +struct outsname { + char sysname[32]; + char nodename[32]; + char release[32]; + char version[32]; + char machine[32]; +}; + +/* ARGSUSED */ +int +compat_09_sys_uname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_09_sys_uname_args /* { + syscallarg(struct outsname *) name; + } */ *uap = v; + struct outsname outsname; + char *cp, *dp, *ep; + extern char ostype[], osrelease[]; + + strncpy(outsname.sysname, ostype, sizeof(outsname.sysname)); + strncpy(outsname.nodename, hostname, sizeof(outsname.nodename)); + strncpy(outsname.release, osrelease, sizeof(outsname.release)); + dp = outsname.version; + ep = &outsname.version[sizeof(outsname.version) - 1]; + for (cp = version; *cp && *cp != '('; cp++) + ; + for (cp++; *cp && *cp != ')' && dp < ep; cp++) + *dp++ = *cp; + for (; *cp && *cp != '#'; cp++) + ; + for (; *cp && *cp != ':' && dp < ep; cp++) + *dp++ = *cp; + *dp = '\0'; + strncpy(outsname.machine, MACHINE, sizeof(outsname.machine)); + return (copyout((caddr_t)&outsname, (caddr_t)SCARG(uap, name), + sizeof(struct outsname))); +} diff --git a/sys/compat/common/kern_info_43.c b/sys/compat/common/kern_info_43.c new file mode 100644 index 00000000000..c9281661a45 --- /dev/null +++ b/sys/compat/common/kern_info_43.c @@ -0,0 +1,228 @@ +/* $NetBSD: kern_info_43.c,v 1.3 1995/10/07 06:26:24 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_xxx.c 8.1 (Berkeley) 6/10/93 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#include <sys/vnode.h> +#include <sys/proc.h> +#include <sys/file.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/unistd.h> +#include <sys/resourcevar.h> +#include <vm/vm.h> +#include <sys/sysctl.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +int +compat_43_sys_getdtablesize(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + + *retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles); + return (0); +} + + +/* ARGSUSED */ +int +compat_43_sys_gethostid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + + *(int32_t *)retval = hostid; + return (0); +} + + +/*ARGSUSED*/ +int +compat_43_sys_gethostname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_gethostname_args /* { + syscallarg(char *) hostname; + syscallarg(u_int) len; + } */ *uap = v; + int name; + + name = KERN_HOSTNAME; + return (kern_sysctl(&name, 1, SCARG(uap, hostname), &SCARG(uap, len), + 0, 0)); +} + +#define KINFO_PROC (0<<8) +#define KINFO_RT (1<<8) +#define KINFO_VNODE (2<<8) +#define KINFO_FILE (3<<8) +#define KINFO_METER (4<<8) +#define KINFO_LOADAVG (5<<8) +#define KINFO_CLOCKRATE (6<<8) + +int +compat_43_sys_getkerninfo(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_getkerninfo_args /* { + syscallarg(int) op; + syscallarg(char *) where; + syscallarg(int *) size; + syscallarg(int) arg; + } */ *uap = v; + int error, name[5]; + size_t size; + + if (SCARG(uap, size) && (error = copyin((caddr_t)SCARG(uap, size), + (caddr_t)&size, sizeof(size)))) + return (error); + + switch (SCARG(uap, op) & 0xff00) { + + case KINFO_RT: + name[0] = PF_ROUTE; + name[1] = 0; + name[2] = (SCARG(uap, op) & 0xff0000) >> 16; + name[3] = SCARG(uap, op) & 0xff; + name[4] = SCARG(uap, arg); + error = + net_sysctl(name, 5, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_VNODE: + name[0] = KERN_VNODE; + error = + kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_PROC: + name[0] = KERN_PROC; + name[1] = SCARG(uap, op) & 0xff; + name[2] = SCARG(uap, arg); + error = + kern_sysctl(name, 3, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_FILE: + name[0] = KERN_FILE; + error = + kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_METER: + name[0] = VM_METER; + error = + vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_LOADAVG: + name[0] = VM_LOADAVG; + error = + vm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); + break; + + case KINFO_CLOCKRATE: + name[0] = KERN_CLOCKRATE; + error = + kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p); + break; + + default: + return (EOPNOTSUPP); + } + if (error) + return (error); + *retval = size; + if (SCARG(uap, size)) + error = copyout((caddr_t)&size, (caddr_t)SCARG(uap, size), + sizeof(size)); + return (error); +} + + +/* ARGSUSED */ +int +compat_43_sys_sethostid(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_sethostid_args /* { + syscallarg(int32_t) hostid; + } */ *uap = v; + int error; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + hostid = SCARG(uap, hostid); + return (0); +} + + +/* ARGSUSED */ +int +compat_43_sys_sethostname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_sethostname_args *uap = v; + int name; + int error; + + if (error = suser(p->p_ucred, &p->p_acflag)) + return (error); + name = KERN_HOSTNAME; + return (kern_sysctl(&name, 1, 0, 0, SCARG(uap, hostname), + SCARG(uap, len))); +} diff --git a/sys/compat/common/kern_ipc_10.c b/sys/compat/common/kern_ipc_10.c new file mode 100644 index 00000000000..f0ad88f2c3c --- /dev/null +++ b/sys/compat/common/kern_ipc_10.c @@ -0,0 +1,243 @@ +/* $NetBSD: kern_ipc_10.c,v 1.4 1995/10/07 06:26:25 mycroft Exp $ */ + +/* + * Copyright (c) 1994 Adam Glass and Charles Hannum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Glass and Charles + * Hannum. + * 4. The names of the authors may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/sem.h> +#include <sys/malloc.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#include <vm/vm.h> +#include <vm/vm_map.h> +#include <vm/vm_map.h> +#include <vm/vm_kern.h> + +#ifdef SYSVSEM +int +compat_10_sys_semsys(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_10_sys_semsys_args /* { + syscallarg(int) which; + syscallarg(int) a2; + syscallarg(int) a3; + syscallarg(int) a4; + syscallarg(int) a5; + } */ *uap = v; + struct sys___semctl_args /* { + syscallarg(int) semid; + syscallarg(int) semnum; + syscallarg(int) cmd; + syscallarg(union semun *) arg; + } */ __semctl_args; + struct sys_semget_args /* { + syscallarg(key_t) key; + syscallarg(int) nsems; + syscallarg(int) semflg; + } */ semget_args; + struct sys_semop_args /* { + syscallarg(int) semid; + syscallarg(struct sembuf *) sops; + syscallarg(u_int) nsops; + } */ semop_args; + struct sys_semconfig_args /* { + syscallarg(int) flag; + } */ semconfig_args; + + switch (SCARG(uap, which)) { + case 0: /* __semctl() */ + SCARG(&__semctl_args, semid) = SCARG(uap, a2); + SCARG(&__semctl_args, semnum) = SCARG(uap, a3); + SCARG(&__semctl_args, cmd) = SCARG(uap, a4); + SCARG(&__semctl_args, arg) = (union semun *)SCARG(uap, a5); + return (sys___semctl(p, &__semctl_args, retval)); + + case 1: /* semget() */ + SCARG(&semget_args, key) = SCARG(uap, a2); + SCARG(&semget_args, nsems) = SCARG(uap, a3); + SCARG(&semget_args, semflg) = SCARG(uap, a4); + return (sys_semget(p, &semget_args, retval)); + + case 2: /* semop() */ + SCARG(&semop_args, semid) = SCARG(uap, a2); + SCARG(&semop_args, sops) = (struct sembuf *)SCARG(uap, a3); + SCARG(&semop_args, nsops) = SCARG(uap, a4); + return (sys_semop(p, &semop_args, retval)); + + case 3: /* semconfig() */ + SCARG(&semconfig_args, flag) = SCARG(uap, a2); + return (sys_semconfig(p, &semconfig_args, retval)); + + default: + return (EINVAL); + } +} +#endif + +#ifdef SYSVSHM +int +compat_10_sys_shmsys(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_10_sys_shmsys_args /* { + syscallarg(int) which; + syscallarg(int) a2; + syscallarg(int) a3; + syscallarg(int) a4; + } */ *uap = v; + struct sys_shmat_args /* { + syscallarg(int) shmid; + syscallarg(void *) shmaddr; + syscallarg(int) shmflg; + } */ shmat_args; + struct sys_shmctl_args /* { + syscallarg(int) shmid; + syscallarg(int) cmd; + syscallarg(struct shmid_ds *) buf; + } */ shmctl_args; + struct sys_shmdt_args /* { + syscallarg(void *) shmaddr; + } */ shmdt_args; + struct sys_shmget_args /* { + syscallarg(key_t) key; + syscallarg(int) size; + syscallarg(int) shmflg; + } */ shmget_args; + + switch (SCARG(uap, which)) { + case 0: /* shmat() */ + SCARG(&shmat_args, shmid) = SCARG(uap, a2); + SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a3); + SCARG(&shmat_args, shmflg) = SCARG(uap, a4); + return (sys_shmat(p, &shmat_args, retval)); + + case 1: /* shmctl() */ + SCARG(&shmctl_args, shmid) = SCARG(uap, a2); + SCARG(&shmctl_args, cmd) = SCARG(uap, a3); + SCARG(&shmctl_args, buf) = (struct shmid_ds *)SCARG(uap, a4); + return (sys_shmctl(p, &shmctl_args, retval)); + + case 2: /* shmdt() */ + SCARG(&shmat_args, shmaddr) = (void *)SCARG(uap, a2); + return (sys_shmdt(p, &shmdt_args, retval)); + + case 3: /* shmget() */ + SCARG(&shmget_args, key) = SCARG(uap, a2); + SCARG(&shmget_args, size) = SCARG(uap, a3); + SCARG(&shmget_args, shmflg) = SCARG(uap, a4); + return (sys_shmget(p, &shmget_args, retval)); + + default: + return (EINVAL); + } +} +#endif + +#ifdef SYSVMSG +int +compat_10_sys_msgsys(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_10_sys_msgsys_args /* { + syscallarg(int) which; + syscallarg(int) a2; + syscallarg(int) a3; + syscallarg(int) a4; + syscallarg(int) a5; + syscallarg(int) a6; + } */ *uap = v; + struct sys_msgctl_args /* { + syscallarg(int) msqid; + syscallarg(int) cmd; + syscallarg(struct msqid_ds *) buf; + } */ msgctl_args; + struct sys_msgget_args /* { + syscallarg(key_t) key; + syscallarg(int) msgflg; + } */ msgget_args; + struct sys_msgsnd_args /* { + syscallarg(int) msqid; + syscallarg(void *) msgp; + syscallarg(size_t) msgsz; + syscallarg(int) msgflg; + } */ msgsnd_args; + struct sys_msgrcv_args /* { + syscallarg(int) msqid; + syscallarg(void *) msgp; + syscallarg(size_t) msgsz; + syscallarg(long) msgtyp; + syscallarg(int) msgflg; + } */ msgrcv_args; + + switch (SCARG(uap, which)) { + case 0: /* msgctl()*/ + SCARG(&msgctl_args, msqid) = SCARG(uap, a2); + SCARG(&msgctl_args, cmd) = SCARG(uap, a3); + SCARG(&msgctl_args, buf) = + (struct msqid_ds *)SCARG(uap, a4); + return (sys_msgctl(p, &msgctl_args, retval)); + + case 1: /* msgget() */ + SCARG(&msgget_args, key) = SCARG(uap, a2); + SCARG(&msgget_args, msgflg) = SCARG(uap, a3); + return (sys_msgget(p, &msgget_args, retval)); + + case 2: /* msgsnd() */ + SCARG(&msgsnd_args, msqid) = SCARG(uap, a2); + SCARG(&msgsnd_args, msgp) = (void *)SCARG(uap, a3); + SCARG(&msgsnd_args, msgsz) = SCARG(uap, a4); + SCARG(&msgsnd_args, msgflg) = SCARG(uap, a5); + return (sys_msgsnd(p, &msgsnd_args, retval)); + + case 3: /* msgrcv() */ + SCARG(&msgrcv_args, msqid) = SCARG(uap, a2); + SCARG(&msgrcv_args, msgp) = (void *)SCARG(uap, a3); + SCARG(&msgrcv_args, msgsz) = SCARG(uap, a4); + SCARG(&msgrcv_args, msgtyp) = SCARG(uap, a5); + SCARG(&msgrcv_args, msgflg) = SCARG(uap, a6); + return (sys_msgrcv(p, &msgrcv_args, retval)); + + default: + return (EINVAL); + } +} +#endif diff --git a/sys/compat/common/kern_prot_43.c b/sys/compat/common/kern_prot_43.c new file mode 100644 index 00000000000..2bb328b9d7f --- /dev/null +++ b/sys/compat/common/kern_prot_43.c @@ -0,0 +1,125 @@ +/* $NetBSD: kern_prot_43.c,v 1.3 1995/10/07 06:26:27 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kern_prot.c 8.6 (Berkeley) 1/21/94 + */ + +#include <sys/param.h> +#include <sys/acct.h> +#include <sys/systm.h> +#include <sys/ucred.h> +#include <sys/proc.h> +#include <sys/timeb.h> +#include <sys/times.h> +#include <sys/malloc.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +/* ARGSUSED */ +int +compat_43_sys_setregid(p, v, retval) + register struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_setregid_args /* { + syscallarg(int) rgid; + syscallarg(int) egid; + } */ *uap = v; + struct sys_setegid_args segidargs; + struct sys_setgid_args sgidargs; + + /* + * There are five cases, described above in osetreuid() + */ + if (SCARG(uap, rgid) == (gid_t)-1) { + if (SCARG(uap, egid) == (gid_t)-1) + return (0); /* -1, -1 */ + SCARG(&segidargs, egid) = SCARG(uap, egid); /* -1, N */ + return (sys_setegid(p, &segidargs, retval)); + } + if (SCARG(uap, egid) == (gid_t)-1) { + SCARG(&segidargs, egid) = SCARG(uap, rgid); /* N, -1 */ + return (sys_setegid(p, &segidargs, retval)); + } + SCARG(&sgidargs, gid) = SCARG(uap, rgid); /* N, N and N, M */ + return (sys_setgid(p, &sgidargs, retval)); +} + +/* ARGSUSED */ +int +compat_43_sys_setreuid(p, v, retval) + register struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_setreuid_args /* { + syscallarg(int) ruid; + syscallarg(int) euid; + } */ *uap = v; + struct sys_seteuid_args seuidargs; + struct sys_setuid_args suidargs; + + /* + * There are five cases, and we attempt to emulate them in + * the following fashion: + * -1, -1: return 0. This is correct emulation. + * -1, N: call seteuid(N). This is correct emulation. + * N, -1: if we called setuid(N), our euid would be changed + * to N as well. the theory is that we don't want to + * revoke root access yet, so we call seteuid(N) + * instead. This is incorrect emulation, but often + * suffices enough for binary compatibility. + * N, N: call setuid(N). This is correct emulation. + * N, M: call setuid(N). This is close to correct emulation. + */ + if (SCARG(uap, ruid) == (uid_t)-1) { + if (SCARG(uap, euid) == (uid_t)-1) + return (0); /* -1, -1 */ + SCARG(&seuidargs, euid) = SCARG(uap, euid); /* -1, N */ + return (sys_seteuid(p, &seuidargs, retval)); + } + if (SCARG(uap, euid) == (uid_t)-1) { + SCARG(&seuidargs, euid) = SCARG(uap, ruid); /* N, -1 */ + return (sys_seteuid(p, &seuidargs, retval)); + } + SCARG(&suidargs, uid) = SCARG(uap, ruid); /* N, N and N, M */ + return (sys_setuid(p, &suidargs, retval)); +} diff --git a/sys/compat/common/kern_resource_43.c b/sys/compat/common/kern_resource_43.c new file mode 100644 index 00000000000..1fc2bdbb19f --- /dev/null +++ b/sys/compat/common/kern_resource_43.c @@ -0,0 +1,102 @@ +/* $NetBSD: kern_resource_43.c,v 1.3 1995/10/07 06:26:28 mycroft Exp $ */ + +/*- + * Copyright (c) 1982, 1986, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kern_resource.c 8.5 (Berkeley) 1/21/94 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/file.h> +#include <sys/resourcevar.h> +#include <sys/malloc.h> +#include <sys/proc.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#include <vm/vm.h> + +/* ARGSUSED */ +int +compat_43_sys_getrlimit(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_getrlimit_args /* { + syscallarg(u_int) which; + syscallarg(struct ogetrlimit *) rlp; + } */ *uap = v; + struct orlimit olim; + + if (SCARG(uap, which) >= RLIM_NLIMITS) + return (EINVAL); + olim.rlim_cur = p->p_rlimit[SCARG(uap, which)].rlim_cur; + if (olim.rlim_cur == -1) + olim.rlim_cur = 0x7fffffff; + olim.rlim_max = p->p_rlimit[SCARG(uap, which)].rlim_max; + if (olim.rlim_max == -1) + olim.rlim_max = 0x7fffffff; + return (copyout((caddr_t)&olim, (caddr_t)SCARG(uap, rlp), + sizeof(olim))); +} + +/* ARGSUSED */ +int +compat_43_sys_setrlimit(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_setrlimit_args /* { + syscallarg(u_int) which; + syscallarg(struct ogetrlimit *) rlp; + } */ *uap = v; + struct orlimit olim; + struct rlimit lim; + int error; + + if (error = copyin((caddr_t)SCARG(uap, rlp), (caddr_t)&olim, + sizeof (struct orlimit))) + return (error); + lim.rlim_cur = olim.rlim_cur; + lim.rlim_max = olim.rlim_max; + return (dosetrlimit(p, SCARG(uap, which), &lim)); +} diff --git a/sys/compat/common/kern_sig_43.c b/sys/compat/common/kern_sig_43.c new file mode 100644 index 00000000000..f11be5dcd89 --- /dev/null +++ b/sys/compat/common/kern_sig_43.c @@ -0,0 +1,213 @@ +/* $NetBSD: kern_sig_43.c,v 1.5 1995/10/07 06:26:29 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 + */ + +#include <sys/param.h> +#include <sys/signalvar.h> +#include <sys/resourcevar.h> +#include <sys/namei.h> +#include <sys/vnode.h> +#include <sys/proc.h> +#include <sys/systm.h> +#include <sys/timeb.h> +#include <sys/times.h> +#include <sys/buf.h> +#include <sys/acct.h> +#include <sys/file.h> +#include <sys/kernel.h> +#include <sys/wait.h> +#include <sys/ktrace.h> +#include <sys/syslog.h> +#include <sys/stat.h> +#include <sys/core.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#include <machine/cpu.h> + +#include <vm/vm.h> +#include <sys/user.h> /* for coredump */ + +int +compat_43_sys_sigblock(p, v, retval) + register struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_sigblock_args /* { + syscallarg(int) mask; + } */ *uap = v; + + (void) splhigh(); + *retval = p->p_sigmask; + p->p_sigmask |= SCARG(uap, mask) &~ sigcantmask; + (void) spl0(); + return (0); +} + + +int +compat_43_sys_sigsetmask(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct compat_43_sys_sigsetmask_args /* { + syscallarg(int) mask; + } */ *uap = v; + + (void) splhigh(); + *retval = p->p_sigmask; + p->p_sigmask = SCARG(uap, mask) &~ sigcantmask; + (void) spl0(); + return (0); +} + + +/* ARGSUSED */ +int +compat_43_sys_sigstack(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_sigstack_args /* { + syscallarg(struct sigstack *) nss; + syscallarg(struct sigstack *) oss; + } */ *uap = v; + struct sigstack ss; + struct sigacts *psp; + int error = 0; + + psp = p->p_sigacts; + ss.ss_sp = psp->ps_sigstk.ss_base; + ss.ss_onstack = psp->ps_sigstk.ss_flags & SS_ONSTACK; + if (SCARG(uap, oss) && (error = copyout((caddr_t)&ss, + (caddr_t)SCARG(uap, oss), sizeof (struct sigstack)))) + return (error); + if (SCARG(uap, nss) == 0) + return (0); + if (error = copyin((caddr_t)SCARG(uap, nss), (caddr_t)&ss, + sizeof (ss))) + return (error); + psp->ps_flags |= SAS_ALTSTACK; + psp->ps_sigstk.ss_base = ss.ss_sp; + psp->ps_sigstk.ss_size = 0; + psp->ps_sigstk.ss_flags |= ss.ss_onstack & SS_ONSTACK; + return (0); +} + +/* + * Generalized interface signal handler, 4.3-compatible. + */ +/* ARGSUSED */ +int +compat_43_sys_sigvec(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_sigvec_args /* { + syscallarg(int) signum; + syscallarg(struct sigvec *) nsv; + syscallarg(struct sigvec *) osv; + } */ *uap = v; + struct sigvec vec; + register struct sigacts *ps = p->p_sigacts; + register struct sigvec *sv; + register int signum; + int bit, error; + + signum = SCARG(uap, signum); + if (signum <= 0 || signum >= NSIG || + signum == SIGKILL || signum == SIGSTOP) + return (EINVAL); + sv = &vec; + if (SCARG(uap, osv)) { + *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum]; + sv->sv_mask = ps->ps_catchmask[signum]; + bit = sigmask(signum); + sv->sv_flags = 0; + if ((ps->ps_sigonstack & bit) != 0) + sv->sv_flags |= SV_ONSTACK; + if ((ps->ps_sigintr & bit) != 0) + sv->sv_flags |= SV_INTERRUPT; + if ((ps->ps_sigreset & bit) != 0) + sv->sv_flags |= SV_RESETHAND; + if (p->p_flag & P_NOCLDSTOP) + sv->sv_flags |= SA_NOCLDSTOP; + sv->sv_mask &= ~bit; + if (error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv), + sizeof (vec))) + return (error); + } + if (SCARG(uap, nsv)) { + if (error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv, + sizeof (vec))) + return (error); + sv->sv_flags ^= SA_RESTART; /* opposite of SV_INTERRUPT */ + setsigvec(p, signum, (struct sigaction *)sv); + } + return (0); +} + + +/* ARGSUSED */ +int +compat_43_sys_killpg(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_killpg_args /* { + syscallarg(int) pgid; + syscallarg(int) signum; + } */ *uap = v; + +#ifdef COMPAT_09 + SCARG(uap, pgid) = (short) SCARG(uap, pgid); +#endif + + if ((u_int)SCARG(uap, signum) >= NSIG) + return (EINVAL); + return (killpg1(p, SCARG(uap, signum), SCARG(uap, pgid), 0)); +} diff --git a/sys/compat/common/uipc_syscalls_43.c b/sys/compat/common/uipc_syscalls_43.c new file mode 100644 index 00000000000..941253de46d --- /dev/null +++ b/sys/compat/common/uipc_syscalls_43.c @@ -0,0 +1,306 @@ +/* $NetBSD: uipc_syscalls_43.c,v 1.3 1995/10/07 06:26:30 mycroft Exp $ */ + +/* + * Copyright (c) 1982, 1986, 1989, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/file.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/unistd.h> +#include <sys/resourcevar.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +#define MSG_COMPAT 0x8000 /* XXX */ + +int +compat_43_sys_accept(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_accept_args /* { + syscallarg(int) s; + syscallarg(caddr_t) name; + syscallarg(int *) anamelen; + } */ *uap = v; + int error; + + if ((error = sys_accept(p, uap, retval)) != 0) + return error; + + if (SCARG(uap, name)) { + struct sockaddr sa; + + if ((error = copyin(SCARG(uap, name), &sa, sizeof(sa))) != 0) + return error; + + ((struct osockaddr*) &sa)->sa_family = sa.sa_family; + + if ((error = copyout(&sa, SCARG(uap, name), sizeof(sa))) != 0) + return error; + } + return 0; +} + + +int +compat_43_sys_getpeername(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_getpeername_args /* { + syscallarg(int) fdes; + syscallarg(caddr_t) asa; + syscallarg(int *) alen; + } */ *uap = v; + struct sockaddr sa; + + int error; + + if ((error = sys_getpeername(p, uap, retval)) != 0) + return error; + + if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0) + return error; + + ((struct osockaddr*) &sa)->sa_family = sa.sa_family; + + if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0) + return error; + + return 0; +} + + +int +compat_43_sys_getsockname(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_getsockname_args /* { + syscallarg(int) fdes; + syscallarg(caddr_t) asa; + syscallarg(int *) alen; + } */ *uap = v; + struct sockaddr sa; + int error; + + if ((error = sys_getsockname(p, uap, retval)) != 0) + return error; + + if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0) + return error; + + ((struct osockaddr*) &sa)->sa_family = sa.sa_family; + + if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0) + return error; + + return 0; +} + + +int +compat_43_sys_recv(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_recv_args /* { + syscallarg(int) s; + syscallarg(caddr_t) buf; + syscallarg(int) len; + syscallarg(int) flags; + } */ *uap = v; + struct msghdr msg; + struct iovec aiov; + + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &aiov; + msg.msg_iovlen = 1; + aiov.iov_base = SCARG(uap, buf); + aiov.iov_len = SCARG(uap, len); + msg.msg_control = 0; + msg.msg_flags = SCARG(uap, flags); + return (recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval)); +} + + +int +compat_43_sys_recvfrom(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct sys_recvfrom_args /* { + syscallarg(int) s; + syscallarg(caddr_t) buf; + syscallarg(size_t) len; + syscallarg(int) flags; + syscallarg(caddr_t) from; + syscallarg(int *) fromlenaddr; + } */ *uap = v; + + SCARG(uap, flags) |= MSG_COMPAT; + return (sys_recvfrom(p, uap, retval)); +} + + +/* + * Old recvmsg. This code takes advantage of the fact that the old msghdr + * overlays the new one, missing only the flags, and with the (old) access + * rights where the control fields are now. + */ +int +compat_43_sys_recvmsg(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_recvmsg_args /* { + syscallarg(int) s; + syscallarg(struct omsghdr *) msg; + syscallarg(int) flags; + } */ *uap = v; + struct msghdr msg; + struct iovec aiov[UIO_SMALLIOV], *iov; + int error; + + if (error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg, + sizeof (struct omsghdr))) + return (error); + if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) { + if ((u_int)msg.msg_iovlen >= UIO_MAXIOV) + return (EMSGSIZE); + MALLOC(iov, struct iovec *, + sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV, + M_WAITOK); + } else + iov = aiov; + msg.msg_flags = SCARG(uap, flags) | MSG_COMPAT; + if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov, + (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))) + goto done; + msg.msg_iov = iov; + error = recvit(p, SCARG(uap, s), &msg, + (caddr_t)&SCARG(uap, msg)->msg_namelen, retval); + + if (msg.msg_controllen && error == 0) + error = copyout((caddr_t)&msg.msg_controllen, + (caddr_t)&SCARG(uap, msg)->msg_accrightslen, sizeof (int)); +done: + if (iov != aiov) + FREE(iov, M_IOV); + return (error); +} + +int +compat_43_sys_send(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_send_args /* { + syscallarg(int) s; + syscallarg(caddr_t) buf; + syscallarg(int) len; + syscallarg(int) flags; + } */ *uap = v; + struct msghdr msg; + struct iovec aiov; + + msg.msg_name = 0; + msg.msg_namelen = 0; + msg.msg_iov = &aiov; + msg.msg_iovlen = 1; + aiov.iov_base = SCARG(uap, buf); + aiov.iov_len = SCARG(uap, len); + msg.msg_control = 0; + msg.msg_flags = 0; + return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval)); +} + +int +compat_43_sys_sendmsg(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_sendmsg_args /* { + syscallarg(int) s; + syscallarg(caddr_t) msg; + syscallarg(int) flags; + } */ *uap = v; + struct msghdr msg; + struct iovec aiov[UIO_SMALLIOV], *iov; + int error; + + if (error = copyin(SCARG(uap, msg), (caddr_t)&msg, + sizeof (struct omsghdr))) + return (error); + if ((u_int)msg.msg_iovlen >= UIO_SMALLIOV) { + if ((u_int)msg.msg_iovlen >= UIO_MAXIOV) + return (EMSGSIZE); + MALLOC(iov, struct iovec *, + sizeof(struct iovec) * (u_int)msg.msg_iovlen, M_IOV, + M_WAITOK); + } else + iov = aiov; + if (error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov, + (unsigned)(msg.msg_iovlen * sizeof (struct iovec)))) + goto done; + msg.msg_flags = MSG_COMPAT; + msg.msg_iov = iov; + error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval); +done: + if (iov != aiov) + FREE(iov, M_IOV); + return (error); +} diff --git a/sys/compat/common/vfs_syscalls_43.c b/sys/compat/common/vfs_syscalls_43.c new file mode 100644 index 00000000000..b834a9eda84 --- /dev/null +++ b/sys/compat/common/vfs_syscalls_43.c @@ -0,0 +1,510 @@ +/* $NetBSD: vfs_syscalls_43.c,v 1.3 1995/10/07 06:26:31 mycroft Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94 + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#include <sys/proc.h> +#include <sys/file.h> +#include <sys/vnode.h> +#include <sys/namei.h> +#include <sys/dirent.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/unistd.h> +#include <sys/resourcevar.h> + +#include <sys/mount.h> +#include <sys/syscallargs.h> + +/* + * Convert from an old to a new stat structure. + */ +static int +cvtstat(st, ost) + struct stat *st; + struct ostat *ost; +{ + + ost->st_dev = st->st_dev; + ost->st_ino = st->st_ino; + ost->st_mode = st->st_mode; + ost->st_nlink = st->st_nlink; + ost->st_uid = st->st_uid; + ost->st_gid = st->st_gid; + ost->st_rdev = st->st_rdev; + if (st->st_size < (quad_t)1 << 32) + ost->st_size = st->st_size; + else + ost->st_size = -2; + ost->st_atime = st->st_atime; + ost->st_mtime = st->st_mtime; + ost->st_ctime = st->st_ctime; + ost->st_blksize = st->st_blksize; + ost->st_blocks = st->st_blocks; + ost->st_flags = st->st_flags; + ost->st_gen = st->st_gen; +} + +/* + * Get file status; this version follows links. + */ +/* ARGSUSED */ +int +compat_43_sys_stat(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_stat_args /* { + syscallarg(char *) path; + syscallarg(struct ostat *) ub; + } */ *uap = v; + struct stat sb; + struct ostat osb; + int error; + struct nameidata nd; + + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, + SCARG(uap, path), p); + if (error = namei(&nd)) + return (error); + error = vn_stat(nd.ni_vp, &sb, p); + vput(nd.ni_vp); + if (error) + return (error); + cvtstat(&sb, &osb); + error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); + return (error); +} + + +/* + * Get file status; this version does not follow links. + */ +/* ARGSUSED */ +int +compat_43_sys_lstat(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_lstat_args /* { + syscallarg(char *) path; + syscallarg(struct ostat *) ub; + } */ *uap = v; + struct vnode *vp, *dvp; + struct stat sb, sb1; + struct ostat osb; + int error; + struct nameidata nd; + + NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE, + SCARG(uap, path), p); + if (error = namei(&nd)) + return (error); + /* + * For symbolic links, always return the attributes of its + * containing directory, except for mode, size, and links. + */ + vp = nd.ni_vp; + dvp = nd.ni_dvp; + if (vp->v_type != VLNK) { + if (dvp == vp) + vrele(dvp); + else + vput(dvp); + error = vn_stat(vp, &sb, p); + vput(vp); + if (error) + return (error); + } else { + error = vn_stat(dvp, &sb, p); + vput(dvp); + if (error) { + vput(vp); + return (error); + } + error = vn_stat(vp, &sb1, p); + vput(vp); + if (error) + return (error); + sb.st_mode &= ~S_IFDIR; + sb.st_mode |= S_IFLNK; + sb.st_nlink = sb1.st_nlink; + sb.st_size = sb1.st_size; + sb.st_blocks = sb1.st_blocks; + } + cvtstat(&sb, &osb); + error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); + return (error); +} + + +/* + * Return status information about a file descriptor. + */ +/* ARGSUSED */ +compat_43_sys_fstat(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_fstat_args /* { + syscallarg(int) fd; + syscallarg(struct ostat *) sb; + } */ *uap = v; + int fd = SCARG(uap, fd); + register struct filedesc *fdp = p->p_fd; + register struct file *fp; + struct stat ub; + struct ostat oub; + int error; + + if ((u_int)fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) + return (EBADF); + switch (fp->f_type) { + + case DTYPE_VNODE: + error = vn_stat((struct vnode *)fp->f_data, &ub, p); + break; + + case DTYPE_SOCKET: + error = soo_stat((struct socket *)fp->f_data, &ub); + break; + + default: + panic("ofstat"); + /*NOTREACHED*/ + } + cvtstat(&ub, &oub); + if (error == 0) + error = copyout((caddr_t)&oub, (caddr_t)SCARG(uap, sb), + sizeof (oub)); + return (error); +} + + +/* + * Truncate a file given a file descriptor. + */ +/* ARGSUSED */ +int +compat_43_sys_ftruncate(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_ftruncate_args /* { + syscallarg(int) fd; + syscallarg(long) length; + } */ *uap = v; + struct sys_ftruncate_args /* { + syscallarg(int) fd; + syscallarg(int) pad; + syscallarg(off_t) length; + } */ nuap; + + SCARG(&nuap, fd) = SCARG(uap, fd); + SCARG(&nuap, length) = SCARG(uap, length); + return (sys_ftruncate(p, &nuap, retval)); +} + +/* + * Truncate a file given its path name. + */ +/* ARGSUSED */ +int +compat_43_sys_truncate(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_truncate_args /* { + syscallarg(char *) path; + syscallarg(long) length; + } */ *uap = v; + struct sys_truncate_args /* { + syscallarg(char *) path; + syscallarg(int) pad; + syscallarg(off_t) length; + } */ nuap; + + SCARG(&nuap, path) = SCARG(uap, path); + SCARG(&nuap, length) = SCARG(uap, length); + return (sys_truncate(p, &nuap, retval)); +} + + +/* + * Reposition read/write file offset. + */ +int +compat_43_sys_lseek(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_lseek_args /* { + syscallarg(int) fd; + syscallarg(long) offset; + syscallarg(int) whence; + } */ *uap = v; + struct sys_lseek_args /* { + syscallarg(int) fd; + syscallarg(int) pad; + syscallarg(off_t) offset; + syscallarg(int) whence; + } */ nuap; + off_t qret; + int error; + + SCARG(&nuap, fd) = SCARG(uap, fd); + SCARG(&nuap, offset) = SCARG(uap, offset); + SCARG(&nuap, whence) = SCARG(uap, whence); + error = sys_lseek(p, &nuap, (register_t *)&qret); + *(long *)retval = qret; + return (error); +} + + +/* + * Create a file. + */ +int +compat_43_sys_creat(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_creat_args /* { + syscallarg(char *) path; + syscallarg(int) mode; + } */ *uap = v; + struct sys_open_args /* { + syscallarg(char *) path; + syscallarg(int) flags; + syscallarg(int) mode; + } */ nuap; + + SCARG(&nuap, path) = SCARG(uap, path); + SCARG(&nuap, mode) = SCARG(uap, mode); + SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; + return (sys_open(p, &nuap, retval)); +} + +/*ARGSUSED*/ +int +compat_43_sys_quota(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + + return (ENOSYS); +} + + +/* + * Read a block of directory entries in a file system independent format. + */ +int +compat_43_sys_getdirentries(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + register struct compat_43_sys_getdirentries_args /* { + syscallarg(int) fd; + syscallarg(char *) buf; + syscallarg(u_int) count; + syscallarg(long *) basep; + } */ *uap = v; + register struct vnode *vp; + struct file *fp; + struct uio auio, kuio; + struct iovec aiov, kiov; + struct dirent *dp, *edp; + caddr_t dirbuf; + int error, eofflag, readcnt; + long loff; + + if (error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) + return (error); + if ((fp->f_flag & FREAD) == 0) + return (EBADF); + vp = (struct vnode *)fp->f_data; +unionread: + if (vp->v_type != VDIR) + return (EINVAL); + aiov.iov_base = SCARG(uap, buf); + aiov.iov_len = SCARG(uap, count); + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_procp = p; + auio.uio_resid = SCARG(uap, count); + VOP_LOCK(vp); + loff = auio.uio_offset = fp->f_offset; +# if (BYTE_ORDER != LITTLE_ENDIAN) + if (vp->v_mount->mnt_maxsymlinklen <= 0) { + error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, + (u_long *)0, 0); + fp->f_offset = auio.uio_offset; + } else +# endif + { + kuio = auio; + kuio.uio_iov = &kiov; + kuio.uio_segflg = UIO_SYSSPACE; + kiov.iov_len = SCARG(uap, count); + MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK); + kiov.iov_base = dirbuf; + error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, + (u_long *)0, 0); + fp->f_offset = kuio.uio_offset; + if (error == 0) { + readcnt = SCARG(uap, count) - kuio.uio_resid; + edp = (struct dirent *)&dirbuf[readcnt]; + for (dp = (struct dirent *)dirbuf; dp < edp; ) { +# if (BYTE_ORDER == LITTLE_ENDIAN) + /* + * The expected low byte of + * dp->d_namlen is our dp->d_type. + * The high MBZ byte of dp->d_namlen + * is our dp->d_namlen. + */ + dp->d_type = dp->d_namlen; + dp->d_namlen = 0; +# else + /* + * The dp->d_type is the high byte + * of the expected dp->d_namlen, + * so must be zero'ed. + */ + dp->d_type = 0; +# endif + if (dp->d_reclen > 0) { + dp = (struct dirent *) + ((char *)dp + dp->d_reclen); + } else { + error = EIO; + break; + } + } + if (dp >= edp) + error = uiomove(dirbuf, readcnt, &auio); + } + FREE(dirbuf, M_TEMP); + } + VOP_UNLOCK(vp); + if (error) + return (error); + +#ifdef UNION +{ + extern int (**union_vnodeop_p)(); + extern struct vnode *union_dircache __P((struct vnode *)); + + if ((SCARG(uap, count) == auio.uio_resid) && + (vp->v_op == union_vnodeop_p)) { + struct vnode *lvp; + + lvp = union_dircache(vp); + if (lvp != NULLVP) { + struct vattr va; + + /* + * If the directory is opaque, + * then don't show lower entries + */ + error = VOP_GETATTR(vp, &va, fp->f_cred, p); + if (va.va_flags & OPAQUE) { + vput(lvp); + lvp = NULL; + } + } + + if (lvp != NULLVP) { + error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); + VOP_UNLOCK(lvp); + + if (error) { + vrele(lvp); + return (error); + } + fp->f_data = (caddr_t) lvp; + fp->f_offset = 0; + error = vn_close(vp, FREAD, fp->f_cred, p); + if (error) + return (error); + vp = lvp; + goto unionread; + } + } +} +#endif /* UNION */ + + if ((SCARG(uap, count) == auio.uio_resid) && + (vp->v_flag & VROOT) && + (vp->v_mount->mnt_flag & MNT_UNION)) { + struct vnode *tvp = vp; + vp = vp->v_mount->mnt_vnodecovered; + VREF(vp); + fp->f_data = (caddr_t) vp; + fp->f_offset = 0; + vrele(tvp); + goto unionread; + } + error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), + sizeof(long)); + *retval = SCARG(uap, count) - auio.uio_resid; + return (error); +} |