[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

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