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