Index: conf/files =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/conf/files,v retrieving revision 1.21 diff -u -u -r1.21 files --- conf/files 24 Oct 2003 14:10:45 -0000 1.21 +++ conf/files 29 Oct 2003 03:44:12 -0000 @@ -1584,3 +1584,5 @@ emulation/43bsd/43bsd_stats.c optional compat_43 emulation/43bsd/43bsd_file.c optional compat_43 emulation/43bsd/43bsd_signal.c optional compat_43 +emulation/43bsd/43bsd_exit.c optional compat_43 +emulation/43bsd/43bsd_resource.c optional compat_43 Index: emulation/43bsd/43bsd_file.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/43bsd/43bsd_file.c,v retrieving revision 1.1 diff -u -u -r1.1 43bsd_file.c --- emulation/43bsd/43bsd_file.c 21 Oct 2003 01:05:09 -0000 1.1 +++ emulation/43bsd/43bsd_file.c 30 Oct 2003 12:43:57 -0000 @@ -50,8 +50,34 @@ #include #include #include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include + +#include + +int +ocreat(struct ocreat_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC, uap->mode, + &uap->sysmsg_result); + + return (error); +} int oftruncate(struct oftruncate_args *uap) @@ -60,5 +86,143 @@ error = kern_ftruncate(uap->fd, uap->length); + return (error); +} + +int +olseek(struct olseek_args *uap) +{ + int error; + + error = kern_lseek(uap->fd, uap->offset, uap->whence, + &uap->sysmsg_result); + + return (error); +} + +int +otruncate(struct otruncate_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_truncate(&nd, uap->length); + + return (error); +} + +int +ogetdirentries(struct ogetdirentries_args *uap) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + 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; + + /* XXX arbitrary sanity limit on `count'. */ + if (uap->count > 64 * 1024) + return (EINVAL); + if ((error = getvnode(p->p_fd, uap->fd, &fp)) != 0) + 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 = uap->buf; + aiov.iov_len = uap->count; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + auio.uio_resid = uap->count; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); + 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, + NULL, NULL); + fp->f_offset = auio.uio_offset; + } else +# endif + { + kuio = auio; + kuio.uio_iov = &kiov; + kuio.uio_segflg = UIO_SYSSPACE; + kiov.iov_len = uap->count; + MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK); + kiov.iov_base = dirbuf; + error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag, + NULL, NULL); + fp->f_offset = kuio.uio_offset; + if (error == 0) { + readcnt = 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, 0, td); + if (error) + return (error); + if (uap->count == auio.uio_resid) { + if (union_dircheckp) { + error = union_dircheckp(td, &vp, fp); + if (error == -1) + goto unionread; + if (error) + return (error); + } + if ((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(&loff, uap->basep, sizeof(long)); + uap->sysmsg_result = uap->count - auio.uio_resid; return (error); } Index: emulation/43bsd/43bsd_stats.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/43bsd/43bsd_stats.c,v retrieving revision 1.1 diff -u -u -r1.1 43bsd_stats.c --- emulation/43bsd/43bsd_stats.c 21 Oct 2003 01:05:09 -0000 1.1 +++ emulation/43bsd/43bsd_stats.c 30 Oct 2003 11:29:32 -0000 @@ -39,9 +39,10 @@ * * $DragonFly: src/sys/emulation/43bsd/43bsd_stats.c,v 1.1 2003/10/21 01:05:09 daver Exp $ * from: DragonFly kern/kern_descrip.c,v 1.16 + * from: DragonFly kern/vfs_syscalls.c,v 1.21 * - * These syscalls used to live in kern/kern_descrip.c. They are modified - * to use the new split syscalls. + * These syscalls used to live in kern/kern_descrip.c and + * kern/vfs_syscalls.c. They are modified * to use the new split syscalls. */ #include "opt_compat.h" @@ -53,6 +54,7 @@ #include #include #include +#include static int compat_43_copyout_stat(struct stat *st, struct ostat *uaddr) @@ -91,8 +93,43 @@ error = kern_fstat(uap->fd, &st); - if (error == 0) { + if (error == 0) error = compat_43_copyout_stat(&st, uap->sb); - } + return (error); +} + +int +ostat(struct ostat_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + struct stat st; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, + UIO_USERSPACE, uap->path, td); + + error = kern_stat(&nd, &st); + + if (error == 0) + error = compat_43_copyout_stat(&st, uap->ub); + return (error); +} + +int +olstat(struct olstat_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + struct stat st; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, + UIO_USERSPACE, uap->path, td); + + error = kern_stat(&nd, &st); + + if (error == 0) + error = compat_43_copyout_stat(&st, uap->ub); return (error); } Index: emulation/43bsd/43bsd_exit.c =================================================================== RCS file: emulation/43bsd/43bsd_exit.c diff -N emulation/43bsd/43bsd_exit.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ emulation/43bsd/43bsd_exit.c 31 Oct 2003 13:05:22 -0000 @@ -0,0 +1,73 @@ +/* + * 43BSD_EXIT.C - 4.3BSD compatibility exit syscalls + * + * 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. + * + * $DragonFly$ + * from: DragonFly kern/kern_exit.c,v 1.26 + * + * These syscalls used to live in kern/kern_exit.c. They are modified + * to use the new split syscalls. + */ + +#include "opt_compat.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * owait() + * + * owait_args(int dummy) + */ +int +owait(struct owait_args *uap) +{ + int error, status; + + error = kern_wait(WAIT_ANY, &status, 0, NULL, &uap->sysmsg_fds[0]); + + if (error == 0) + uap->sysmsg_fds[1] = status; + return (error); +} Index: emulation/43bsd/43bsd_resource.c =================================================================== RCS file: emulation/43bsd/43bsd_resource.c diff -N emulation/43bsd/43bsd_resource.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ emulation/43bsd/43bsd_resource.c 29 Oct 2003 03:45:56 -0000 @@ -0,0 +1,96 @@ +/* + * 43BSD_RESOURCE.C - 4.3BSD compatibility exit syscalls + * + * 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. + * + * $DragonFly$ + * from: DragonFly kern/kern_resource.c,v 1.14 + * + * These syscalls used to live in kern/kern_resource.c. They are modified + * to use the new split syscalls. + */ + +#include "opt_compat.h" + +#include +#include +#include +#include +#include +#include +#include + +int +ogetrlimit(struct ogetrlimit_args *uap) +{ + struct orlimit olim; + struct rlimit lim; + int error; + + error = kern_getrlimit(uap->which, &lim); + + if (error == 0) { + olim.rlim_cur = lim.rlim_cur; + if (olim.rlim_cur == -1) + olim.rlim_cur = 0x7fffffff; + olim.rlim_max = lim.rlim_max; + if (olim.rlim_max == -1) + olim.rlim_max = 0x7fffffff; + error = copyout(&olim, uap->rlp, sizeof(*uap->rlp)); + } + return (error); + +} + +int +osetrlimit(struct osetrlimit_args *uap) +{ + struct orlimit olim; + struct rlimit lim; + int error; + + error = copyin(uap->rlp, &olim, sizeof(olim)); + if (error) + return (error); + lim.rlim_cur = olim.rlim_cur; + lim.rlim_max = olim.rlim_max; + + error = kern_setrlimit(uap->which, &lim); + + return (error); + +} Index: emulation/linux/linux_misc.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/linux_misc.c,v retrieving revision 1.14 diff -u -u -r1.14 linux_misc.c --- emulation/linux/linux_misc.c 23 Sep 2003 05:03:51 -0000 1.14 +++ emulation/linux/linux_misc.c 31 Oct 2003 13:14:14 -0000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -786,43 +787,33 @@ int linux_waitpid(struct linux_waitpid_args *args) { - struct wait_args bsd_args; - int error, tmpstat; + int error, options, status; #ifdef DEBUG if (ldebug(waitpid)) printf(ARGS(waitpid, "%d, %p, %d"), args->pid, (void *)args->status, args->options); #endif - - bsd_args.sysmsg_result = 0; - bsd_args.pid = args->pid; - bsd_args.status = args->status; - bsd_args.options = (args->options & (WNOHANG | WUNTRACED)); + options = args->options & (WNOHANG | WUNTRACED); /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ if (args->options & __WCLONE) - bsd_args.options |= WLINUXCLONE; - bsd_args.rusage = NULL; + options |= WLINUXCLONE; - if ((error = wait4(&bsd_args)) != 0) - return error; - args->sysmsg_result = bsd_args.sysmsg_result; + error = kern_wait(args->pid, args->status ? &status : NULL, options, + NULL, &args->sysmsg_result); - if (args->status) { - if ((error = copyin((caddr_t)args->status, &tmpstat, - sizeof(int))) != 0) - return error; - tmpstat &= 0xffff; - 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, (caddr_t)args->status, sizeof(int)); + if (error == 0 && args->status) { + status &= 0xffff; + if (WIFSIGNALED(status)) + status = (status & 0xffffff80) | + BSD_TO_LINUX_SIGNAL(WTERMSIG(status)); + else if (WIFSTOPPED(status)) + status = (status & 0xffff00ff) | + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(status)) << 8); + error = copyout(&status, args->status, sizeof(status)); } - return 0; + return (error); } #endif /*!__alpha__*/ @@ -831,8 +822,8 @@ { struct thread *td = curthread; struct proc *p = td->td_proc; - struct wait_args bsd_args; - int error, tmpstat; + struct rusage rusage; + int error, options, status; KKASSERT(p); @@ -842,37 +833,31 @@ args->pid, (void *)args->status, args->options, (void *)args->rusage); #endif - - bsd_args.sysmsg_result = 0; - bsd_args.pid = args->pid; - bsd_args.status = args->status; - bsd_args.options = (args->options & (WNOHANG | WUNTRACED)); + options = args->options & (WNOHANG | WUNTRACED); /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ if (args->options & __WCLONE) - bsd_args.options |= WLINUXCLONE; - bsd_args.rusage = (struct rusage *)args->rusage; + options |= WLINUXCLONE; - if ((error = wait4(&bsd_args)) != 0) - return error; - args->sysmsg_result = bsd_args.sysmsg_result; + error = kern_wait(args->pid, args->status ? &status : NULL, options, + args->rusage ? &rusage : NULL, &args->sysmsg_result); - SIGDELSET(p->p_siglist, SIGCHLD); + if (error == 0) + SIGDELSET(p->p_siglist, SIGCHLD); - if (args->status) { - if ((error = copyin((caddr_t)args->status, &tmpstat, - sizeof(int))) != 0) - return error; - tmpstat &= 0xffff; - 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, (caddr_t)args->status, sizeof(int)); + if (error == 0 && args->status) { + status &= 0xffff; + if (WIFSIGNALED(status)) + status = (status & 0xffffff80) | + BSD_TO_LINUX_SIGNAL(WTERMSIG(status)); + else if (WIFSTOPPED(status)) + status = (status & 0xffff00ff) | + (BSD_TO_LINUX_SIGNAL(WSTOPSIG(status)) << 8); + error = copyout(&status, args->status, sizeof(status)); } + if (error == 0 && args->rusage) + error = copyout(&rusage, args->rusage, sizeof(rusage)); - return 0; + return (error); } int @@ -1100,104 +1085,93 @@ int linux_setrlimit(struct linux_setrlimit_args *args) { - struct __setrlimit_args bsd; - struct l_rlimit rlim; + struct l_rlimit linux_rlim; + struct rlimit rlim; + u_int which; int error; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(setrlimit)) printf(ARGS(setrlimit, "%d, %p"), args->resource, (void *)args->rlim); #endif - if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); - error = copyin((caddr_t)args->rlim, &rlim, sizeof(rlim)); + error = copyin(args->rlim, &linux_rlim, sizeof(linux_rlim)); if (error) return (error); + rlim.rlim_cur = (rlim_t)linux_rlim.rlim_cur; + rlim.rlim_max = (rlim_t)linux_rlim.rlim_max; + + error = kern_setrlimit(which, &rlim); - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - bsd.rlp->rlim_cur = (rlim_t)rlim.rlim_cur; - bsd.rlp->rlim_max = (rlim_t)rlim.rlim_max; - bsd.sysmsg_result = 0; - error = setrlimit(&bsd); - args->sysmsg_result = bsd.sysmsg_result; return(error); } int linux_old_getrlimit(struct linux_old_getrlimit_args *args) { - struct __getrlimit_args bsd; - struct l_rlimit rlim; + struct l_rlimit linux_rlim; + struct rlimit rlim; + u_int which; int error; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(old_getrlimit)) printf(ARGS(old_getrlimit, "%d, %p"), args->resource, (void *)args->rlim); #endif - if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - bsd.sysmsg_result = 0; - error = getrlimit(&bsd); - if (error) - return (error); - args->sysmsg_result = bsd.sysmsg_result; - rlim.rlim_cur = (unsigned long)bsd.rlp->rlim_cur; - if (rlim.rlim_cur == ULONG_MAX) - rlim.rlim_cur = LONG_MAX; - rlim.rlim_max = (unsigned long)bsd.rlp->rlim_max; - if (rlim.rlim_max == ULONG_MAX) - rlim.rlim_max = LONG_MAX; - return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); + error = kern_getrlimit(which, &rlim); + + if (error == 0) { + linux_rlim.rlim_cur = (l_ulong)rlim.rlim_cur; + if (linux_rlim.rlim_cur == ULONG_MAX) + linux_rlim.rlim_cur = LONG_MAX; + linux_rlim.rlim_max = (l_ulong)rlim.rlim_max; + if (linux_rlim.rlim_max == ULONG_MAX) + linux_rlim.rlim_max = LONG_MAX; + error = copyout(&linux_rlim, args->rlim, sizeof(rlim)); + } + return (error); } int linux_getrlimit(struct linux_getrlimit_args *args) { - struct __getrlimit_args bsd; - struct l_rlimit rlim; + struct l_rlimit linux_rlim; + struct rlimit rlim; + u_int which; int error; - caddr_t sg = stackgap_init(); #ifdef DEBUG if (ldebug(getrlimit)) printf(ARGS(getrlimit, "%d, %p"), args->resource, (void *)args->rlim); #endif - if (args->resource >= LINUX_RLIM_NLIMITS) return (EINVAL); - - bsd.which = linux_to_bsd_resource[args->resource]; - if (bsd.which == -1) + which = linux_to_bsd_resource[args->resource]; + if (which == -1) return (EINVAL); - bsd.rlp = stackgap_alloc(&sg, sizeof(struct rlimit)); - bsd.sysmsg_result = 0; - error = getrlimit(&bsd); - if (error) - return (error); - args->sysmsg_result = bsd.sysmsg_result; + error = kern_getrlimit(which, &rlim); - rlim.rlim_cur = (l_ulong)bsd.rlp->rlim_cur; - rlim.rlim_max = (l_ulong)bsd.rlp->rlim_max; - return (copyout(&rlim, (caddr_t)args->rlim, sizeof(rlim))); + if (error == 0) { + linux_rlim.rlim_cur = (l_ulong)rlim.rlim_cur; + linux_rlim.rlim_max = (l_ulong)rlim.rlim_max; + error = copyout(&linux_rlim, args->rlim, sizeof(rlim)); + } + return (error); } #endif /*!__alpha__*/ Index: kern/kern_exit.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/kern_exit.c,v retrieving revision 1.26 diff -u -u -r1.26 kern_exit.c --- kern/kern_exit.c 18 Oct 2003 20:41:08 -0000 1.26 +++ kern/kern_exit.c 30 Oct 2003 09:31:19 -0000 @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -77,8 +78,6 @@ static MALLOC_DEFINE(M_ATEXIT, "atexit", "atexit callback"); -static int wait1 (struct wait_args *, int); - /* * callout list for things to do at exit time */ @@ -381,29 +380,20 @@ cpu_proc_exit(); } -#ifdef COMPAT_43 -/* - * owait() - * - * owait_args(int dummy) - */ int -owait(struct owait_args *uap) +wait4(struct wait_args *uap) { - struct wait_args w; + struct rusage rusage; + int error, status; - w.options = 0; - w.rusage = NULL; - w.pid = WAIT_ANY; - w.status = NULL; - return (wait1(&w, 1)); -} -#endif /* COMPAT_43 */ + error = kern_wait(uap->pid, uap->status ? &status : NULL, + uap->options, uap->rusage ? &rusage : NULL, &uap->sysmsg_fds[0]); -int -wait4(struct wait_args *uap) -{ - return (wait1(uap, 0)); + if (error == 0 && uap->status) + error = copyout(&status, uap->status, sizeof(*uap->status)); + if (error == 0 && uap->rusage) + error = copyout(&rusage, uap->rusage, sizeof(*uap->rusage)); + return (error); } /* @@ -411,22 +401,23 @@ * * wait_args(int pid, int *status, int options, struct rusage *rusage) */ -static int -wait1(struct wait_args *uap, int compat) +int +kern_wait(pid_t pid, int *status, int options, struct rusage *rusage, int *res) { - struct proc *q = curproc; + struct thread *td = curthread; + struct proc *q = td->td_proc; struct proc *p, *t; - int status, nfound, error; + int nfound, error; - if (uap->pid == 0) - uap->pid = -q->p_pgid; - if (uap->options &~ (WUNTRACED|WNOHANG|WLINUXCLONE)) + if (pid == 0) + pid = -q->p_pgid; + if (options &~ (WUNTRACED|WNOHANG|WLINUXCLONE)) return (EINVAL); loop: nfound = 0; LIST_FOREACH(p, &q->p_children, p_sibling) { - if (uap->pid != WAIT_ANY && - p->p_pid != uap->pid && p->p_pgid != -uap->pid) + if (pid != WAIT_ANY && + p->p_pid != pid && p->p_pgid != -pid) continue; /* This special case handles a kthread spawned by linux_clone @@ -436,7 +427,7 @@ * and the WLINUXCLONE option signifies we want to wait for threads * and not processes. */ - if ((p->p_sigparent != SIGCHLD) ^ ((uap->options & WLINUXCLONE) != 0)) + if ((p->p_sigparent != SIGCHLD) ^ ((options & WLINUXCLONE) != 0)) continue; nfound++; @@ -472,21 +463,12 @@ ESTCPULIM(curproc->p_estcpu + p->p_estcpu); } - uap->sysmsg_fds[0] = p->p_pid; -#ifdef COMPAT_43 - if (compat) - uap->sysmsg_fds[1] = p->p_xstat; - else -#endif - if (uap->status) { - status = p->p_xstat; /* convert to int */ - if ((error = copyout((caddr_t)&status, - (caddr_t)uap->status, sizeof(status)))) - return (error); - } - if (uap->rusage && (error = copyout((caddr_t)p->p_ru, - (caddr_t)uap->rusage, sizeof (struct rusage)))) - return (error); + /* Take care of our return values. */ + *res = p->p_pid; + if (status) + *status = p->p_xstat; + if (rusage) + *rusage = *p->p_ru; /* * If we got the child via a ptrace 'attach', * we need to give it back to the old parent. @@ -506,7 +488,7 @@ /* * Decrement the count of procs running with this uid. */ - (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); + chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0); /* * Free up credentials. @@ -541,31 +523,26 @@ return (0); } if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 && - (p->p_flag & P_TRACED || uap->options & WUNTRACED)) { + (p->p_flag & P_TRACED || options & WUNTRACED)) { p->p_flag |= P_WAITED; - uap->sysmsg_fds[0] = p->p_pid; -#ifdef COMPAT_43 - if (compat) { - uap->sysmsg_fds[1] = W_STOPCODE(p->p_xstat); - error = 0; - } else -#endif - if (uap->status) { - status = W_STOPCODE(p->p_xstat); - error = copyout((caddr_t)&status, - (caddr_t)uap->status, sizeof(status)); - } else - error = 0; - return (error); + + *res = p->p_pid; + if (status) + *status = p->p_xstat; + /* Zero rusage so we get something consistent. */ + if (rusage) + bzero(rusage, sizeof(rusage)); + return (0); } } if (nfound == 0) return (ECHILD); - if (uap->options & WNOHANG) { - uap->sysmsg_fds[0] = 0; + if (options & WNOHANG) { + *res = 0; return (0); } - if ((error = tsleep((caddr_t)q, PCATCH, "wait", 0))) + error = tsleep((caddr_t)q, PCATCH, "wait", 0); + if (error) return (error); goto loop; } Index: kern/kern_resource.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/kern_resource.c,v retrieving revision 1.14 diff -u -u -r1.14 kern_resource.c --- kern/kern_resource.c 26 Aug 2003 21:09:02 -0000 1.14 +++ kern/kern_resource.c 29 Oct 2003 03:43:49 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -273,57 +274,23 @@ } } -#if defined(COMPAT_43) || defined(COMPAT_SUNOS) -/* ARGSUSED */ -int -osetrlimit(struct osetrlimit_args *uap) -{ - struct orlimit olim; - struct rlimit lim; - int error; - - if ((error = - copyin((caddr_t)uap->rlp, (caddr_t)&olim, sizeof(struct orlimit)))) - return (error); - lim.rlim_cur = olim.rlim_cur; - lim.rlim_max = olim.rlim_max; - return (dosetrlimit(uap->which, &lim)); -} - -/* ARGSUSED */ -int -ogetrlimit(struct ogetrlimit_args *uap) -{ - struct proc *p = curproc; - struct orlimit olim; - - if (uap->which >= RLIM_NLIMITS) - return (EINVAL); - olim.rlim_cur = p->p_rlimit[uap->which].rlim_cur; - if (olim.rlim_cur == -1) - olim.rlim_cur = 0x7fffffff; - olim.rlim_max = p->p_rlimit[uap->which].rlim_max; - if (olim.rlim_max == -1) - olim.rlim_max = 0x7fffffff; - return (copyout((caddr_t)&olim, (caddr_t)uap->rlp, sizeof(olim))); -} -#endif /* COMPAT_43 || COMPAT_SUNOS */ - -/* ARGSUSED */ int setrlimit(struct __setrlimit_args *uap) { struct rlimit alim; int error; - if ((error = - copyin((caddr_t)uap->rlp, (caddr_t)&alim, sizeof (struct rlimit)))) + error = copyin(uap->rlp, &alim, sizeof(alim)); + if (error) return (error); - return (dosetrlimit(uap->which, &alim)); + + error = kern_setrlimit(uap->which, &alim); + + return (error); } int -dosetrlimit(u_int which, struct rlimit *limp) +kern_setrlimit(u_int which, struct rlimit *limp) { struct proc *p = curproc; struct rlimit *alimp; @@ -423,16 +390,34 @@ return (0); } -/* ARGSUSED */ +/* + * The rlimit indexed by which is returned in the second argument. + */ int -getrlimit(struct __getrlimit_args *uap) +kern_getrlimit(u_int which, struct rlimit *limp) { - struct proc *p = curproc; + struct thread *td = curthread; + struct proc *p = td->td_proc; - if (uap->which >= RLIM_NLIMITS) + if (which >= RLIM_NLIMITS) return (EINVAL); - return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp, - sizeof (struct rlimit))); + + *limp = p->p_rlimit[which]; + + return (0); +} + +int +getrlimit(struct __getrlimit_args *uap) +{ + struct rlimit lim; + int error; + + error = kern_getrlimit(uap->which, &lim); + + if (error == 0) + error = copyout(&lim, uap->rlp, sizeof(*uap->rlp)); + return error; } /* Index: kern/vfs_syscalls.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.21 diff -u -u -r1.21 vfs_syscalls.c --- kern/vfs_syscalls.c 21 Oct 2003 01:05:09 -0000 1.21 +++ kern/vfs_syscalls.c 31 Oct 2003 13:26:09 -0000 @@ -40,9 +40,6 @@ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.21 2003/10/21 01:05:09 daver Exp $ */ -/* For 4.3 integer FS ID compatibility */ -#include "opt_compat.h" - #include #include #include @@ -109,9 +106,6 @@ struct vfsconf *vfsp; int error, flag = 0, flag2 = 0; struct vattr va; -#ifdef COMPAT_43 - u_long fstypenum; -#endif struct nameidata nd; char fstypename[MFSNAMELEN]; @@ -202,24 +196,6 @@ vput(vp); return (ENOTDIR); } -#ifdef COMPAT_43 - /* - * Historically filesystem types were identified by number. If we - * get an integer for the filesystem type instead of a string, we - * check to see if it matches one of the historic filesystem types. - */ - fstypenum = (uintptr_t)SCARG(uap, type); - if (fstypenum < maxvfsconf) { - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (vfsp->vfc_typenum == fstypenum) - break; - if (vfsp == NULL) { - vput(vp); - return (ENODEV); - } - strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN); - } else -#endif /* COMPAT_43 */ if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) { vput(vp); return (error); @@ -609,50 +585,56 @@ SCARG(uap, arg), td)); } -/* - * statfs_args(char *path, struct statfs *buf) - * - * Get filesystem statistics. - */ -/* ARGSUSED */ int -statfs(struct statfs_args *uap) +kern_statfs(struct nameidata *nd, struct statfs *buf) { struct thread *td = curthread; struct mount *mp; struct statfs *sp; int error; - struct nameidata nd; - struct statfs sb; - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - mp = nd.ni_vp->v_mount; + mp = nd->ni_vp->v_mount; sp = &mp->mnt_stat; - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(nd.ni_vp); + NDFREE(nd, NDF_ONLY_PNBUF); + vrele(nd->ni_vp); error = VFS_STATFS(mp, sp, td); if (error) return (error); sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - if (suser(td)) { - bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); - sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; - sp = &sb; - } - return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); + bcopy(sp, buf, sizeof(*buf)); + /* Only root should have access to the fsid's. */ + if (suser(td)) + buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; + return (0); } /* - * fstatfs_args(int fd, struct statfs *buf) + * statfs_args(char *path, struct statfs *buf) * * Get filesystem statistics. */ -/* ARGSUSED */ int -fstatfs(struct fstatfs_args *uap) +statfs(struct statfs_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + struct statfs buf; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_statfs(&nd, &buf); + + if (error == 0) + error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + return (error); +} + +int +kern_fstatfs(int fd, struct statfs *buf) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -660,10 +642,10 @@ struct mount *mp; struct statfs *sp; int error; - struct statfs sb; KKASSERT(p); - if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) + error = getvnode(p->p_fd, fd, &fp); + if (error) return (error); mp = ((struct vnode *)fp->f_data)->v_mount; if (mp == NULL) @@ -673,12 +655,29 @@ if (error) return (error); sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - if (suser(td)) { - bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb)); - sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0; - sp = &sb; - } - return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp))); + bcopy(sp, buf, sizeof(*buf)); + /* Only root should have access to the fsid's. */ + if (suser(td)) + buf->f_fsid.val[0] = buf->f_fsid.val[1] = 0; + return (0); +} + +/* + * fstatfs_args(int fd, struct statfs *buf) + * + * Get filesystem statistics. + */ +int +fstatfs(struct fstatfs_args *uap) +{ + struct statfs buf; + int error; + + error = kern_fstatfs(uap->fd, &buf); + + if (error == 0) + error = copyout(&buf, uap->buf, sizeof(*uap->buf)); + return (error); } /* @@ -787,29 +786,41 @@ return (0); } +int +kern_chdir(struct nameidata *nd) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + struct filedesc *fdp = p->p_fd; + int error; + + error = change_dir(nd, td); + if (error) + return (error); + NDFREE(nd, NDF_ONLY_PNBUF); + vrele(fdp->fd_cdir); + fdp->fd_cdir = nd->ni_vp; + return (0); +} + /* * chdir_args(char *path) * * Change current working directory (``.''). */ -/* ARGSUSED */ int chdir(struct chdir_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - struct filedesc *fdp = p->p_fd; - int error; struct nameidata nd; + int error; NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = change_dir(&nd, td)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - vrele(fdp->fd_cdir); - fdp->fd_cdir = nd.ni_vp; - return (0); + uap->path, td); + + error = kern_chdir(&nd); + + return (error); } /* @@ -912,27 +923,19 @@ return (error); } -/* - * open_args(char *path, int flags, int mode) - * - * Check permissions, allocate an open file structure, - * and call the device open routine if any. - */ int -open(struct open_args *uap) +kern_open(struct nameidata *nd, int oflags, int mode, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; struct filedesc *fdp = p->p_fd; struct file *fp; struct vnode *vp; - int cmode, flags, oflags; + int cmode, flags; struct file *nfp; int type, indx, error; struct flock lf; - struct nameidata nd; - oflags = SCARG(uap, flags); if ((oflags & O_ACCMODE) == O_ACCMODE) return (EINVAL); flags = FFLAGS(oflags); @@ -940,16 +943,14 @@ if (error) return (error); fp = nfp; - cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, - SCARG(uap, path), td); + cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; p->p_dupfd = -indx - 1; /* XXX check for fdopen */ /* * Bump the ref count to prevent another process from closing * the descriptor while we are blocked in vn_open() */ fhold(fp); - error = vn_open(&nd, flags, cmode); + error = vn_open(nd, flags, cmode); if (error) { /* * release our own reference @@ -965,7 +966,7 @@ p->p_dupfd >= 0 && /* XXX from fdopen */ (error = dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) { - uap->sysmsg_result = indx; + *res = indx; return (0); } /* @@ -982,8 +983,8 @@ return (error); } p->p_dupfd = 0; - NDFREE(&nd, NDF_ONLY_PNBUF); - vp = nd.ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); + vp = nd->ni_vp; /* * There should be 2 references on the file, one from the descriptor @@ -999,7 +1000,7 @@ VOP_UNLOCK(vp, 0, td); vn_close(vp, flags & FMASK, td); fdrop(fp, td); - uap->sysmsg_result = indx; + *res = indx; return 0; } @@ -1046,40 +1047,32 @@ * descriptor table intact. */ fdrop(fp, td); - uap->sysmsg_result = indx; + *res = indx; return (0); } -#ifdef COMPAT_43 /* - * ocreat(char *path, int mode) + * open_args(char *path, int flags, int mode) * - * Create a file. + * Check permissions, allocate an open file structure, + * and call the device open routine if any. */ int -ocreat(struct ocreat_args *uap) +open(struct open_args *uap) { - struct open_args /* { - syscallarg(char *) path; - syscallarg(int) flags; - syscallarg(int) mode; - } */ nuap; + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); - SCARG(&nuap, path) = SCARG(uap, path); - SCARG(&nuap, mode) = SCARG(uap, mode); - SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC; - return (open(&nuap)); + error = kern_open(&nd, uap->flags, uap->mode, &uap->sysmsg_result); + + return (error); } -#endif /* COMPAT_43 */ -/* - * mknod_args(char *path, int mode, int dev) - * - * Create a special file. - */ -/* ARGSUSED */ int -mknod(struct mknod_args *uap) +kern_mknod(struct nameidata *nd, int mode, int dev) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -1087,11 +1080,10 @@ struct vattr vattr; int error; int whiteout = 0; - struct nameidata nd; KKASSERT(p); - switch (SCARG(uap, mode) & S_IFMT) { + switch (mode & S_IFMT) { case S_IFCHR: case S_IFBLK: error = suser(td); @@ -1103,20 +1095,19 @@ if (error) return (error); bwillwrite(); - NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - vp = nd.ni_vp; + vp = nd->ni_vp; if (vp != NULL) error = EEXIST; else { VATTR_NULL(&vattr); - vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask; - vattr.va_rdev = SCARG(uap, dev); + vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask; + vattr.va_rdev = dev; whiteout = 0; - switch (SCARG(uap, mode) & S_IFMT) { + switch (mode & S_IFMT) { case S_IFMT: /* used by badsect to flag bad sectors */ vattr.va_type = VBAD; break; @@ -1134,29 +1125,50 @@ break; } } - if (!error) { - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); + if (error == 0) { + VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); if (whiteout) - error = VOP_WHITEOUT(nd.ni_dvp, NCPNULL, &nd.ni_cnd, NAMEI_CREATE); + error = VOP_WHITEOUT(nd->ni_dvp, NCPNULL, + &nd->ni_cnd, NAMEI_CREATE); else { - error = VOP_MKNOD(nd.ni_dvp, NCPNULL, &nd.ni_vp, - &nd.ni_cnd, &vattr); + error = VOP_MKNOD(nd->ni_dvp, NCPNULL, &nd->ni_vp, + &nd->ni_cnd, &vattr); if (error == 0) - vput(nd.ni_vp); + vput(nd->ni_vp); } - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_dvp); + NDFREE(nd, NDF_ONLY_PNBUF); + vput(nd->ni_dvp); } else { - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); + NDFREE(nd, NDF_ONLY_PNBUF); + if (nd->ni_dvp == vp) + vrele(nd->ni_dvp); else - vput(nd.ni_dvp); + vput(nd->ni_dvp); if (vp) vrele(vp); } - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod"); + ASSERT_VOP_UNLOCKED(nd->ni_dvp, "mknod"); + ASSERT_VOP_UNLOCKED(nd->.ni_vp, "mknod"); + return (error); +} + +/* + * mknod_args(char *path, int mode, int dev) + * + * Create a special file. + */ +int +mknod(struct mknod_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, uap->path, + td); + + error = kern_mknod(&nd, uap->mode, uap->dev); + return (error); } @@ -1201,103 +1213,129 @@ return (error); } -/* - * link_args(char *path, char *link) - * - * Make a hard file link. - */ -/* ARGSUSED */ int -link(struct link_args *uap) +kern_link(struct nameidata *nd, struct nameidata *linknd) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; - struct nameidata nd; int error; bwillwrite(); - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_NOOBJ, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - vp = nd.ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); + vp = nd->ni_vp; if (vp->v_type == VDIR) error = EPERM; /* POSIX */ else { - NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, link), td); - error = namei(&nd); - if (!error) { - if (nd.ni_vp != NULL) { - if (nd.ni_vp) - vrele(nd.ni_vp); + error = namei(linknd); + if (error == 0) { + if (linknd->ni_vp != NULL) { + if (linknd->ni_vp) + vrele(linknd->ni_vp); error = EEXIST; } else { - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, + VOP_LEASE(linknd->ni_dvp, td, p->p_ucred, LEASE_WRITE); VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); - error = VOP_LINK(nd.ni_dvp, NCPNULL, vp, &nd.ni_cnd); + error = VOP_LINK(linknd->ni_dvp, NCPNULL, vp, + &linknd->ni_cnd); } - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); + NDFREE(linknd, NDF_ONLY_PNBUF); + if (linknd->ni_dvp == linknd->ni_vp) + vrele(linknd->ni_dvp); else - vput(nd.ni_dvp); + vput(linknd->ni_dvp); + ASSERT_VOP_UNLOCKED(linknd->ni_dvp, "link"); + ASSERT_VOP_UNLOCKED(linknd->ni_vp, "link"); } } vrele(vp); - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "link"); return (error); } /* - * symlink(char *path, char *link) + * link_args(char *path, char *link) * - * Make a symbolic link. + * Make a hard file link. */ -/* ARGSUSED */ int -symlink(struct symlink_args *uap) +link(struct link_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd, linknd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_NOOBJ, UIO_USERSPACE, + uap->path, td); + NDINIT(&linknd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, + UIO_USERSPACE, uap->link, td); + + error = kern_link(&nd, &linknd); + + return (error); +} + +int +kern_symlink(char *path, struct nameidata *nd) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vattr vattr; - char *path; int error; - struct nameidata nd; - path = zalloc(namei_zone); - if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) - goto out; bwillwrite(); - NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, UIO_USERSPACE, - SCARG(uap, link), td); - if ((error = namei(&nd)) != 0) - goto out; - if (nd.ni_vp) { - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); + error = namei(nd); + if (error) + return (error); + if (nd->ni_vp) { + NDFREE(nd, NDF_ONLY_PNBUF); + if (nd->ni_dvp == nd->ni_vp) + vrele(nd->ni_dvp); else - vput(nd.ni_dvp); - vrele(nd.ni_vp); - error = EEXIST; - goto out; + vput(nd->ni_dvp); + vrele(nd->ni_vp); + return (EEXIST); } VATTR_NULL(&vattr); vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask; - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); - error = VOP_SYMLINK(nd.ni_dvp, NCPNULL, &nd.ni_vp, &nd.ni_cnd, &vattr, path); - NDFREE(&nd, NDF_ONLY_PNBUF); + VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); + error = VOP_SYMLINK(nd->ni_dvp, NCPNULL, &nd->ni_vp, &nd->ni_cnd, + &vattr, path); + NDFREE(nd, NDF_ONLY_PNBUF); if (error == 0) - vput(nd.ni_vp); - vput(nd.ni_dvp); - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink"); -out: + vput(nd->ni_vp); + vput(nd->ni_dvp); + ASSERT_VOP_UNLOCKED(nd->ni_dvp, "symlink"); + ASSERT_VOP_UNLOCKED(nd->ni_vp, "symlink"); + + return (error); +} + +/* + * symlink(char *path, char *link) + * + * Make a symbolic link. + */ +int +symlink(struct symlink_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + char *path; + int error; + + path = zalloc(namei_zone); + error = copyinstr(uap->path, path, MAXPATHLEN, NULL); + if (error) + return (error); + NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, UIO_USERSPACE, + uap->link, td); + + error = kern_symlink(path, &nd); + zfree(namei_zone, path); return (error); } @@ -1343,25 +1381,19 @@ return (error); } -/* - * unlink_args(char *path) - * - * Delete a name from the filesystem. - */ int -unlink(struct unlink_args *uap) +kern_unlink(struct nameidata *nd) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; int error; - struct nameidata nd; bwillwrite(); - NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - vp = nd.ni_vp; + vp = nd->ni_vp; VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); @@ -1377,29 +1409,44 @@ error = EBUSY; } - if (!error) { - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); - error = VOP_REMOVE(nd.ni_dvp, NCPNULL, vp, &nd.ni_cnd); - } - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); + if (error == 0) { + VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); + error = VOP_REMOVE(nd->ni_dvp, NCPNULL, vp, &nd->ni_cnd); + } + NDFREE(nd, NDF_ONLY_PNBUF); + if (nd->ni_dvp == vp) + vrele(nd->ni_dvp); else - vput(nd.ni_dvp); + vput(nd->ni_dvp); if (vp != NULLVP) vput(vp); - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink"); + ASSERT_VOP_UNLOCKED(nd->ni_dvp, "unlink"); + ASSERT_VOP_UNLOCKED(nd->ni_vp, "unlink"); return (error); } /* - * lseek_args(int fd, int pad, off_t offset, int whence) + * unlink_args(char *path) * - * Reposition read/write file offset. + * Delete a name from the filesystem. */ int -lseek(struct lseek_args *uap) +unlink(struct unlink_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT, UIO_USERSPACE, uap->path, + td); + + error = kern_unlink(&nd); + + return (error); +} + +int +kern_lseek(int fd, off_t offset, int whence, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -1408,70 +1455,55 @@ struct vattr vattr; int error; - if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) + if (fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) return (EBADF); if (fp->f_type != DTYPE_VNODE) return (ESPIPE); - switch (SCARG(uap, whence)) { + switch (whence) { case L_INCR: - fp->f_offset += SCARG(uap, offset); + fp->f_offset += offset; break; case L_XTND: error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, td); if (error) return (error); - fp->f_offset = SCARG(uap, offset) + vattr.va_size; + fp->f_offset = offset + vattr.va_size; break; case L_SET: - fp->f_offset = SCARG(uap, offset); + fp->f_offset = offset; break; default: return (EINVAL); } - uap->sysmsg_offset = fp->f_offset; + *res = fp->f_offset; return (0); } -#if defined(COMPAT_43) || defined(COMPAT_SUNOS) /* - * Reposition read/write file offset. + * lseek_args(int fd, int pad, off_t offset, int whence) * - * olseek_args(int fd, long offset, int whence) + * Reposition read/write file offset. */ int -olseek(struct olseek_args *uap) +lseek(struct lseek_args *uap) { - struct lseek_args /* { - syscallarg(int) fd; - syscallarg(int) pad; - syscallarg(off_t) offset; - syscallarg(int) whence; - } */ nuap; int error; - SCARG(&nuap, fd) = SCARG(uap, fd); - SCARG(&nuap, offset) = SCARG(uap, offset); - SCARG(&nuap, whence) = SCARG(uap, whence); - error = lseek(&nuap); + error = kern_lseek(uap->fd, uap->offset, uap->whence, + &uap->sysmsg_result); + return (error); } -#endif /* COMPAT_43 */ -/* - * access_args(char *path, int flags) - * - * Check access permissions. - */ int -access(struct access_args *uap) +kern_access(struct nameidata *nd, int aflags) { struct thread *td = curthread; struct proc *p = td->td_proc; struct ucred *cred, *tmpcred; struct vnode *vp; int error, flags; - struct nameidata nd; cred = p->p_ucred; /* @@ -1483,25 +1515,25 @@ tmpcred->cr_uid = p->p_ucred->cr_ruid; tmpcred->cr_groups[0] = p->p_ucred->cr_rgid; p->p_ucred = tmpcred; - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + nd->ni_cnd.cn_cred = tmpcred; + error = namei(nd); + if (error) goto out1; - vp = nd.ni_vp; + vp = nd->ni_vp; /* Flags == 0 means only check for existence. */ - if (SCARG(uap, flags)) { + if (aflags) { flags = 0; - if (SCARG(uap, flags) & R_OK) + if (aflags & R_OK) flags |= VREAD; - if (SCARG(uap, flags) & W_OK) + if (aflags & W_OK) flags |= VWRITE; - if (SCARG(uap, flags) & X_OK) + if (aflags & X_OK) flags |= VEXEC; if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0) error = VOP_ACCESS(vp, flags, tmpcred, td); } - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE(nd, NDF_ONLY_PNBUF); vput(vp); out1: p->p_ucred = cred; @@ -1509,120 +1541,61 @@ return (error); } -#if defined(COMPAT_43) || defined(COMPAT_SUNOS) /* - * ostat_args(char *path, struct ostat *ub) + * access_args(char *path, int flags) * - * Get file status; this version follows links. + * Check access permissions. */ -/* ARGSUSED */ int -ostat(struct ostat_args *uap) +access(struct access_args *uap) { struct thread *td = curthread; - struct stat sb; - struct ostat osb; - int error; struct nameidata nd; + int error; NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = vn_stat(nd.ni_vp, &sb, td); - vput(nd.ni_vp); - if (error) - return (error); - cvtstat(&sb, &osb); - error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); + UIO_USERSPACE, uap->path, td); + + error = kern_access(&nd, uap->flags); + return (error); } -/* - * olstat_args(char *path, struct ostat *ub) - * - * Get file status; this version does not follow links. - */ -/* ARGSUSED */ int -olstat(struct olstat_args *uap) +kern_stat(struct nameidata *nd, struct stat *st) { struct thread *td = curthread; - struct vnode *vp; - struct stat sb; - struct ostat osb; int error; - struct nameidata nd; - NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - vp = nd.ni_vp; - error = vn_stat(vp, &sb, td); - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(vp); + error = namei(nd); if (error) return (error); - cvtstat(&sb, &osb); - error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb)); + error = vn_stat(nd->ni_vp, st, td); + NDFREE(nd, NDF_ONLY_PNBUF); + vput(nd->ni_vp); return (error); } /* - * Convert from an old to a new stat structure. - */ -void -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; -} -#endif /* COMPAT_43 || COMPAT_SUNOS */ - -/* * stat_args(char *path, struct stat *ub) * * Get file status; this version follows links. */ -/* ARGSUSED */ int stat(struct stat_args *uap) { struct thread *td = curthread; - struct stat sb; - int error; struct nameidata nd; + struct stat st; + int error; NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - error = vn_stat(nd.ni_vp, &sb, td); - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_vp); - if (error) - return (error); - error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); + UIO_USERSPACE, uap->path, td); + + error = kern_stat(&nd, &st); + + if (error == 0) + error = copyout(&st, uap->ub, sizeof(*uap->ub)); return (error); } @@ -1631,27 +1604,21 @@ * * Get file status; this version does not follow links. */ -/* ARGSUSED */ int lstat(struct lstat_args *uap) { struct thread *td = curthread; - int error; - struct vnode *vp; - struct stat sb; struct nameidata nd; + struct stat st; + int error; NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - vp = nd.ni_vp; - error = vn_stat(vp, &sb, td); - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(vp); - if (error) - return (error); - error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb)); + + error = kern_stat(&nd, &st); + + if (error == 0) + error = copyout(&st, uap->ub, sizeof(*uap->ub)); return (error); } @@ -1760,14 +1727,8 @@ return (error); } -/* - * readlink_args(char *path, char *buf, int count) - * - * Return target name of a symbolic link. - */ -/* ARGSUSED */ int -readlink(struct readlink_args *uap) +kern_readlink(struct nameidata *nd, char *buf, int count, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -1775,30 +1736,49 @@ struct iovec aiov; struct uio auio; int error; - struct nameidata nd; - NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - vp = nd.ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); + vp = nd->ni_vp; if (vp->v_type != VLNK) error = EINVAL; else { - aiov.iov_base = SCARG(uap, buf); - aiov.iov_len = SCARG(uap, count); + aiov.iov_base = buf; + aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_offset = 0; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - auio.uio_resid = SCARG(uap, count); + auio.uio_resid = count; error = VOP_READLINK(vp, &auio, p->p_ucred); } vput(vp); - uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; + *res = count - auio.uio_resid; + return (error); +} + +/* + * readlink_args(char *path, char *buf, int count) + * + * Return target name of a symbolic link. + */ +int +readlink(struct readlink_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, UIO_USERSPACE, + uap->path, td); + + error = kern_readlink(&nd, uap->buf, uap->count, + &uap->sysmsg_result); + return (error); } @@ -1888,6 +1868,20 @@ return error; } +int +kern_chmod(struct nameidata *nd, int mode) +{ + int error; + + error = namei(nd); + if (error) + return (error); + NDFREE(nd, NDF_ONLY_PNBUF); + error = setfmode(nd->ni_vp, mode); + vrele(nd->ni_vp); + return error; +} + /* * chmod_args(char *path, int mode) * @@ -1898,17 +1892,14 @@ chmod(struct chmod_args *uap) { struct thread *td = curthread; - int error; struct nameidata nd; + int error; - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfmode(nd.ni_vp, SCARG(uap, mode)); - vrele(nd.ni_vp); - return error; + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_chmod(&nd, uap->mode); + + return (error); } /* @@ -1970,26 +1961,36 @@ return error; } +int +kern_chown(struct nameidata *nd, int uid, int gid) +{ + int error; + + error = namei(nd); + if (error) + return (error); + NDFREE(nd, NDF_ONLY_PNBUF); + error = setfown(nd->ni_vp, uid, gid); + vrele(nd->ni_vp); + return (error); +} + /* * chown(char *path, int uid, int gid) * * Set ownership given a path name. */ -/* ARGSUSED */ int chown(struct chown_args *uap) { struct thread *td = curthread; - int error; struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_chown(&nd, uap->uid, uap->gid); - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); - vrele(nd.ni_vp); return (error); } @@ -1998,7 +1999,6 @@ * * Set ownership given a path name, do not cross symlinks. */ -/* ARGSUSED */ int lchown(struct lchown_args *uap) { @@ -2006,12 +2006,10 @@ int error; struct nameidata nd; - NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setfown(nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid)); - vrele(nd.ni_vp); + NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, uap->path, td); + + error = kern_chown(&nd, uap->uid, uap->gid); + return (error); } @@ -2036,20 +2034,17 @@ } static int -getutimes(const struct timeval *usrtvp, struct timespec *tsp) +getutimes(const struct timeval *tvp, struct timespec *tsp) { struct timeval tv[2]; - int error; - if (usrtvp == NULL) { + if (tvp == NULL) { microtime(&tv[0]); TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); tsp[1] = tsp[0]; } else { - if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0) - return (error); - TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]); - TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]); + TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]); + TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]); } return 0; } @@ -2074,30 +2069,46 @@ return error; } +int +kern_utimes(struct nameidata *nd, struct timeval *tptr) +{ + struct timespec ts[2]; + int error; + + error = getutimes(tptr, ts); + if (error) + return (error); + error = namei(nd); + if (error) + return (error); + NDFREE(nd, NDF_ONLY_PNBUF); + error = setutimes(nd->ni_vp, ts, tptr == NULL); + vrele(nd->ni_vp); + return (error); +} + /* * utimes_args(char *path, struct timeval *tptr) * * Set the access and modification times of a file. */ -/* ARGSUSED */ int utimes(struct utimes_args *uap) { struct thread *td = curthread; - struct timespec ts[2]; - struct timeval *usrtvp; - int error; + struct timeval tv[2]; struct nameidata nd; + int error; + + if (uap->tptr) { + error = copyin(uap->tptr, tv, sizeof(tv)); + if (error) + return (error); + } + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_utimes(&nd, tv); - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) - return (error); - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setutimes(nd.ni_vp, ts, usrtvp == NULL); - vrele(nd.ni_vp); return (error); } @@ -2106,75 +2117,82 @@ * * Set the access and modification times of a file. */ -/* ARGSUSED */ int lutimes(struct lutimes_args *uap) { struct thread *td = curthread; - struct timespec ts[2]; - struct timeval *usrtvp; - int error; + struct timeval tv[2]; struct nameidata nd; + int error; + + if (uap->tptr) { + error = copyin(uap->tptr, tv, sizeof(tv)); + if (error) + return (error); + } + NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, uap->path, td); + + error = kern_utimes(&nd, tv); - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) - return (error); - NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setutimes(nd.ni_vp, ts, usrtvp == NULL); - vrele(nd.ni_vp); return (error); } -/* - * futimes_args(int fd, struct timeval *tptr) - * - * Set the access and modification times of a file. - */ -/* ARGSUSED */ int -futimes(struct futimes_args *uap) +kern_futimes(int fd, struct timeval *tptr) { struct thread *td = curthread; struct proc *p = td->td_proc; struct timespec ts[2]; struct file *fp; - struct timeval *usrtvp; int error; - usrtvp = SCARG(uap, tptr); - if ((error = getutimes(usrtvp, ts)) != 0) + error = getutimes(tptr, ts); + if (error) return (error); - if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) + error = getvnode(p->p_fd, fd, &fp); + if (error) return (error); - return setutimes((struct vnode *)fp->f_data, ts, usrtvp == NULL); + error = setutimes((struct vnode *)fp->f_data, ts, tptr == NULL); + return (error); } /* - * truncate(char *path, int pad, off_t length) + * futimes_args(int fd, struct timeval *tptr) * - * Truncate a file given its path name. + * Set the access and modification times of a file. */ -/* ARGSUSED */ int -truncate(struct truncate_args *uap) +futimes(struct futimes_args *uap) +{ + struct timeval tv[2]; + int error; + + if (uap->tptr) { + error = copyin(uap->tptr, tv, sizeof(tv)); + if (error) + return (error); + } + + error = kern_futimes(uap->fd, tv); + + return (error); +} + +int +kern_truncate(struct nameidata* nd, off_t length) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; struct vattr vattr; int error; - struct nameidata nd; - if (uap->length < 0) + if (length < 0) return(EINVAL); - NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + if ((error = namei(nd)) != 0) return (error); - vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); + vp = nd->ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); if (vp->v_type == VDIR) @@ -2182,13 +2200,32 @@ else if ((error = vn_writechk(vp)) == 0 && (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, td)) == 0) { VATTR_NULL(&vattr); - vattr.va_size = SCARG(uap, length); + vattr.va_size = length; error = VOP_SETATTR(vp, &vattr, p->p_ucred, td); } vput(vp); return (error); } +/* + * truncate(char *path, int pad, off_t length) + * + * Truncate a file given its path name. + */ +int +truncate(struct truncate_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_USERSPACE, uap->path, td); + + error = kern_truncate(&nd, uap->length); + + return error; +} + int kern_ftruncate(int fd, off_t length) { @@ -2224,7 +2261,6 @@ * * Truncate a file given a file descriptor. */ -/* ARGSUSED */ int ftruncate(struct ftruncate_args *uap) { @@ -2235,28 +2271,6 @@ return (error); } -#if defined(COMPAT_43) || defined(COMPAT_SUNOS) -/* - * otruncate_args(char *path, long length) - * - * Truncate a file given its path name. - */ -/* ARGSUSED */ -int -otruncate(struct otruncate_args *uap) -{ - struct 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 (truncate(&nuap)); -} -#endif /* COMPAT_43 || COMPAT_SUNOS */ - /* * fsync(int fd) * @@ -2287,45 +2301,33 @@ return (error); } -/* - * rename_args(char *from, char *to) - * - * Rename files. Source and destination must either both be directories, - * or both not be directories. If target is a directory, it must be empty. - */ -/* ARGSUSED */ int -rename(struct rename_args *uap) +kern_rename(struct nameidata *fromnd, struct nameidata *tond) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *tvp, *fvp, *tdvp; - struct nameidata fromnd, tond; int error; bwillwrite(); - NDINIT(&fromnd, NAMEI_DELETE, CNP_WANTPARENT | CNP_SAVESTART, - UIO_USERSPACE, SCARG(uap, from), td); - if ((error = namei(&fromnd)) != 0) + error = namei(fromnd); + if (error) return (error); - fvp = fromnd.ni_vp; - NDINIT(&tond, NAMEI_RENAME, - CNP_LOCKPARENT | CNP_LOCKLEAF | CNP_NOCACHE | - CNP_SAVESTART | CNP_NOOBJ, - UIO_USERSPACE, SCARG(uap, to), td); - if (fromnd.ni_vp->v_type == VDIR) - tond.ni_cnd.cn_flags |= CNP_WILLBEDIR; - if ((error = namei(&tond)) != 0) { + fvp = fromnd->ni_vp; + if (fromnd->ni_vp->v_type == VDIR) + tond->ni_cnd.cn_flags |= CNP_WILLBEDIR; + error = namei(tond); + if (error) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; - NDFREE(&fromnd, NDF_ONLY_PNBUF); - vrele(fromnd.ni_dvp); + NDFREE(fromnd, NDF_ONLY_PNBUF); + vrele(fromnd->ni_dvp); vrele(fvp); goto out1; } - tdvp = tond.ni_dvp; - tvp = tond.ni_vp; + tdvp = tond->ni_dvp; + tvp = tond->ni_vp; if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { error = ENOTDIR; @@ -2346,108 +2348,140 @@ out: if (!error) { VOP_LEASE(tdvp, td, p->p_ucred, LEASE_WRITE); - if (fromnd.ni_dvp != tdvp) { - VOP_LEASE(fromnd.ni_dvp, td, p->p_ucred, LEASE_WRITE); + if (fromnd->ni_dvp != tdvp) { + VOP_LEASE(fromnd->ni_dvp, td, p->p_ucred, LEASE_WRITE); } if (tvp) { VOP_LEASE(tvp, td, p->p_ucred, LEASE_WRITE); } - error = VOP_RENAME(fromnd.ni_dvp, NCPNULL, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, NCPNULL, tond.ni_vp, &tond.ni_cnd); - NDFREE(&fromnd, NDF_ONLY_PNBUF); - NDFREE(&tond, NDF_ONLY_PNBUF); + error = VOP_RENAME(fromnd->ni_dvp, NCPNULL, fromnd->ni_vp, + &fromnd->ni_cnd, tond->ni_dvp, NCPNULL, tond->ni_vp, + &tond->ni_cnd); + NDFREE(fromnd, NDF_ONLY_PNBUF); + NDFREE(tond, NDF_ONLY_PNBUF); } else { - NDFREE(&fromnd, NDF_ONLY_PNBUF); - NDFREE(&tond, NDF_ONLY_PNBUF); + NDFREE(fromnd, NDF_ONLY_PNBUF); + NDFREE(tond, NDF_ONLY_PNBUF); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); if (tvp) vput(tvp); - vrele(fromnd.ni_dvp); + vrele(fromnd->ni_dvp); vrele(fvp); } - vrele(tond.ni_startdir); - ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename"); - ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename"); - ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename"); - ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename"); + vrele(tond->ni_startdir); + ASSERT_VOP_UNLOCKED(fromnd->ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(fromnd->ni_vp, "rename"); + ASSERT_VOP_UNLOCKED(tond->ni_dvp, "rename"); + ASSERT_VOP_UNLOCKED(tond->ni_vp, "rename"); out1: - if (fromnd.ni_startdir) - vrele(fromnd.ni_startdir); + if (fromnd->ni_startdir) + vrele(fromnd->ni_startdir); if (error == -1) return (0); return (error); } /* - * mkdir_args(char *path, int mode) + * rename_args(char *from, char *to) * - * Make a directory file. + * Rename files. Source and destination must either both be directories, + * or both not be directories. If target is a directory, it must be empty. */ -/* ARGSUSED */ int -mkdir(struct mkdir_args *uap) +rename(struct rename_args *uap) +{ + struct thread *td = curthread; + struct nameidata fromnd, tond; + int error; + + NDINIT(&fromnd, NAMEI_DELETE, CNP_WANTPARENT | CNP_SAVESTART, + UIO_USERSPACE, uap->from, td); + NDINIT(&tond, NAMEI_RENAME, + CNP_LOCKPARENT | CNP_LOCKLEAF | CNP_NOCACHE | + CNP_SAVESTART | CNP_NOOBJ, + UIO_USERSPACE, uap->to, td); + + error = kern_rename(&fromnd, &tond); + + return (error); +} + +int +kern_mkdir(struct nameidata *nd, int mode) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; struct vattr vattr; int error; - struct nameidata nd; bwillwrite(); - NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, - SCARG(uap, path), td); - nd.ni_cnd.cn_flags |= CNP_WILLBEDIR; - if ((error = namei(&nd)) != 0) + nd->ni_cnd.cn_flags |= CNP_WILLBEDIR; + error = namei(nd); + if (error) return (error); - vp = nd.ni_vp; - if (vp != NULL) { - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); + vp = nd->ni_vp; + if (vp) { + NDFREE(nd, NDF_ONLY_PNBUF); + if (nd->ni_dvp == vp) + vrele(nd->ni_dvp); else - vput(nd.ni_dvp); + vput(nd->ni_dvp); vrele(vp); return (EEXIST); } VATTR_NULL(&vattr); vattr.va_type = VDIR; - vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask; - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); - error = VOP_MKDIR(nd.ni_dvp, NCPNULL, &nd.ni_vp, &nd.ni_cnd, &vattr); - NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_dvp); - if (!error) - vput(nd.ni_vp); - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir"); + vattr.va_mode = (mode & ACCESSPERMS) &~ p->p_fd->fd_cmask; + VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); + error = VOP_MKDIR(nd->ni_dvp, NCPNULL, &nd->ni_vp, &nd->ni_cnd, + &vattr); + NDFREE(nd, NDF_ONLY_PNBUF); + vput(nd->ni_dvp); + if (error == 0) + vput(nd->ni_vp); + ASSERT_VOP_UNLOCKED(nd->ni_dvp, "mkdir"); + ASSERT_VOP_UNLOCKED(nd->ni_vp, "mkdir"); return (error); } /* - * rmdir_args(char *path) + * mkdir_args(char *path, int mode) * - * Remove a directory file. + * Make a directory file. */ /* ARGSUSED */ int -rmdir(struct rmdir_args *uap) +mkdir(struct mkdir_args *uap) +{ + struct thread *td = curthread; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_USERSPACE, uap->path, + td); + + error = kern_mkdir(&nd, uap->mode); + + return (error); +} + +int +kern_rmdir(struct nameidata *nd) { struct thread *td = curthread; struct proc *p = td->td_proc; struct vnode *vp; int error; - struct nameidata nd; bwillwrite(); - NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), td); - if ((error = namei(&nd)) != 0) + error = namei(nd); + if (error) return (error); - vp = nd.ni_vp; + vp = nd->ni_vp; if (vp->v_type != VDIR) { error = ENOTDIR; goto out; @@ -2455,7 +2489,7 @@ /* * No rmdir "." please. */ - if (nd.ni_dvp == vp) { + if (nd->ni_dvp == vp) { error = EINVAL; goto out; } @@ -2465,151 +2499,47 @@ if (vp->v_flag & VROOT) error = EBUSY; else { - VOP_LEASE(nd.ni_dvp, td, p->p_ucred, LEASE_WRITE); + VOP_LEASE(nd->ni_dvp, td, p->p_ucred, LEASE_WRITE); VOP_LEASE(vp, td, p->p_ucred, LEASE_WRITE); - error = VOP_RMDIR(nd.ni_dvp, NCPNULL, nd.ni_vp, &nd.ni_cnd); + error = VOP_RMDIR(nd->ni_dvp, NCPNULL, nd->ni_vp, + &nd->ni_cnd); } out: - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); + NDFREE(nd, NDF_ONLY_PNBUF); + if (nd->ni_dvp == vp) + vrele(nd->ni_dvp); else - vput(nd.ni_dvp); + vput(nd->ni_dvp); if (vp != NULLVP) vput(vp); - ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir"); - ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir"); + ASSERT_VOP_UNLOCKED(nd->ni_dvp, "rmdir"); + ASSERT_VOP_UNLOCKED(nd->ni_vp, "rmdir"); return (error); } -#ifdef COMPAT_43 /* - * ogetdirentries_args(int fd, char *buf, u_int count, long *basep) + * rmdir_args(char *path) * - * Read a block of directory entries in a file system independent format. + * Remove a directory file. */ +/* ARGSUSED */ int -ogetdirentries(struct ogetdirentries_args *uap) +rmdir(struct rmdir_args *uap) { struct thread *td = curthread; - struct proc *p = td->td_proc; - 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; + struct nameidata nd; + int error; + + NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_LOCKLEAF, + UIO_USERSPACE, uap->path, td); + + error = kern_rmdir(&nd); - /* XXX arbitrary sanity limit on `count'. */ - if (SCARG(uap, count) > 64 * 1024) - return (EINVAL); - if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) - 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_td = td; - auio.uio_resid = SCARG(uap, count); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - 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, - NULL, NULL); - 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, - NULL, NULL); - 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, 0, td); - if (error) - return (error); - if (SCARG(uap, count) == auio.uio_resid) { - if (union_dircheckp) { - error = union_dircheckp(td, &vp, fp); - if (error == -1) - goto unionread; - if (error) - return (error); - } - if ((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)); - uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; return (error); } -#endif /* COMPAT_43 */ -/* - * getdirentries_args(int fd, char *buf, u_int conut, long *basep) - * - * Read a block of directory entries in a file system independent format. - */ int -getdirentries(struct getdirentries_args *uap) +kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -2620,7 +2550,7 @@ long loff; int error, eofflag; - if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) + if ((error = getvnode(p->p_fd, fd, &fp)) != 0) return (error); if ((fp->f_flag & FREAD) == 0) return (EBADF); @@ -2628,14 +2558,14 @@ unionread: if (vp->v_type != VDIR) return (EINVAL); - aiov.iov_base = SCARG(uap, buf); - aiov.iov_len = SCARG(uap, count); + aiov.iov_base = buf; + aiov.iov_len = count; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - auio.uio_resid = SCARG(uap, count); + auio.uio_resid = count; /* vn_lock(vp, LK_SHARED | LK_RETRY, td); */ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); loff = auio.uio_offset = fp->f_offset; @@ -2644,7 +2574,7 @@ VOP_UNLOCK(vp, 0, td); if (error) return (error); - if (SCARG(uap, count) == auio.uio_resid) { + if (count == auio.uio_resid) { if (union_dircheckp) { error = union_dircheckp(td, &vp, fp); if (error == -1) @@ -2663,11 +2593,29 @@ goto unionread; } } - if (SCARG(uap, basep) != NULL) { - error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), - sizeof(long)); + if (basep) { + *basep = loff; } - uap->sysmsg_result = SCARG(uap, count) - auio.uio_resid; + *res = count - auio.uio_resid; + return (error); +} + +/* + * getdirentries_args(int fd, char *buf, u_int conut, long *basep) + * + * Read a block of directory entries in a file system independent format. + */ +int +getdirentries(struct getdirentries_args *uap) +{ + long base; + int error; + + error = kern_getdirentries(uap->fd, uap->buf, uap->count, &base, + &uap->sysmsg_result); + + if (error == 0) + error = copyout(&base, uap->basep, sizeof(*uap->basep)); return (error); } @@ -2677,13 +2625,12 @@ int getdents(struct getdents_args *uap) { - struct getdirentries_args ap; + int error; + + error = kern_getdirentries(uap->fd, uap->buf, uap->count, NULL, + &uap->sysmsg_result); - ap.fd = uap->fd; - ap.buf = uap->buf; - ap.count = uap->count; - ap.basep = NULL; - return getdirentries(&ap); + return (error); } /* Index: sys/kern_syscall.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v retrieving revision 1.9 diff -u -u -r1.9 kern_syscall.h --- sys/kern_syscall.h 24 Oct 2003 14:10:46 -0000 1.9 +++ sys/kern_syscall.h 31 Oct 2003 13:36:37 -0000 @@ -35,6 +35,9 @@ union fcntl_dat; struct mbuf; struct msghdr; +struct nameidata; +struct rlimit; +struct rusage; struct sigaction; struct sigaltstack; struct __sigset; @@ -43,6 +46,8 @@ struct socket; struct sockopt; struct stat; +struct statfs; +struct timeval; struct uio; struct vnode; @@ -54,6 +59,12 @@ int kern_fstat(int fd, struct stat *st); /* + * Prototypes for syscalls in kern/kern_exit.c + */ +int kern_wait(pid_t pid, int *status, int options, struct rusage *rusage, + int *res); + +/* * Prototypes for syscalls in kern/kern_sig.c */ int kern_sigaction(int sig, struct sigaction *act, struct sigaction *oact); @@ -70,6 +81,12 @@ int kern_writev(int fd, struct uio *auio, int flags, int *res); /* + * Prototypes for syscalls in kern/kern_resource.c + */ +int kern_setrlimit(u_int which, struct rlimit *limp); +int kern_getrlimit(u_int which, struct rlimit *limp); + +/* * Prototypes for syscalls in kern/uipc_syscalls.c */ int kern_accept(int s, struct sockaddr **name, int *namelen, int *res); @@ -93,6 +110,27 @@ /* * Prototypes for syscalls in kern/vfs_syscalls.c */ +int kern_access(struct nameidata *nd, int aflags); +int kern_chdir(struct nameidata *nd); +int kern_chmod(struct nameidata *nd, int mode); +int kern_chown(struct nameidata *nd, int uid, int gid); +int kern_fstatfs(int fd, struct statfs *buf); int kern_ftruncate(int fd, off_t length); +int kern_futimes(int fd, struct timeval *tptr); +int kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res); +int kern_link(struct nameidata *nd, struct nameidata *linknd); +int kern_lseek(int fd, off_t offset, int whence, int *res); +int kern_mkdir(struct nameidata *nd, int mode); +int kern_mknod(struct nameidata *nd, int mode, int dev); +int kern_open(struct nameidata *nd, int flags, int mode, int *res); +int kern_readlink(struct nameidata *nd, char *buf, int count, int *res); +int kern_rename(struct nameidata *fromnd, struct nameidata *tond); +int kern_rmdir(struct nameidata *nd); +int kern_stat(struct nameidata *nd, struct stat *st); +int kern_statfs(struct nameidata *nd, struct statfs *buf); +int kern_symlink(char *path, struct nameidata *nd); +int kern_truncate(struct nameidata *nd, off_t length); +int kern_unlink(struct nameidata *nd); +int kern_utimes(struct nameidata *nd, struct timeval *tptr); #endif /* !_SYS_KERN_SYSCALL_H_ */