summaryrefslogtreecommitdiff
path: root/sys/compat/netbsd/netbsd_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/netbsd/netbsd_file.c')
-rw-r--r--sys/compat/netbsd/netbsd_file.c726
1 files changed, 726 insertions, 0 deletions
diff --git a/sys/compat/netbsd/netbsd_file.c b/sys/compat/netbsd/netbsd_file.c
new file mode 100644
index 00000000000..5fe0988a34c
--- /dev/null
+++ b/sys/compat/netbsd/netbsd_file.c
@@ -0,0 +1,726 @@
+/* $OpenBSD: netbsd_file.c,v 1.1 1999/09/17 22:14:09 kstailey Exp $ */
+/* $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos Exp $ */
+
+/*
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Frank van der Linden
+ * 4. 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.
+ *
+ * from: linux_file.c,v 1.3 1995/04/04 04:21:30 mycroft Exp
+ */
+
+#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/vnode.h>
+#include <sys/mount.h>
+#include <sys/malloc.h>
+
+#include <sys/syscallargs.h>
+
+#include <compat/netbsd/netbsd_types.h>
+#include <compat/netbsd/netbsd_stat.h>
+#include <compat/netbsd/netbsd_signal.h>
+#include <compat/netbsd/netbsd_syscallargs.h>
+#include <compat/netbsd/netbsd_util.h>
+
+#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
+
+const char netbsd_emul_path[] = "/emul/netbsd";
+
+#if 0
+static char * convert_from_netbsd_mount_type __P((int));
+void statfs_to_netbsd_statfs __P((struct proc *, struct mount *,
+ struct statfs *, struct netbsd_statfs *));
+
+struct netbsd_statfs {
+ long f_spare2; /* placeholder */
+ long f_bsize; /* fundamental file system block size */
+ long f_iosize; /* optimal transfer block size */
+ long f_blocks; /* total data blocks in file system */
+ long f_bfree; /* free blocks in fs */
+ long f_bavail; /* free blocks avail to non-superuser */
+ long f_files; /* total file nodes in file system */
+ long f_ffree; /* free file nodes in fs */
+ fsid_t f_fsid; /* file system id */
+ uid_t f_owner; /* user that mounted the filesystem */
+ int f_type; /* type of filesystem */
+ int f_flags; /* copy of mount exported flags */
+ long f_syncwrites; /* count of sync writes since mount */
+ long f_asyncwrites; /* count of async writes since mount */
+ char f_fstypename[MFSNAMELEN]; /* fs type name */
+ char f_mntonname[MNAMELEN]; /* directory on which mounted */
+ char f_mntfromname[MNAMELEN];/* mounted filesystem */
+};
+
+static char *
+convert_from_netbsd_mount_type(type)
+ int type;
+{
+ static char *netbsd_mount_type[] = {
+ NULL, /* 0 = MOUNT_NONE */
+ "ffs", /* 1 = "Fast" Filesystem */
+ "nfs", /* 2 = Network Filesystem */
+ "mfs", /* 3 = Memory Filesystem */
+ "msdos", /* 4 = MSDOS Filesystem */
+ "lfs", /* 5 = Log-based Filesystem */
+ "lofs", /* 6 = Loopback filesystem */
+ "fdesc", /* 7 = File Descriptor Filesystem */
+ "portal", /* 8 = Portal Filesystem */
+ "null", /* 9 = Minimal Filesystem Layer */
+ "umap", /* 10 = User/Group Identifier Remapping Filesystem */
+ "kernfs", /* 11 = Kernel Information Filesystem */
+ "procfs", /* 12 = /proc Filesystem */
+ "afs", /* 13 = Andrew Filesystem */
+ "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
+ "union", /* 15 = Union (translucent) Filesystem */
+ NULL, /* 16 = "devfs" - existing device Filesystem */
+#if 0 /* These filesystems don't exist in Netbsd */
+ "adosfs", /* ?? = AmigaDOS Filesystem */
+#endif
+ };
+
+ if (type < 0 || type >= ARRAY_LENGTH(netbsd_mount_type))
+ return (NULL);
+ return (netbsd_mount_type[type]);
+}
+
+int
+netbsd_sys_mount(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_mount_args /* {
+ syscallarg(int) type;
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(caddr_t) data;
+ } */ *uap = v;
+ int error;
+ char *type, *s;
+ caddr_t sg = stackgap_init(p->p_emul);
+ struct sys_mount_args bma;
+
+ if ((type = convert_from_netbsd_mount_type(SCARG(uap, type))) == NULL)
+ return ENODEV;
+ s = stackgap_alloc(&sg, MFSNAMELEN + 1);
+ if ((error = copyout(type, s, strlen(type) + 1)) != 0)
+ return error;
+ SCARG(&bma, type) = s;
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ SCARG(&bma, path) = SCARG(uap, path);
+ SCARG(&bma, flags) = SCARG(uap, flags);
+ SCARG(&bma, data) = SCARG(uap, data);
+ return sys_mount(p, &bma, retval);
+}
+#endif /* 0 */
+
+/*
+ * The following syscalls are only here because of the alternate path check.
+ */
+
+/* XXX - UNIX domain: int netbsd_sys_bind(int s, caddr_t name, int namelen); */
+/* XXX - UNIX domain: int netbsd_sys_connect(int s, caddr_t name, int namelen); */
+
+
+int
+netbsd_sys_open(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_open_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(int) mode;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ if (SCARG(uap, flags) & O_CREAT)
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ else
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_open(p, uap, retval);
+}
+
+int
+compat_43_netbsd_sys_creat(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct compat_43_netbsd_sys_creat_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ return compat_43_sys_creat(p, uap, retval);
+}
+
+int
+netbsd_sys_link(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_link_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) link;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
+ return sys_link(p, uap, retval);
+}
+
+int
+netbsd_sys_unlink(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_unlink_args /* {
+ syscallarg(char *) path;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_unlink(p, uap, retval);
+}
+
+int
+netbsd_sys_chdir(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_chdir_args /* {
+ syscallarg(char *) path;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_chdir(p, uap, retval);
+}
+
+int
+netbsd_sys_mknod(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_mknod_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ syscallarg(int) dev;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ return sys_mknod(p, uap, retval);
+}
+
+int
+netbsd_sys_chmod(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_chmod_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_chmod(p, uap, retval);
+}
+
+int
+netbsd_sys_chown(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_chown_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) uid;
+ syscallarg(int) gid;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_chown(p, uap, retval);
+}
+
+int
+netbsd_sys_unmount(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_unmount_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_unmount(p, uap, retval);
+}
+
+int
+netbsd_sys_access(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_access_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_access(p, uap, retval);
+}
+
+int
+netbsd_sys_chflags(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_chflags_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_chflags(p, uap, retval);
+}
+
+int
+netbsd_sys_revoke(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_revoke_args /* {
+ syscallarg(char *) path;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_revoke(p, uap, retval);
+}
+
+int
+netbsd_sys_symlink(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_symlink_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) link;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
+ return sys_symlink(p, uap, retval);
+}
+
+int
+netbsd_sys_readlink(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_readlink_args /* {
+ syscallarg(char *) path;
+ syscallarg(char *) buf;
+ syscallarg(int) count;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_readlink(p, uap, retval);
+}
+
+int
+netbsd_sys_execve(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_execve_args /* {
+ syscallarg(char *) path;
+ syscallarg(char **) argp;
+ syscallarg(char **) envp;
+ } */ *uap = v;
+ struct sys_execve_args ap;
+ caddr_t sg;
+
+ sg = stackgap_init(p->p_emul);
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+
+ SCARG(&ap, path) = SCARG(uap, path);
+ SCARG(&ap, argp) = SCARG(uap, argp);
+ SCARG(&ap, envp) = SCARG(uap, envp);
+
+ return sys_execve(p, &ap, retval);
+}
+
+int
+netbsd_sys_chroot(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_chroot_args /* {
+ syscallarg(char *) path;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_chroot(p, uap, retval);
+}
+
+int
+netbsd_sys_rename(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_rename_args /* {
+ syscallarg(char *) from;
+ syscallarg(char *) to;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
+ return sys_rename(p, uap, retval);
+}
+
+int
+compat_43_netbsd_sys_truncate(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct compat_43_netbsd_sys_truncate_args /* {
+ syscallarg(char *) path;
+ syscallarg(long) length;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return compat_43_sys_truncate(p, uap, retval);
+}
+
+int
+netbsd_sys_mkfifo(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_mkfifo_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ return sys_mkfifo(p, uap, retval);
+}
+
+int
+netbsd_sys_mkdir(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_mkdir_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) mode;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
+ return sys_mkdir(p, uap, retval);
+}
+
+int
+netbsd_sys_rmdir(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_rmdir_args /* {
+ syscallarg(char *) path;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_rmdir(p, uap, retval);
+}
+
+#if 0 /* XXX */
+/*
+ * Convert struct statfs -> struct netbsd_statfs
+ */
+void
+statfs_to_netbsd_statfs(p, mp, sp, fsp)
+ struct proc *p;
+ struct mount *mp;
+ struct statfs *sp;
+ struct netbsd_statfs *fsp;
+{
+ fsp->f_bsize = sp->f_bsize;
+ fsp->f_iosize = sp->f_iosize;
+ fsp->f_blocks = sp->f_blocks;
+ fsp->f_bfree = sp->f_bfree;
+ fsp->f_bavail = sp->f_bavail;
+ fsp->f_files = sp->f_files;
+ fsp->f_ffree = sp->f_ffree;
+ /* Don't let non-root see filesystem id (for NFS security) */
+ if (suser(p->p_ucred, &p->p_acflag))
+ fsp->f_fsid.val[0] = fsp->f_fsid.val[1] = 0;
+ else
+ bcopy(&sp->f_fsid, &fsp->f_fsid, sizeof(fsp->f_fsid));
+ fsp->f_owner = sp->f_owner;
+ fsp->f_type = mp->mnt_vfc->vfc_typenum;
+ fsp->f_flags = sp->f_flags;
+ fsp->f_syncwrites = sp->f_syncwrites;
+ fsp->f_asyncwrites = sp->f_asyncwrites;
+ bcopy(sp->f_fstypename, fsp->f_fstypename, MFSNAMELEN);
+ bcopy(sp->f_mntonname, fsp->f_mntonname, MNAMELEN);
+ bcopy(sp->f_mntfromname, fsp->f_mntfromname, MNAMELEN);
+}
+
+/*
+ * Get filesystem statistics.
+ */
+/* ARGSUSED */
+int
+netbsd_sys_statfs(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct netbsd_sys_statfs_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct netbsd_statfs *) buf;
+ } */ *uap = v;
+ register struct mount *mp;
+ register struct statfs *sp;
+ struct netbsd_statfs fsb;
+ int error;
+ struct nameidata nd;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ mp = nd.ni_vp->v_mount;
+ sp = &mp->mnt_stat;
+ vrele(nd.ni_vp);
+ if ((error = VFS_STATFS(mp, sp, p)) != 0)
+ return (error);
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+
+ statfs_to_netbsd_statfs(p, mp, sp, &fsb);
+ return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
+}
+
+/*
+ * Get filesystem statistics.
+ */
+/* ARGSUSED */
+int
+netbsd_sys_fstatfs(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct netbsd_sys_fstatfs_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct netbsd_statfs *) buf;
+ } */ *uap = v;
+ struct file *fp;
+ struct mount *mp;
+ register struct statfs *sp;
+ struct netbsd_statfs fsb;
+ int error;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+ mp = ((struct vnode *)fp->f_data)->v_mount;
+ sp = &mp->mnt_stat;
+ if ((error = VFS_STATFS(mp, sp, p)) != 0)
+ return (error);
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+
+ statfs_to_netbsd_statfs(p, mp, sp, &fsb);
+ return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
+}
+
+/*
+ * Get statistics on all filesystems.
+ */
+int
+netbsd_sys_getfsstat(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ register struct netbsd_sys_getfsstat_args /* {
+ syscallarg(struct netbsd_statfs *) buf;
+ syscallarg(long) bufsize;
+ syscallarg(int) flags;
+ } */ *uap = v;
+ register struct mount *mp, *nmp;
+ register struct statfs *sp;
+ struct netbsd_statfs fsb;
+ caddr_t sfsp;
+ long count, maxcount;
+ int error, flags = SCARG(uap, flags);
+
+ maxcount = SCARG(uap, bufsize) / sizeof(struct netbsd_statfs);
+ sfsp = (caddr_t)SCARG(uap, buf);
+ count = 0;
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
+ if (sfsp && count < maxcount) {
+ sp = &mp->mnt_stat;
+
+ /* Refresh stats unless MNT_NOWAIT is specified */
+ if (flags != MNT_NOWAIT &&
+ flags != MNT_LAZY &&
+ (flags == MNT_WAIT ||
+ flags == 0) &&
+ (error = VFS_STATFS(mp, sp, p))) {
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
+ continue;
+ }
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+
+ statfs_to_netbsd_statfs(p, mp, sp, &fsb);
+ error = copyout((caddr_t)&fsb, sfsp, sizeof(fsb));
+ if (error) {
+ vfs_unbusy(mp, p);
+ return (error);
+ }
+ sfsp += sizeof(fsb);
+ }
+ count++;
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
+ }
+ simple_unlock(&mountlist_slock);
+ if (sfsp && count > maxcount)
+ *retval = maxcount;
+ else
+ *retval = count;
+ return (0);
+}
+
+#ifdef NFSCLIENT
+int
+netbsd_sys_getfh(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_getfh_args /* {
+ syscallarg(char *) fname;
+ syscallarg(fhandle_t *) fhp;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
+ return sys_getfh(p, uap, retval);
+}
+#endif /* NFSCLIENT */
+
+#endif /* 0 XXX */
+
+int
+netbsd_sys_pathconf(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_pathconf_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) name;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_pathconf(p, uap, retval);
+}
+
+int
+netbsd_sys_truncate(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct netbsd_sys_truncate_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) pad;
+ syscallarg(off_t) length;
+ } */ *uap = v;
+ caddr_t sg = stackgap_init(p->p_emul);
+
+ NETBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
+ return sys_truncate(p, uap, retval);
+}