[BACK]Return to freebsd_file.c CVS log [TXT][DIR] Up to [local] / sys / compat / freebsd

Annotation of sys/compat/freebsd/freebsd_file.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: freebsd_file.c,v 1.25 2006/06/25 15:01:53 sturm Exp $ */
        !             2: /*     $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos Exp $        */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1995 Frank van der Linden
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. All advertising materials mentioning features or use of this software
        !            17:  *    must display the following acknowledgement:
        !            18:  *      This product includes software developed for the NetBSD Project
        !            19:  *      by Frank van der Linden
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            33:  *
        !            34:  *     from: linux_file.c,v 1.3 1995/04/04 04:21:30 mycroft Exp
        !            35:  */
        !            36:
        !            37: #include <sys/param.h>
        !            38: #include <sys/systm.h>
        !            39: #include <sys/namei.h>
        !            40: #include <sys/proc.h>
        !            41: #include <sys/file.h>
        !            42: #include <sys/stat.h>
        !            43: #include <sys/filedesc.h>
        !            44: #include <sys/ioctl.h>
        !            45: #include <sys/kernel.h>
        !            46: #include <sys/vnode.h>
        !            47: #include <sys/mount.h>
        !            48: #include <sys/malloc.h>
        !            49:
        !            50: #include <sys/syscallargs.h>
        !            51:
        !            52: #include <compat/freebsd/freebsd_signal.h>
        !            53: #include <compat/freebsd/freebsd_syscallargs.h>
        !            54: #include <compat/freebsd/freebsd_util.h>
        !            55:
        !            56: #define        ARRAY_LENGTH(array)     (sizeof(array)/sizeof(array[0]))
        !            57:
        !            58: const char freebsd_emul_path[] = "/emul/freebsd";
        !            59:
        !            60: static char * convert_from_freebsd_mount_type(int);
        !            61: void statfs_to_freebsd_statfs(struct proc *, struct mount *, struct statfs *, struct freebsd_statfs *);
        !            62:
        !            63: struct freebsd_statfs {
        !            64:        long    f_spare2;               /* placeholder */
        !            65:        long    f_bsize;                /* fundamental file system block size */
        !            66:        long    f_iosize;               /* optimal transfer block size */
        !            67:        long    f_blocks;               /* total data blocks in file system */
        !            68:        long    f_bfree;                /* free blocks in fs */
        !            69:        long    f_bavail;               /* free blocks avail to non-superuser */
        !            70:        long    f_files;                /* total file nodes in file system */
        !            71:        long    f_ffree;                /* free file nodes in fs */
        !            72:        fsid_t  f_fsid;                 /* file system id */
        !            73:        uid_t   f_owner;                /* user that mounted the filesystem */
        !            74:        int     f_type;                 /* type of filesystem */
        !            75:        int     f_flags;                /* copy of mount exported flags */
        !            76:        long    f_syncwrites;           /* count of sync writes since mount */
        !            77:        long    f_asyncwrites;          /* count of async writes since mount */
        !            78:        char    f_fstypename[MFSNAMELEN]; /* fs type name */
        !            79:        char    f_mntonname[MNAMELEN];  /* directory on which mounted */
        !            80:        char    f_mntfromname[MNAMELEN];/* mounted filesystem */
        !            81: };
        !            82:
        !            83: static char *
        !            84: convert_from_freebsd_mount_type(type)
        !            85:        int type;
        !            86: {
        !            87:        static char *freebsd_mount_type[] = {
        !            88:                NULL,     /*  0 = MOUNT_NONE */
        !            89:                "ffs",    /*  1 = "Fast" Filesystem */
        !            90:                "nfs",    /*  2 = Network Filesystem */
        !            91:                "mfs",    /*  3 = Memory Filesystem */
        !            92:                "msdos",  /*  4 = MSDOS Filesystem */
        !            93:                "lfs",    /*  5 = Log-based Filesystem */
        !            94:                "lofs",   /*  6 = Loopback filesystem */
        !            95:                "fdesc",  /*  7 = File Descriptor Filesystem */
        !            96:                "portal", /*  8 = Portal Filesystem */
        !            97:                "null",   /*  9 = Minimal Filesystem Layer */
        !            98:                "umap",   /* 10 = User/Group Identifier Remapping Filesystem */
        !            99:                "kernfs", /* 11 = Kernel Information Filesystem */
        !           100:                "procfs", /* 12 = /proc Filesystem */
        !           101:                "afs",    /* 13 = Andrew Filesystem */
        !           102:                "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
        !           103:                "union",  /* 15 = Union (translucent) Filesystem */
        !           104:                NULL,     /* 16 = "devfs" - existing device Filesystem */
        !           105: #if 0 /* These filesystems don't exist in FreeBSD */
        !           106:                "adosfs", /* ?? = AmigaDOS Filesystem */
        !           107: #endif
        !           108:        };
        !           109:
        !           110:        if (type < 0 || type >= ARRAY_LENGTH(freebsd_mount_type))
        !           111:                return (NULL);
        !           112:        return (freebsd_mount_type[type]);
        !           113: }
        !           114:
        !           115: int
        !           116: freebsd_sys_mount(p, v, retval)
        !           117:        struct proc *p;
        !           118:        void *v;
        !           119:        register_t *retval;
        !           120: {
        !           121:        struct freebsd_sys_mount_args /* {
        !           122:                syscallarg(int) type;
        !           123:                syscallarg(char *) path;
        !           124:                syscallarg(int) flags;
        !           125:                syscallarg(caddr_t) data;
        !           126:        } */ *uap = v;
        !           127:        int error;
        !           128:        char *type, *s;
        !           129:        caddr_t sg = stackgap_init(p->p_emul);
        !           130:        struct sys_mount_args bma;
        !           131:
        !           132:        if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
        !           133:                return ENODEV;
        !           134:        s = stackgap_alloc(&sg, MFSNAMELEN + 1);
        !           135:        if ((error = copyout(type, s, strlen(type) + 1)) != 0)
        !           136:                return error;
        !           137:        SCARG(&bma, type) = s;
        !           138:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           139:        SCARG(&bma, path) = SCARG(uap, path);
        !           140:        SCARG(&bma, flags) = SCARG(uap, flags);
        !           141:        SCARG(&bma, data) = SCARG(uap, data);
        !           142:        return sys_mount(p, &bma, retval);
        !           143: }
        !           144:
        !           145: /*
        !           146:  * The following syscalls are only here because of the alternate path check.
        !           147:  */
        !           148:
        !           149: /* XXX - UNIX domain: int freebsd_sys_bind(int s, caddr_t name, int namelen); */
        !           150: /* XXX - UNIX domain: int freebsd_sys_connect(int s, caddr_t name, int namelen); */
        !           151:
        !           152:
        !           153: int
        !           154: freebsd_sys_open(p, v, retval)
        !           155:        struct proc *p;
        !           156:        void *v;
        !           157:        register_t *retval;
        !           158: {
        !           159:        struct freebsd_sys_open_args /* {
        !           160:                syscallarg(char *) path;
        !           161:                syscallarg(int) flags;
        !           162:                syscallarg(int) mode;
        !           163:        } */ *uap = v;
        !           164:        caddr_t sg = stackgap_init(p->p_emul);
        !           165:
        !           166:        if (SCARG(uap, flags) & O_CREAT)
        !           167:                FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           168:        else
        !           169:                FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           170:        return sys_open(p, uap, retval);
        !           171: }
        !           172:
        !           173: int
        !           174: compat_43_freebsd_sys_creat(p, v, retval)
        !           175:        struct proc *p;
        !           176:        void *v;
        !           177:        register_t *retval;
        !           178: {
        !           179:        struct compat_43_freebsd_sys_creat_args /* {
        !           180:                syscallarg(char *) path;
        !           181:                syscallarg(int) mode;
        !           182:        } */ *uap = v;
        !           183:        caddr_t sg  = stackgap_init(p->p_emul);
        !           184:
        !           185:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           186:        return compat_43_sys_creat(p, uap, retval);
        !           187: }
        !           188:
        !           189: int
        !           190: freebsd_sys_link(p, v, retval)
        !           191:        struct proc *p;
        !           192:        void *v;
        !           193:        register_t *retval;
        !           194: {
        !           195:        struct freebsd_sys_link_args /* {
        !           196:                syscallarg(char *) path;
        !           197:                syscallarg(char *) link;
        !           198:        } */ *uap = v;
        !           199:        caddr_t sg = stackgap_init(p->p_emul);
        !           200:
        !           201:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           202:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
        !           203:        return sys_link(p, uap, retval);
        !           204: }
        !           205:
        !           206: int
        !           207: freebsd_sys_unlink(p, v, retval)
        !           208:        struct proc *p;
        !           209:        void *v;
        !           210:        register_t *retval;
        !           211: {
        !           212:        struct freebsd_sys_unlink_args /* {
        !           213:                syscallarg(char *) path;
        !           214:        } */ *uap = v;
        !           215:        caddr_t sg = stackgap_init(p->p_emul);
        !           216:
        !           217:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           218:        return sys_unlink(p, uap, retval);
        !           219: }
        !           220:
        !           221: int
        !           222: freebsd_sys_chdir(p, v, retval)
        !           223:        struct proc *p;
        !           224:        void *v;
        !           225:        register_t *retval;
        !           226: {
        !           227:        struct freebsd_sys_chdir_args /* {
        !           228:                syscallarg(char *) path;
        !           229:        } */ *uap = v;
        !           230:        caddr_t sg = stackgap_init(p->p_emul);
        !           231:
        !           232:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           233:        return sys_chdir(p, uap, retval);
        !           234: }
        !           235:
        !           236: int
        !           237: freebsd_sys_mknod(p, v, retval)
        !           238:        struct proc *p;
        !           239:        void *v;
        !           240:        register_t *retval;
        !           241: {
        !           242:        struct freebsd_sys_mknod_args /* {
        !           243:                syscallarg(char *) path;
        !           244:                syscallarg(int) mode;
        !           245:                syscallarg(int) dev;
        !           246:        } */ *uap = v;
        !           247:        caddr_t sg = stackgap_init(p->p_emul);
        !           248:
        !           249:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           250:        return sys_mknod(p, uap, retval);
        !           251: }
        !           252:
        !           253: int
        !           254: freebsd_sys_chmod(p, v, retval)
        !           255:        struct proc *p;
        !           256:        void *v;
        !           257:        register_t *retval;
        !           258: {
        !           259:        struct freebsd_sys_chmod_args /* {
        !           260:                syscallarg(char *) path;
        !           261:                syscallarg(int) mode;
        !           262:        } */ *uap = v;
        !           263:        caddr_t sg = stackgap_init(p->p_emul);
        !           264:
        !           265:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           266:        return sys_chmod(p, uap, retval);
        !           267: }
        !           268:
        !           269: int
        !           270: freebsd_sys_chown(p, v, retval)
        !           271:        struct proc *p;
        !           272:        void *v;
        !           273:        register_t *retval;
        !           274: {
        !           275:        struct freebsd_sys_chown_args /* {
        !           276:                syscallarg(char *) path;
        !           277:                syscallarg(int) uid;
        !           278:                syscallarg(int) gid;
        !           279:        } */ *uap = v;
        !           280:        caddr_t sg = stackgap_init(p->p_emul);
        !           281:
        !           282:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           283:        return sys_chown(p, uap, retval);
        !           284: }
        !           285:
        !           286: int
        !           287: freebsd_sys_unmount(p, v, retval)
        !           288:        struct proc *p;
        !           289:        void *v;
        !           290:        register_t *retval;
        !           291: {
        !           292:        struct freebsd_sys_unmount_args /* {
        !           293:                syscallarg(char *) path;
        !           294:                syscallarg(int) flags;
        !           295:        } */ *uap = v;
        !           296:        caddr_t sg = stackgap_init(p->p_emul);
        !           297:
        !           298:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           299:        return sys_unmount(p, uap, retval);
        !           300: }
        !           301:
        !           302: int
        !           303: freebsd_sys_access(p, v, retval)
        !           304:        struct proc *p;
        !           305:        void *v;
        !           306:        register_t *retval;
        !           307: {
        !           308:        struct freebsd_sys_access_args /* {
        !           309:                syscallarg(char *) path;
        !           310:                syscallarg(int) flags;
        !           311:        } */ *uap = v;
        !           312:        caddr_t sg = stackgap_init(p->p_emul);
        !           313:
        !           314:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           315:        return sys_access(p, uap, retval);
        !           316: }
        !           317:
        !           318: int
        !           319: freebsd_sys_chflags(p, v, retval)
        !           320:        struct proc *p;
        !           321:        void *v;
        !           322:        register_t *retval;
        !           323: {
        !           324:        struct freebsd_sys_chflags_args /* {
        !           325:                syscallarg(char *) path;
        !           326:                syscallarg(int) flags;
        !           327:        } */ *uap = v;
        !           328:        caddr_t sg = stackgap_init(p->p_emul);
        !           329:
        !           330:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           331:        return sys_chflags(p, uap, retval);
        !           332: }
        !           333:
        !           334: int
        !           335: compat_43_freebsd_sys_stat(p, v, retval)
        !           336:        struct proc *p;
        !           337:        void *v;
        !           338:        register_t *retval;
        !           339: {
        !           340:        struct compat_43_freebsd_sys_stat_args /* {
        !           341:                syscallarg(char *) path;
        !           342:                syscallarg(struct stat43 *) ub;
        !           343:        } */ *uap = v;
        !           344:        caddr_t sg = stackgap_init(p->p_emul);
        !           345:
        !           346:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           347:        return compat_43_sys_stat(p, uap, retval);
        !           348: }
        !           349:
        !           350: int
        !           351: compat_43_freebsd_sys_lstat(p, v, retval)
        !           352:        struct proc *p;
        !           353:        void *v;
        !           354:        register_t *retval;
        !           355: {
        !           356:        struct compat_43_freebsd_sys_lstat_args /* {
        !           357:                syscallarg(char *) path;
        !           358:                syscallarg(struct stat43 *) ub;
        !           359:        } */ *uap = v;
        !           360:        caddr_t sg = stackgap_init(p->p_emul);
        !           361:
        !           362:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           363:        return compat_43_sys_lstat(p, uap, retval);
        !           364: }
        !           365:
        !           366: int
        !           367: freebsd_sys_revoke(p, v, retval)
        !           368:        struct proc *p;
        !           369:        void *v;
        !           370:        register_t *retval;
        !           371: {
        !           372:        struct freebsd_sys_revoke_args /* {
        !           373:                syscallarg(char *) path;
        !           374:        } */ *uap = v;
        !           375:        caddr_t sg = stackgap_init(p->p_emul);
        !           376:
        !           377:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           378:        return sys_revoke(p, uap, retval);
        !           379: }
        !           380:
        !           381: int
        !           382: freebsd_sys_symlink(p, v, retval)
        !           383:        struct proc *p;
        !           384:        void *v;
        !           385:        register_t *retval;
        !           386: {
        !           387:        struct freebsd_sys_symlink_args /* {
        !           388:                syscallarg(char *) path;
        !           389:                syscallarg(char *) link;
        !           390:        } */ *uap = v;
        !           391:        caddr_t sg = stackgap_init(p->p_emul);
        !           392:
        !           393:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           394:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
        !           395:        return sys_symlink(p, uap, retval);
        !           396: }
        !           397:
        !           398: int
        !           399: freebsd_sys_readlink(p, v, retval)
        !           400:        struct proc *p;
        !           401:        void *v;
        !           402:        register_t *retval;
        !           403: {
        !           404:        struct freebsd_sys_readlink_args /* {
        !           405:                syscallarg(char *) path;
        !           406:                syscallarg(char *) buf;
        !           407:                syscallarg(int) count;
        !           408:        } */ *uap = v;
        !           409:        caddr_t sg = stackgap_init(p->p_emul);
        !           410:
        !           411:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           412:        return sys_readlink(p, uap, retval);
        !           413: }
        !           414:
        !           415: int
        !           416: freebsd_sys_execve(p, v, retval)
        !           417:        struct proc *p;
        !           418:        void *v;
        !           419:        register_t *retval;
        !           420: {
        !           421:        struct freebsd_sys_execve_args /* {
        !           422:                syscallarg(char *) path;
        !           423:                syscallarg(char **) argp;
        !           424:                syscallarg(char **) envp;
        !           425:        } */ *uap = v;
        !           426:        struct sys_execve_args ap;
        !           427:        caddr_t sg;
        !           428:
        !           429:        sg = stackgap_init(p->p_emul);
        !           430:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           431:
        !           432:        SCARG(&ap, path) = SCARG(uap, path);
        !           433:        SCARG(&ap, argp) = SCARG(uap, argp);
        !           434:        SCARG(&ap, envp) = SCARG(uap, envp);
        !           435:
        !           436:        return sys_execve(p, &ap, retval);
        !           437: }
        !           438:
        !           439: int
        !           440: freebsd_sys_chroot(p, v, retval)
        !           441:        struct proc *p;
        !           442:        void *v;
        !           443:        register_t *retval;
        !           444: {
        !           445:        struct freebsd_sys_chroot_args /* {
        !           446:                syscallarg(char *) path;
        !           447:        } */ *uap = v;
        !           448:        caddr_t sg = stackgap_init(p->p_emul);
        !           449:
        !           450:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           451:        return sys_chroot(p, uap, retval);
        !           452: }
        !           453:
        !           454: int
        !           455: freebsd_sys_rename(p, v, retval)
        !           456:        struct proc *p;
        !           457:        void *v;
        !           458:        register_t *retval;
        !           459: {
        !           460:        struct freebsd_sys_rename_args /* {
        !           461:                syscallarg(char *) from;
        !           462:                syscallarg(char *) to;
        !           463:        } */ *uap = v;
        !           464:        caddr_t sg = stackgap_init(p->p_emul);
        !           465:
        !           466:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
        !           467:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
        !           468:        return sys_rename(p, uap, retval);
        !           469: }
        !           470:
        !           471: int
        !           472: compat_43_freebsd_sys_truncate(p, v, retval)
        !           473:        struct proc *p;
        !           474:        void *v;
        !           475:        register_t *retval;
        !           476: {
        !           477:        struct compat_43_freebsd_sys_truncate_args /* {
        !           478:                syscallarg(char *) path;
        !           479:                syscallarg(long) length;
        !           480:        } */ *uap = v;
        !           481:        caddr_t sg = stackgap_init(p->p_emul);
        !           482:
        !           483:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           484:        return compat_43_sys_truncate(p, uap, retval);
        !           485: }
        !           486:
        !           487: int
        !           488: freebsd_sys_mkfifo(p, v, retval)
        !           489:        struct proc *p;
        !           490:        void *v;
        !           491:        register_t *retval;
        !           492: {
        !           493:        struct freebsd_sys_mkfifo_args /* {
        !           494:                syscallarg(char *) path;
        !           495:                syscallarg(int) mode;
        !           496:        } */ *uap = v;
        !           497:        caddr_t sg = stackgap_init(p->p_emul);
        !           498:
        !           499:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           500:        return sys_mkfifo(p, uap, retval);
        !           501: }
        !           502:
        !           503: int
        !           504: freebsd_sys_mkdir(p, v, retval)
        !           505:        struct proc *p;
        !           506:        void *v;
        !           507:        register_t *retval;
        !           508: {
        !           509:        struct freebsd_sys_mkdir_args /* {
        !           510:                syscallarg(char *) path;
        !           511:                syscallarg(int) mode;
        !           512:        } */ *uap = v;
        !           513:        caddr_t sg = stackgap_init(p->p_emul);
        !           514:
        !           515:        FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
        !           516:        return sys_mkdir(p, uap, retval);
        !           517: }
        !           518:
        !           519: int
        !           520: freebsd_sys_rmdir(p, v, retval)
        !           521:        struct proc *p;
        !           522:        void *v;
        !           523:        register_t *retval;
        !           524: {
        !           525:        struct freebsd_sys_rmdir_args /* {
        !           526:                syscallarg(char *) path;
        !           527:        } */ *uap = v;
        !           528:        caddr_t sg = stackgap_init(p->p_emul);
        !           529:
        !           530:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           531:        return sys_rmdir(p, uap, retval);
        !           532: }
        !           533:
        !           534: /*
        !           535:  * Convert struct statfs -> struct freebsd_statfs
        !           536:  */
        !           537: void
        !           538: statfs_to_freebsd_statfs(p, mp, sp, fsp)
        !           539:        struct proc *p;
        !           540:        struct mount *mp;
        !           541:        struct statfs *sp;
        !           542:        struct freebsd_statfs *fsp;
        !           543: {
        !           544:        fsp->f_bsize = sp->f_bsize;
        !           545:        fsp->f_iosize = sp->f_iosize;
        !           546:        fsp->f_blocks = sp->f_blocks;
        !           547:        fsp->f_bfree = sp->f_bfree;
        !           548:        fsp->f_bavail = sp->f_bavail;
        !           549:        fsp->f_files = sp->f_files;
        !           550:        fsp->f_ffree = sp->f_ffree;
        !           551:        /* Don't let non-root see filesystem id (for NFS security) */
        !           552:        if (suser(p, 0))
        !           553:                fsp->f_fsid.val[0] = fsp->f_fsid.val[1] = 0;
        !           554:        else
        !           555:                bcopy(&sp->f_fsid, &fsp->f_fsid, sizeof(fsp->f_fsid));
        !           556:        fsp->f_owner = sp->f_owner;
        !           557:        fsp->f_type = mp->mnt_vfc->vfc_typenum;
        !           558:        fsp->f_flags = sp->f_flags;
        !           559:        fsp->f_syncwrites = sp->f_syncwrites;
        !           560:        fsp->f_asyncwrites = sp->f_asyncwrites;
        !           561:        bcopy(sp->f_fstypename, fsp->f_fstypename, MFSNAMELEN);
        !           562:        bcopy(sp->f_mntonname, fsp->f_mntonname, MNAMELEN);
        !           563:        bcopy(sp->f_mntfromname, fsp->f_mntfromname, MNAMELEN);
        !           564: }
        !           565:
        !           566: /*
        !           567:  * Get filesystem statistics.
        !           568:  */
        !           569: /* ARGSUSED */
        !           570: int
        !           571: freebsd_sys_statfs(p, v, retval)
        !           572:        struct proc *p;
        !           573:        void *v;
        !           574:        register_t *retval;
        !           575: {
        !           576:        register struct freebsd_sys_statfs_args /* {
        !           577:                syscallarg(char *) path;
        !           578:                syscallarg(struct freebsd_statfs *) buf;
        !           579:        } */ *uap = v;
        !           580:        register struct mount *mp;
        !           581:        register struct statfs *sp;
        !           582:        struct freebsd_statfs fsb;
        !           583:        int error;
        !           584:        struct nameidata nd;
        !           585:        caddr_t sg = stackgap_init(p->p_emul);
        !           586:
        !           587:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           588:        NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
        !           589:        if ((error = namei(&nd)) != 0)
        !           590:                return (error);
        !           591:        mp = nd.ni_vp->v_mount;
        !           592:        sp = &mp->mnt_stat;
        !           593:        vrele(nd.ni_vp);
        !           594:        if ((error = VFS_STATFS(mp, sp, p)) != 0)
        !           595:                return (error);
        !           596:        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
        !           597:
        !           598:        statfs_to_freebsd_statfs(p, mp, sp, &fsb);
        !           599:        return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
        !           600: }
        !           601:
        !           602: /*
        !           603:  * Get filesystem statistics.
        !           604:  */
        !           605: /* ARGSUSED */
        !           606: int
        !           607: freebsd_sys_fstatfs(p, v, retval)
        !           608:        struct proc *p;
        !           609:        void *v;
        !           610:        register_t *retval;
        !           611: {
        !           612:        register struct freebsd_sys_fstatfs_args /* {
        !           613:                syscallarg(int) fd;
        !           614:                syscallarg(struct freebsd_statfs *) buf;
        !           615:        } */ *uap = v;
        !           616:        struct file *fp;
        !           617:        struct mount *mp;
        !           618:        register struct statfs *sp;
        !           619:        struct freebsd_statfs fsb;
        !           620:        int error;
        !           621:
        !           622:        if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
        !           623:                return (error);
        !           624:        mp = ((struct vnode *)fp->f_data)->v_mount;
        !           625:        sp = &mp->mnt_stat;
        !           626:        error = VFS_STATFS(mp, sp, p);
        !           627:        FRELE(fp);
        !           628:        if (error)
        !           629:                return (error);
        !           630:        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
        !           631:
        !           632:        statfs_to_freebsd_statfs(p, mp, sp, &fsb);
        !           633:        return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
        !           634: }
        !           635:
        !           636: /*
        !           637:  * Get statistics on all filesystems.
        !           638:  */
        !           639: int
        !           640: freebsd_sys_getfsstat(p, v, retval)
        !           641:        struct proc *p;
        !           642:        void *v;
        !           643:        register_t *retval;
        !           644: {
        !           645:        register struct freebsd_sys_getfsstat_args /* {
        !           646:                syscallarg(struct freebsd_statfs *) buf;
        !           647:                syscallarg(long) bufsize;
        !           648:                syscallarg(int) flags;
        !           649:        } */ *uap = v;
        !           650:        register struct mount *mp, *nmp;
        !           651:        register struct statfs *sp;
        !           652:        struct freebsd_statfs fsb;
        !           653:        caddr_t sfsp;
        !           654:        long count, maxcount;
        !           655:        int error, flags = SCARG(uap, flags);
        !           656:
        !           657:        maxcount = SCARG(uap, bufsize) / sizeof(struct freebsd_statfs);
        !           658:        sfsp = (caddr_t)SCARG(uap, buf);
        !           659:        count = 0;
        !           660:
        !           661:        for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
        !           662:            mp = nmp) {
        !           663:                if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
        !           664:                        nmp = CIRCLEQ_NEXT(mp, mnt_list);
        !           665:                        continue;
        !           666:                }
        !           667:                if (sfsp && count < maxcount) {
        !           668:                        sp = &mp->mnt_stat;
        !           669:
        !           670:                        /* Refresh stats unless MNT_NOWAIT is specified */
        !           671:                        if (flags != MNT_NOWAIT &&
        !           672:                            flags != MNT_LAZY &&
        !           673:                            (flags == MNT_WAIT ||
        !           674:                             flags == 0) &&
        !           675:                            (error = VFS_STATFS(mp, sp, p))) {
        !           676:                                nmp = CIRCLEQ_NEXT(mp, mnt_list);
        !           677:                                vfs_unbusy(mp);
        !           678:                                continue;
        !           679:                        }
        !           680:                        sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
        !           681:
        !           682:                        statfs_to_freebsd_statfs(p, mp, sp, &fsb);
        !           683:                        error = copyout((caddr_t)&fsb, sfsp, sizeof(fsb));
        !           684:                        if (error) {
        !           685:                                vfs_unbusy(mp);
        !           686:                                return (error);
        !           687:                        }
        !           688:                        sfsp += sizeof(fsb);
        !           689:                }
        !           690:                count++;
        !           691:                nmp = CIRCLEQ_NEXT(mp, mnt_list);
        !           692:                vfs_unbusy(mp);
        !           693:        }
        !           694:
        !           695:        if (sfsp && count > maxcount)
        !           696:                *retval = maxcount;
        !           697:        else
        !           698:                *retval = count;
        !           699:
        !           700:        return (0);
        !           701: }
        !           702:
        !           703: #ifdef NFSCLIENT
        !           704: int
        !           705: freebsd_sys_getfh(p, v, retval)
        !           706:        struct proc *p;
        !           707:        void *v;
        !           708:        register_t *retval;
        !           709: {
        !           710:        struct freebsd_sys_getfh_args /* {
        !           711:                syscallarg(char *) fname;
        !           712:                syscallarg(fhandle_t *) fhp;
        !           713:        } */ *uap = v;
        !           714:        caddr_t sg = stackgap_init(p->p_emul);
        !           715:
        !           716:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
        !           717:        return sys_getfh(p, uap, retval);
        !           718: }
        !           719: #endif /* NFSCLIENT */
        !           720:
        !           721: int
        !           722: freebsd_sys_stat(p, v, retval)
        !           723:        struct proc *p;
        !           724:        void *v;
        !           725:        register_t *retval;
        !           726: {
        !           727:        struct freebsd_sys_stat_args /* {
        !           728:                syscallarg(char *) path;
        !           729:                syscallarg(struct stat35 *) ub;
        !           730:        } */ *uap = v;
        !           731:        caddr_t sg = stackgap_init(p->p_emul);
        !           732:
        !           733:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           734:        return compat_35_sys_stat(p, uap, retval);
        !           735: }
        !           736:
        !           737: int
        !           738: freebsd_sys_lstat(p, v, retval)
        !           739:        struct proc *p;
        !           740:        void *v;
        !           741:        register_t *retval;
        !           742: {
        !           743:        struct freebsd_sys_lstat_args /* {
        !           744:                syscallarg(char *) path;
        !           745:                syscallarg(struct stat35 *) ub;
        !           746:        } */ *uap = v;
        !           747:        caddr_t sg = stackgap_init(p->p_emul);
        !           748:
        !           749:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           750:        return compat_35_sys_lstat(p, uap, retval);
        !           751: }
        !           752:
        !           753: int
        !           754: freebsd_sys_pathconf(p, v, retval)
        !           755:        struct proc *p;
        !           756:        void *v;
        !           757:        register_t *retval;
        !           758: {
        !           759:        struct freebsd_sys_pathconf_args /* {
        !           760:                syscallarg(char *) path;
        !           761:                syscallarg(int) name;
        !           762:        } */ *uap = v;
        !           763:        caddr_t sg = stackgap_init(p->p_emul);
        !           764:
        !           765:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           766:        return sys_pathconf(p, uap, retval);
        !           767: }
        !           768:
        !           769: int
        !           770: freebsd_sys_truncate(p, v, retval)
        !           771:        struct proc *p;
        !           772:        void *v;
        !           773:        register_t *retval;
        !           774: {
        !           775:        struct freebsd_sys_truncate_args /* {
        !           776:                syscallarg(char *) path;
        !           777:                syscallarg(int) pad;
        !           778:                syscallarg(off_t) length;
        !           779:        } */ *uap = v;
        !           780:        caddr_t sg = stackgap_init(p->p_emul);
        !           781:
        !           782:        FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
        !           783:        return sys_truncate(p, uap, retval);
        !           784: }
        !           785:
        !           786: /*
        !           787:  * Just pass on everything to our fcntl, except for F_[GS]ETOWN on pipes,
        !           788:  * where we translate to SIOC[GS]PGRP.
        !           789:  */
        !           790: int
        !           791: freebsd_sys_fcntl(p, v, retval)
        !           792:        struct proc *p;
        !           793:        void *v;
        !           794:        register_t *retval;
        !           795: {
        !           796:        struct freebsd_sys_fcntl_args /* {
        !           797:                syscallarg(int) fd;
        !           798:                syscallarg(int) cmd;
        !           799:                syscallarg(void *) arg;
        !           800:        } */ *uap = v;
        !           801:        int fd, cmd, error;
        !           802:        struct filedesc *fdp;
        !           803:        struct file *fp;
        !           804:
        !           805:        fd = SCARG(uap, fd);
        !           806:        cmd = SCARG(uap, cmd);
        !           807:
        !           808:        switch (cmd) {
        !           809:        case F_GETOWN:
        !           810:        case F_SETOWN:
        !           811:                /* Our pipes does not understand F_[GS]ETOWN.  */
        !           812:                fdp = p->p_fd;
        !           813:                if ((fp = fd_getfile(fdp, fd)) == NULL)
        !           814:                        return (EBADF);
        !           815:                if (fp->f_type == DTYPE_PIPE) {
        !           816:                        FREF(fp);
        !           817:                        error = (*fp->f_ops->fo_ioctl)(fp,
        !           818:                            cmd == F_GETOWN ? SIOCGPGRP : SIOCSPGRP,
        !           819:                            (caddr_t)&SCARG(uap, arg), p);
        !           820:                        FRELE(fp);
        !           821:                        return (error);
        !           822:                }
        !           823:                break;
        !           824:        }
        !           825:
        !           826:        return (sys_fcntl(p, uap, retval));
        !           827: }
        !           828:

CVSweb