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