freebsd_file.c revision 1.13.2.2 1 /* $NetBSD: freebsd_file.c,v 1.13.2.2 2001/06/21 19:59:00 nathanw Exp $ */
2
3 /*
4 * Copyright (c) 1995 Frank van der Linden
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed for the NetBSD Project
18 * by Frank van der Linden
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * from: linux_file.c,v 1.3 1995/04/04 04:21:30 mycroft Exp
34 */
35
36 #if defined(_KERNEL_OPT)
37 #include "fs_nfs.h"
38 #endif
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/namei.h>
43 #include <sys/lwp.h>
44 #include <sys/proc.h>
45 #include <sys/file.h>
46 #include <sys/stat.h>
47 #include <sys/filedesc.h>
48 #include <sys/ioctl.h>
49 #include <sys/kernel.h>
50 #include <sys/mount.h>
51 #include <sys/malloc.h>
52
53 #include <sys/syscallargs.h>
54
55 #include <compat/freebsd/freebsd_syscallargs.h>
56 #include <compat/common/compat_util.h>
57
58 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
59
60 static const char * convert_from_freebsd_mount_type __P((int));
61
62 static const char *
63 convert_from_freebsd_mount_type(type)
64 int type;
65 {
66 static const char * const netbsd_mount_type[] = {
67 NULL, /* 0 = MOUNT_NONE */
68 "ffs", /* 1 = "Fast" Filesystem */
69 "nfs", /* 2 = Network Filesystem */
70 "mfs", /* 3 = Memory Filesystem */
71 "msdos", /* 4 = MSDOS Filesystem */
72 "lfs", /* 5 = Log-based Filesystem */
73 "lofs", /* 6 = Loopback filesystem */
74 "fdesc", /* 7 = File Descriptor Filesystem */
75 "portal", /* 8 = Portal Filesystem */
76 "null", /* 9 = Minimal Filesystem Layer */
77 "umap", /* 10 = User/Group Identifier Remapping Filesystem */
78 "kernfs", /* 11 = Kernel Information Filesystem */
79 "procfs", /* 12 = /proc Filesystem */
80 "afs", /* 13 = Andrew Filesystem */
81 "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
82 "union", /* 15 = Union (translucent) Filesystem */
83 NULL, /* 16 = "devfs" - existing device Filesystem */
84 #if 0 /* These filesystems don't exist in FreeBSD */
85 "adosfs", /* ?? = AmigaDOS Filesystem */
86 #endif
87 };
88
89 if (type < 0 || type >= ARRAY_LENGTH(netbsd_mount_type))
90 return (NULL);
91 return (netbsd_mount_type[type]);
92 }
93
94 int
95 freebsd_sys_mount(l, v, retval)
96 struct lwp *l;
97 void *v;
98 register_t *retval;
99 {
100 struct freebsd_sys_mount_args /* {
101 syscallarg(int) type;
102 syscallarg(char *) path;
103 syscallarg(int) flags;
104 syscallarg(caddr_t) data;
105 } */ *uap = v;
106 struct proc *p = l->l_proc;
107 int error;
108 const char *type;
109 char *s;
110 caddr_t sg = stackgap_init(p->p_emul);
111 struct sys_mount_args bma;
112
113 if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
114 return ENODEV;
115 s = stackgap_alloc(&sg, MFSNAMELEN + 1);
116 if ((error = copyout(type, s, strlen(type) + 1)) != 0)
117 return error;
118 SCARG(&bma, type) = s;
119 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
120 SCARG(&bma, path) = SCARG(uap, path);
121 SCARG(&bma, flags) = SCARG(uap, flags);
122 SCARG(&bma, data) = SCARG(uap, data);
123 return sys_mount(l, &bma, retval);
124 }
125
126 /*
127 * The following syscalls are only here because of the alternate path check.
128 */
129
130 /* XXX - UNIX domain: int freebsd_sys_bind(int s, caddr_t name, int namelen); */
131 /* XXX - UNIX domain: int freebsd_sys_connect(int s, caddr_t name, int namelen); */
132
133
134 int
135 freebsd_sys_open(l, v, retval)
136 struct lwp *l;
137 void *v;
138 register_t *retval;
139 {
140 struct freebsd_sys_open_args /* {
141 syscallarg(char *) path;
142 syscallarg(int) flags;
143 syscallarg(int) mode;
144 } */ *uap = v;
145 struct proc *p = l->l_proc;
146 caddr_t sg = stackgap_init(p->p_emul);
147
148 if (SCARG(uap, flags) & O_CREAT)
149 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
150 else
151 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
152 return sys_open(l, uap, retval);
153 }
154
155 int
156 compat_43_freebsd_sys_creat(l, v, retval)
157 struct lwp *l;
158 void *v;
159 register_t *retval;
160 {
161 struct compat_43_freebsd_sys_creat_args /* {
162 syscallarg(char *) path;
163 syscallarg(int) mode;
164 } */ *uap = v;
165 struct proc *p = l->l_proc;
166 caddr_t sg = stackgap_init(p->p_emul);
167
168 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
169 return compat_43_sys_creat(l, uap, retval);
170 }
171
172 int
173 freebsd_sys_link(l, v, retval)
174 struct lwp *l;
175 void *v;
176 register_t *retval;
177 {
178 struct freebsd_sys_link_args /* {
179 syscallarg(char *) path;
180 syscallarg(char *) link;
181 } */ *uap = v;
182 struct proc *p = l->l_proc;
183 caddr_t sg = stackgap_init(p->p_emul);
184
185 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
186 CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
187 return sys_link(l, uap, retval);
188 }
189
190 int
191 freebsd_sys_unlink(l, v, retval)
192 struct lwp *l;
193 void *v;
194 register_t *retval;
195 {
196 struct freebsd_sys_unlink_args /* {
197 syscallarg(char *) path;
198 } */ *uap = v;
199 struct proc *p = l->l_proc;
200 caddr_t sg = stackgap_init(p->p_emul);
201
202 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
203 return sys_unlink(l, uap, retval);
204 }
205
206 int
207 freebsd_sys_chdir(l, v, retval)
208 struct lwp *l;
209 void *v;
210 register_t *retval;
211 {
212 struct freebsd_sys_chdir_args /* {
213 syscallarg(char *) path;
214 } */ *uap = v;
215 struct proc *p = l->l_proc;
216 caddr_t sg = stackgap_init(p->p_emul);
217
218 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
219 return sys_chdir(l, uap, retval);
220 }
221
222 int
223 freebsd_sys_mknod(l, v, retval)
224 struct lwp *l;
225 void *v;
226 register_t *retval;
227 {
228 struct freebsd_sys_mknod_args /* {
229 syscallarg(char *) path;
230 syscallarg(int) mode;
231 syscallarg(int) dev;
232 } */ *uap = v;
233 struct proc *p = l->l_proc;
234 caddr_t sg = stackgap_init(p->p_emul);
235
236 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
237 return sys_mknod(l, uap, retval);
238 }
239
240 int
241 freebsd_sys_chmod(l, v, retval)
242 struct lwp *l;
243 void *v;
244 register_t *retval;
245 {
246 struct freebsd_sys_chmod_args /* {
247 syscallarg(char *) path;
248 syscallarg(int) mode;
249 } */ *uap = v;
250 struct proc *p = l->l_proc;
251 caddr_t sg = stackgap_init(p->p_emul);
252
253 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
254 return sys_chmod(l, uap, retval);
255 }
256
257 int
258 freebsd_sys_chown(l, v, retval)
259 struct lwp *l;
260 void *v;
261 register_t *retval;
262 {
263 struct freebsd_sys_chown_args /* {
264 syscallarg(char *) path;
265 syscallarg(int) uid;
266 syscallarg(int) gid;
267 } */ *uap = v;
268 struct proc *p = l->l_proc;
269 caddr_t sg = stackgap_init(p->p_emul);
270
271 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
272 return sys_chown(l, uap, retval);
273 }
274
275 int
276 freebsd_sys_lchown(l, v, retval)
277 struct lwp *l;
278 void *v;
279 register_t *retval;
280 {
281 struct freebsd_sys_lchown_args /* {
282 syscallarg(char *) path;
283 syscallarg(int) uid;
284 syscallarg(int) gid;
285 } */ *uap = v;
286 struct proc *p = l->l_proc;
287 caddr_t sg = stackgap_init(p->p_emul);
288
289 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, path));
290 return sys_lchown(l, uap, retval);
291 }
292
293 int
294 freebsd_sys_unmount(l, v, retval)
295 struct lwp *l;
296 void *v;
297 register_t *retval;
298 {
299 struct freebsd_sys_unmount_args /* {
300 syscallarg(char *) path;
301 syscallarg(int) flags;
302 } */ *uap = v;
303 struct proc *p = l->l_proc;
304 caddr_t sg = stackgap_init(p->p_emul);
305
306 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
307 return sys_unmount(l, uap, retval);
308 }
309
310 int
311 freebsd_sys_access(l, v, retval)
312 struct lwp *l;
313 void *v;
314 register_t *retval;
315 {
316 struct freebsd_sys_access_args /* {
317 syscallarg(char *) path;
318 syscallarg(int) flags;
319 } */ *uap = v;
320 struct proc *p = l->l_proc;
321 caddr_t sg = stackgap_init(p->p_emul);
322
323 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
324 return sys_access(l, uap, retval);
325 }
326
327 int
328 freebsd_sys_chflags(l, v, retval)
329 struct lwp *l;
330 void *v;
331 register_t *retval;
332 {
333 struct freebsd_sys_chflags_args /* {
334 syscallarg(char *) path;
335 syscallarg(int) flags;
336 } */ *uap = v;
337 struct proc *p = l->l_proc;
338 caddr_t sg = stackgap_init(p->p_emul);
339
340 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
341 return sys_chflags(l, uap, retval);
342 }
343
344 int
345 compat_43_freebsd_sys_stat(l, v, retval)
346 struct lwp *l;
347 void *v;
348 register_t *retval;
349 {
350 struct compat_43_freebsd_sys_stat_args /* {
351 syscallarg(char *) path;
352 syscallarg(struct stat43 *) ub;
353 } */ *uap = v;
354 struct proc *p = l->l_proc;
355 caddr_t sg = stackgap_init(p->p_emul);
356
357 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
358 return compat_43_sys_stat(l, uap, retval);
359 }
360
361 int
362 compat_43_freebsd_sys_lstat(l, v, retval)
363 struct lwp *l;
364 void *v;
365 register_t *retval;
366 {
367 struct compat_43_freebsd_sys_lstat_args /* {
368 syscallarg(char *) path;
369 syscallarg(struct stat43 *) ub;
370 } */ *uap = v;
371 struct proc *p = l->l_proc;
372 caddr_t sg = stackgap_init(p->p_emul);
373
374 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
375 return compat_43_sys_lstat(l, uap, retval);
376 }
377
378 int
379 freebsd_sys_revoke(l, v, retval)
380 struct lwp *l;
381 void *v;
382 register_t *retval;
383 {
384 struct freebsd_sys_revoke_args /* {
385 syscallarg(char *) path;
386 } */ *uap = v;
387 struct proc *p = l->l_proc;
388 caddr_t sg = stackgap_init(p->p_emul);
389
390 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
391 return sys_revoke(l, uap, retval);
392 }
393
394 int
395 freebsd_sys_symlink(l, v, retval)
396 struct lwp *l;
397 void *v;
398 register_t *retval;
399 {
400 struct freebsd_sys_symlink_args /* {
401 syscallarg(char *) path;
402 syscallarg(char *) link;
403 } */ *uap = v;
404 struct proc *p = l->l_proc;
405 caddr_t sg = stackgap_init(p->p_emul);
406
407 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
408 CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
409 return sys_symlink(l, uap, retval);
410 }
411
412 int
413 freebsd_sys_readlink(l, v, retval)
414 struct lwp *l;
415 void *v;
416 register_t *retval;
417 {
418 struct freebsd_sys_readlink_args /* {
419 syscallarg(char *) path;
420 syscallarg(char *) buf;
421 syscallarg(int) count;
422 } */ *uap = v;
423 struct proc *p = l->l_proc;
424 caddr_t sg = stackgap_init(p->p_emul);
425
426 CHECK_ALT_SYMLINK(p, &sg, SCARG(uap, path));
427 return sys_readlink(l, uap, retval);
428 }
429
430 int
431 freebsd_sys_execve(l, v, retval)
432 struct lwp *l;
433 void *v;
434 register_t *retval;
435 {
436 struct freebsd_sys_execve_args /* {
437 syscallarg(char *) path;
438 syscallarg(char **) argp;
439 syscallarg(char **) envp;
440 } */ *uap = v;
441 struct proc *p = l->l_proc;
442 struct sys_execve_args ap;
443 caddr_t sg;
444
445 sg = stackgap_init(p->p_emul);
446 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
447
448 SCARG(&ap, path) = SCARG(uap, path);
449 SCARG(&ap, argp) = SCARG(uap, argp);
450 SCARG(&ap, envp) = SCARG(uap, envp);
451
452 return sys_execve(l, &ap, retval);
453 }
454
455 int
456 freebsd_sys_chroot(l, v, retval)
457 struct lwp *l;
458 void *v;
459 register_t *retval;
460 {
461 struct freebsd_sys_chroot_args /* {
462 syscallarg(char *) path;
463 } */ *uap = v;
464 struct proc *p = l->l_proc;
465 caddr_t sg = stackgap_init(p->p_emul);
466
467 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
468 return sys_chroot(l, uap, retval);
469 }
470
471 int
472 freebsd_sys_rename(l, v, retval)
473 struct lwp *l;
474 void *v;
475 register_t *retval;
476 {
477 struct freebsd_sys_rename_args /* {
478 syscallarg(char *) from;
479 syscallarg(char *) to;
480 } */ *uap = v;
481 struct proc *p = l->l_proc;
482 caddr_t sg = stackgap_init(p->p_emul);
483
484 CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
485 CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
486 return sys_rename(l, uap, retval);
487 }
488
489 int
490 compat_43_freebsd_sys_truncate(l, v, retval)
491 struct lwp *l;
492 void *v;
493 register_t *retval;
494 {
495 struct compat_43_freebsd_sys_truncate_args /* {
496 syscallarg(char *) path;
497 syscallarg(long) length;
498 } */ *uap = v;
499 struct proc *p = l->l_proc;
500 caddr_t sg = stackgap_init(p->p_emul);
501
502 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
503 return compat_43_sys_truncate(l, uap, retval);
504 }
505
506 int
507 freebsd_sys_mkfifo(l, v, retval)
508 struct lwp *l;
509 void *v;
510 register_t *retval;
511 {
512 struct freebsd_sys_mkfifo_args /* {
513 syscallarg(char *) path;
514 syscallarg(int) mode;
515 } */ *uap = v;
516 struct proc *p = l->l_proc;
517 caddr_t sg = stackgap_init(p->p_emul);
518
519 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
520 return sys_mkfifo(l, uap, retval);
521 }
522
523 int
524 freebsd_sys_mkdir(l, v, retval)
525 struct lwp *l;
526 void *v;
527 register_t *retval;
528 {
529 struct freebsd_sys_mkdir_args /* {
530 syscallarg(char *) path;
531 syscallarg(int) mode;
532 } */ *uap = v;
533 struct proc *p = l->l_proc;
534 caddr_t sg = stackgap_init(p->p_emul);
535
536 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
537 return sys_mkdir(l, uap, retval);
538 }
539
540 int
541 freebsd_sys_rmdir(l, v, retval)
542 struct lwp *l;
543 void *v;
544 register_t *retval;
545 {
546 struct freebsd_sys_rmdir_args /* {
547 syscallarg(char *) path;
548 } */ *uap = v;
549 struct proc *p = l->l_proc;
550 caddr_t sg = stackgap_init(p->p_emul);
551
552 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
553 return sys_rmdir(l, uap, retval);
554 }
555
556 int
557 freebsd_sys_statfs(l, v, retval)
558 struct lwp *l;
559 void *v;
560 register_t *retval;
561 {
562 struct freebsd_sys_stat_args /* {
563 syscallarg(char *) path;
564 syscallarg(struct statfs *) buf;
565 } */ *uap = v;
566 struct proc *p = l->l_proc;
567 caddr_t sg = stackgap_init(p->p_emul);
568
569 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
570 return sys_statfs(l, uap, retval);
571 }
572
573 #ifdef NFS
574 int
575 freebsd_sys_getfh(l, v, retval)
576 struct lwp *l;
577 void *v;
578 register_t *retval;
579 {
580 struct freebsd_sys_getfh_args /* {
581 syscallarg(char *) fname;
582 syscallarg(fhandle_t *) fhp;
583 } */ *uap = v;
584 struct proc *p = l->l_proc;
585 caddr_t sg = stackgap_init(p->p_emul);
586
587 CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
588 return sys_getfh(l, uap, retval);
589 }
590 #endif /* NFS */
591
592 int
593 freebsd_sys_stat(l, v, retval)
594 struct lwp *l;
595 void *v;
596 register_t *retval;
597 {
598 struct freebsd_sys_stat_args /* {
599 syscallarg(char *) path;
600 syscallarg(struct stat12 *) ub;
601 } */ *uap = v;
602 struct proc *p = l->l_proc;
603 caddr_t sg = stackgap_init(p->p_emul);
604
605 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
606 return compat_12_sys_stat(l, uap, retval);
607 }
608
609 int
610 freebsd_sys_lstat(l, v, retval)
611 struct lwp *l;
612 void *v;
613 register_t *retval;
614 {
615 struct freebsd_sys_lstat_args /* {
616 syscallarg(char *) path;
617 syscallarg(struct stat12 *) ub;
618 } */ *uap = v;
619 struct proc *p = l->l_proc;
620 caddr_t sg = stackgap_init(p->p_emul);
621
622 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
623 return compat_12_sys_lstat(l, uap, retval);
624 }
625
626 int
627 freebsd_sys_pathconf(l, v, retval)
628 struct lwp *l;
629 void *v;
630 register_t *retval;
631 {
632 struct freebsd_sys_pathconf_args /* {
633 syscallarg(char *) path;
634 syscallarg(int) name;
635 } */ *uap = v;
636 struct proc *p = l->l_proc;
637 caddr_t sg = stackgap_init(p->p_emul);
638
639 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
640 return sys_pathconf(l, uap, retval);
641 }
642
643 int
644 freebsd_sys_truncate(l, v, retval)
645 struct lwp *l;
646 void *v;
647 register_t *retval;
648 {
649 struct freebsd_sys_truncate_args /* {
650 syscallarg(char *) path;
651 syscallarg(int) pad;
652 syscallarg(off_t) length;
653 } */ *uap = v;
654 struct proc *p = l->l_proc;
655 caddr_t sg = stackgap_init(p->p_emul);
656
657 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
658 return sys_truncate(l, uap, retval);
659 }
660