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