freebsd_file.c revision 1.9.14.1 1 /* $NetBSD: freebsd_file.c,v 1.9.14.1 2000/12/08 09:08:11 bouyer 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) && !defined(_LKM)
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/proc.h>
44 #include <sys/file.h>
45 #include <sys/stat.h>
46 #include <sys/filedesc.h>
47 #include <sys/ioctl.h>
48 #include <sys/kernel.h>
49 #include <sys/mount.h>
50 #include <sys/malloc.h>
51
52 #include <sys/syscallargs.h>
53
54 #include <compat/freebsd/freebsd_syscallargs.h>
55 #include <compat/common/compat_util.h>
56
57 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
58
59 static char * convert_from_freebsd_mount_type __P((int));
60
61 static char *
62 convert_from_freebsd_mount_type(type)
63 int type;
64 {
65 static char *netbsd_mount_type[] = {
66 NULL, /* 0 = MOUNT_NONE */
67 "ffs", /* 1 = "Fast" Filesystem */
68 "nfs", /* 2 = Network Filesystem */
69 "mfs", /* 3 = Memory Filesystem */
70 "msdos", /* 4 = MSDOS Filesystem */
71 "lfs", /* 5 = Log-based Filesystem */
72 "lofs", /* 6 = Loopback filesystem */
73 "fdesc", /* 7 = File Descriptor Filesystem */
74 "portal", /* 8 = Portal Filesystem */
75 "null", /* 9 = Minimal Filesystem Layer */
76 "umap", /* 10 = User/Group Identifier Remapping Filesystem */
77 "kernfs", /* 11 = Kernel Information Filesystem */
78 "procfs", /* 12 = /proc Filesystem */
79 "afs", /* 13 = Andrew Filesystem */
80 "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
81 "union", /* 15 = Union (translucent) Filesystem */
82 NULL, /* 16 = "devfs" - existing device Filesystem */
83 #if 0 /* These filesystems don't exist in FreeBSD */
84 "adosfs", /* ?? = AmigaDOS Filesystem */
85 #endif
86 };
87
88 if (type < 0 || type >= ARRAY_LENGTH(netbsd_mount_type))
89 return (NULL);
90 return (netbsd_mount_type[type]);
91 }
92
93 int
94 freebsd_sys_mount(p, v, retval)
95 struct proc *p;
96 void *v;
97 register_t *retval;
98 {
99 struct freebsd_sys_mount_args /* {
100 syscallarg(int) type;
101 syscallarg(char *) path;
102 syscallarg(int) flags;
103 syscallarg(caddr_t) data;
104 } */ *uap = v;
105 int error;
106 char *type, *s;
107 caddr_t sg = stackgap_init(p->p_emul);
108 struct sys_mount_args bma;
109
110 if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
111 return ENODEV;
112 s = stackgap_alloc(&sg, MFSNAMELEN + 1);
113 if ((error = copyout(type, s, strlen(type) + 1)) != 0)
114 return error;
115 SCARG(&bma, type) = s;
116 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
117 SCARG(&bma, path) = SCARG(uap, path);
118 SCARG(&bma, flags) = SCARG(uap, flags);
119 SCARG(&bma, data) = SCARG(uap, data);
120 return sys_mount(p, &bma, retval);
121 }
122
123 /*
124 * The following syscalls are only here because of the alternate path check.
125 */
126
127 /* XXX - UNIX domain: int freebsd_sys_bind(int s, caddr_t name, int namelen); */
128 /* XXX - UNIX domain: int freebsd_sys_connect(int s, caddr_t name, int namelen); */
129
130
131 int
132 freebsd_sys_open(p, v, retval)
133 struct proc *p;
134 void *v;
135 register_t *retval;
136 {
137 struct freebsd_sys_open_args /* {
138 syscallarg(char *) path;
139 syscallarg(int) flags;
140 syscallarg(int) mode;
141 } */ *uap = v;
142 caddr_t sg = stackgap_init(p->p_emul);
143
144 if (SCARG(uap, flags) & O_CREAT)
145 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
146 else
147 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
148 return sys_open(p, uap, retval);
149 }
150
151 int
152 compat_43_freebsd_sys_creat(p, v, retval)
153 struct proc *p;
154 void *v;
155 register_t *retval;
156 {
157 struct compat_43_freebsd_sys_creat_args /* {
158 syscallarg(char *) path;
159 syscallarg(int) mode;
160 } */ *uap = v;
161 caddr_t sg = stackgap_init(p->p_emul);
162
163 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
164 return compat_43_sys_creat(p, uap, retval);
165 }
166
167 int
168 freebsd_sys_link(p, v, retval)
169 struct proc *p;
170 void *v;
171 register_t *retval;
172 {
173 struct freebsd_sys_link_args /* {
174 syscallarg(char *) path;
175 syscallarg(char *) link;
176 } */ *uap = v;
177 caddr_t sg = stackgap_init(p->p_emul);
178
179 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
180 CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
181 return sys_link(p, uap, retval);
182 }
183
184 int
185 freebsd_sys_unlink(p, v, retval)
186 struct proc *p;
187 void *v;
188 register_t *retval;
189 {
190 struct freebsd_sys_unlink_args /* {
191 syscallarg(char *) path;
192 } */ *uap = v;
193 caddr_t sg = stackgap_init(p->p_emul);
194
195 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
196 return sys_unlink(p, uap, retval);
197 }
198
199 int
200 freebsd_sys_chdir(p, v, retval)
201 struct proc *p;
202 void *v;
203 register_t *retval;
204 {
205 struct freebsd_sys_chdir_args /* {
206 syscallarg(char *) path;
207 } */ *uap = v;
208 caddr_t sg = stackgap_init(p->p_emul);
209
210 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
211 return sys_chdir(p, uap, retval);
212 }
213
214 int
215 freebsd_sys_mknod(p, v, retval)
216 struct proc *p;
217 void *v;
218 register_t *retval;
219 {
220 struct freebsd_sys_mknod_args /* {
221 syscallarg(char *) path;
222 syscallarg(int) mode;
223 syscallarg(int) dev;
224 } */ *uap = v;
225 caddr_t sg = stackgap_init(p->p_emul);
226
227 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
228 return sys_mknod(p, uap, retval);
229 }
230
231 int
232 freebsd_sys_chmod(p, v, retval)
233 struct proc *p;
234 void *v;
235 register_t *retval;
236 {
237 struct freebsd_sys_chmod_args /* {
238 syscallarg(char *) path;
239 syscallarg(int) mode;
240 } */ *uap = v;
241 caddr_t sg = stackgap_init(p->p_emul);
242
243 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
244 return sys_chmod(p, uap, retval);
245 }
246
247 int
248 freebsd_sys_chown(p, v, retval)
249 struct proc *p;
250 void *v;
251 register_t *retval;
252 {
253 struct freebsd_sys_chown_args /* {
254 syscallarg(char *) path;
255 syscallarg(int) uid;
256 syscallarg(int) gid;
257 } */ *uap = v;
258 caddr_t sg = stackgap_init(p->p_emul);
259
260 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
261 return sys_chown(p, uap, retval);
262 }
263
264 int
265 freebsd_sys_lchown(p, v, retval)
266 struct proc *p;
267 void *v;
268 register_t *retval;
269 {
270 struct freebsd_sys_lchown_args /* {
271 syscallarg(char *) path;
272 syscallarg(int) uid;
273 syscallarg(int) gid;
274 } */ *uap = v;
275 caddr_t sg = stackgap_init(p->p_emul);
276
277 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
278 return sys_lchown(p, uap, retval);
279 }
280
281 int
282 freebsd_sys_unmount(p, v, retval)
283 struct proc *p;
284 void *v;
285 register_t *retval;
286 {
287 struct freebsd_sys_unmount_args /* {
288 syscallarg(char *) path;
289 syscallarg(int) flags;
290 } */ *uap = v;
291 caddr_t sg = stackgap_init(p->p_emul);
292
293 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
294 return sys_unmount(p, uap, retval);
295 }
296
297 int
298 freebsd_sys_access(p, v, retval)
299 struct proc *p;
300 void *v;
301 register_t *retval;
302 {
303 struct freebsd_sys_access_args /* {
304 syscallarg(char *) path;
305 syscallarg(int) flags;
306 } */ *uap = v;
307 caddr_t sg = stackgap_init(p->p_emul);
308
309 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
310 return sys_access(p, uap, retval);
311 }
312
313 int
314 freebsd_sys_chflags(p, v, retval)
315 struct proc *p;
316 void *v;
317 register_t *retval;
318 {
319 struct freebsd_sys_chflags_args /* {
320 syscallarg(char *) path;
321 syscallarg(int) flags;
322 } */ *uap = v;
323 caddr_t sg = stackgap_init(p->p_emul);
324
325 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
326 return sys_chflags(p, uap, retval);
327 }
328
329 int
330 compat_43_freebsd_sys_stat(p, v, retval)
331 struct proc *p;
332 void *v;
333 register_t *retval;
334 {
335 struct compat_43_freebsd_sys_stat_args /* {
336 syscallarg(char *) path;
337 syscallarg(struct stat43 *) ub;
338 } */ *uap = v;
339 caddr_t sg = stackgap_init(p->p_emul);
340
341 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
342 return compat_43_sys_stat(p, uap, retval);
343 }
344
345 int
346 compat_43_freebsd_sys_lstat(p, v, retval)
347 struct proc *p;
348 void *v;
349 register_t *retval;
350 {
351 struct compat_43_freebsd_sys_lstat_args /* {
352 syscallarg(char *) path;
353 syscallarg(struct stat43 *) ub;
354 } */ *uap = v;
355 caddr_t sg = stackgap_init(p->p_emul);
356
357 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
358 return compat_43_sys_lstat(p, uap, retval);
359 }
360
361 int
362 freebsd_sys_revoke(p, v, retval)
363 struct proc *p;
364 void *v;
365 register_t *retval;
366 {
367 struct freebsd_sys_revoke_args /* {
368 syscallarg(char *) path;
369 } */ *uap = v;
370 caddr_t sg = stackgap_init(p->p_emul);
371
372 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
373 return sys_revoke(p, uap, retval);
374 }
375
376 int
377 freebsd_sys_symlink(p, v, retval)
378 struct proc *p;
379 void *v;
380 register_t *retval;
381 {
382 struct freebsd_sys_symlink_args /* {
383 syscallarg(char *) path;
384 syscallarg(char *) link;
385 } */ *uap = v;
386 caddr_t sg = stackgap_init(p->p_emul);
387
388 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
389 CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
390 return sys_symlink(p, uap, retval);
391 }
392
393 int
394 freebsd_sys_readlink(p, v, retval)
395 struct proc *p;
396 void *v;
397 register_t *retval;
398 {
399 struct freebsd_sys_readlink_args /* {
400 syscallarg(char *) path;
401 syscallarg(char *) buf;
402 syscallarg(int) count;
403 } */ *uap = v;
404 caddr_t sg = stackgap_init(p->p_emul);
405
406 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
407 return sys_readlink(p, uap, retval);
408 }
409
410 int
411 freebsd_sys_execve(p, v, retval)
412 struct proc *p;
413 void *v;
414 register_t *retval;
415 {
416 struct freebsd_sys_execve_args /* {
417 syscallarg(char *) path;
418 syscallarg(char **) argp;
419 syscallarg(char **) envp;
420 } */ *uap = v;
421 struct sys_execve_args ap;
422 caddr_t sg;
423
424 sg = stackgap_init(p->p_emul);
425 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
426
427 SCARG(&ap, path) = SCARG(uap, path);
428 SCARG(&ap, argp) = SCARG(uap, argp);
429 SCARG(&ap, envp) = SCARG(uap, envp);
430
431 return sys_execve(p, &ap, retval);
432 }
433
434 int
435 freebsd_sys_chroot(p, v, retval)
436 struct proc *p;
437 void *v;
438 register_t *retval;
439 {
440 struct freebsd_sys_chroot_args /* {
441 syscallarg(char *) path;
442 } */ *uap = v;
443 caddr_t sg = stackgap_init(p->p_emul);
444
445 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
446 return sys_chroot(p, uap, retval);
447 }
448
449 int
450 freebsd_sys_rename(p, v, retval)
451 struct proc *p;
452 void *v;
453 register_t *retval;
454 {
455 struct freebsd_sys_rename_args /* {
456 syscallarg(char *) from;
457 syscallarg(char *) to;
458 } */ *uap = v;
459 caddr_t sg = stackgap_init(p->p_emul);
460
461 CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
462 CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
463 return sys_rename(p, uap, retval);
464 }
465
466 int
467 compat_43_freebsd_sys_truncate(p, v, retval)
468 struct proc *p;
469 void *v;
470 register_t *retval;
471 {
472 struct compat_43_freebsd_sys_truncate_args /* {
473 syscallarg(char *) path;
474 syscallarg(long) length;
475 } */ *uap = v;
476 caddr_t sg = stackgap_init(p->p_emul);
477
478 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
479 return compat_43_sys_truncate(p, uap, retval);
480 }
481
482 int
483 freebsd_sys_mkfifo(p, v, retval)
484 struct proc *p;
485 void *v;
486 register_t *retval;
487 {
488 struct freebsd_sys_mkfifo_args /* {
489 syscallarg(char *) path;
490 syscallarg(int) mode;
491 } */ *uap = v;
492 caddr_t sg = stackgap_init(p->p_emul);
493
494 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
495 return sys_mkfifo(p, uap, retval);
496 }
497
498 int
499 freebsd_sys_mkdir(p, v, retval)
500 struct proc *p;
501 void *v;
502 register_t *retval;
503 {
504 struct freebsd_sys_mkdir_args /* {
505 syscallarg(char *) path;
506 syscallarg(int) mode;
507 } */ *uap = v;
508 caddr_t sg = stackgap_init(p->p_emul);
509
510 CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
511 return sys_mkdir(p, uap, retval);
512 }
513
514 int
515 freebsd_sys_rmdir(p, v, retval)
516 struct proc *p;
517 void *v;
518 register_t *retval;
519 {
520 struct freebsd_sys_rmdir_args /* {
521 syscallarg(char *) path;
522 } */ *uap = v;
523 caddr_t sg = stackgap_init(p->p_emul);
524
525 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
526 return sys_rmdir(p, uap, retval);
527 }
528
529 int
530 freebsd_sys_statfs(p, v, retval)
531 struct proc *p;
532 void *v;
533 register_t *retval;
534 {
535 struct freebsd_sys_stat_args /* {
536 syscallarg(char *) path;
537 syscallarg(struct statfs *) buf;
538 } */ *uap = v;
539 caddr_t sg = stackgap_init(p->p_emul);
540
541 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
542 return sys_statfs(p, uap, retval);
543 }
544
545 #ifdef NFS
546 int
547 freebsd_sys_getfh(p, v, retval)
548 struct proc *p;
549 void *v;
550 register_t *retval;
551 {
552 struct freebsd_sys_getfh_args /* {
553 syscallarg(char *) fname;
554 syscallarg(fhandle_t *) fhp;
555 } */ *uap = v;
556 caddr_t sg = stackgap_init(p->p_emul);
557
558 CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
559 return sys_getfh(p, uap, retval);
560 }
561 #endif /* NFS */
562
563 int
564 freebsd_sys_stat(p, v, retval)
565 struct proc *p;
566 void *v;
567 register_t *retval;
568 {
569 struct freebsd_sys_stat_args /* {
570 syscallarg(char *) path;
571 syscallarg(struct stat12 *) ub;
572 } */ *uap = v;
573 caddr_t sg = stackgap_init(p->p_emul);
574
575 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
576 return compat_12_sys_stat(p, uap, retval);
577 }
578
579 int
580 freebsd_sys_lstat(p, v, retval)
581 struct proc *p;
582 void *v;
583 register_t *retval;
584 {
585 struct freebsd_sys_lstat_args /* {
586 syscallarg(char *) path;
587 syscallarg(struct stat12 *) ub;
588 } */ *uap = v;
589 caddr_t sg = stackgap_init(p->p_emul);
590
591 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
592 return compat_12_sys_lstat(p, uap, retval);
593 }
594
595 int
596 freebsd_sys_pathconf(p, v, retval)
597 struct proc *p;
598 void *v;
599 register_t *retval;
600 {
601 struct freebsd_sys_pathconf_args /* {
602 syscallarg(char *) path;
603 syscallarg(int) name;
604 } */ *uap = v;
605 caddr_t sg = stackgap_init(p->p_emul);
606
607 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
608 return sys_pathconf(p, uap, retval);
609 }
610
611 int
612 freebsd_sys_truncate(p, v, retval)
613 struct proc *p;
614 void *v;
615 register_t *retval;
616 {
617 struct freebsd_sys_truncate_args /* {
618 syscallarg(char *) path;
619 syscallarg(int) pad;
620 syscallarg(off_t) length;
621 } */ *uap = v;
622 caddr_t sg = stackgap_init(p->p_emul);
623
624 CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
625 return sys_truncate(p, uap, retval);
626 }
627