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