xref: /netbsd-src/sys/compat/freebsd/freebsd_file.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: freebsd_file.c,v 1.9 1998/02/19 00:36:03 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 "fs_nfs.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/namei.h>
41 #include <sys/proc.h>
42 #include <sys/file.h>
43 #include <sys/stat.h>
44 #include <sys/filedesc.h>
45 #include <sys/ioctl.h>
46 #include <sys/kernel.h>
47 #include <sys/mount.h>
48 #include <sys/malloc.h>
49 
50 #include <sys/syscallargs.h>
51 
52 #include <compat/freebsd/freebsd_syscallargs.h>
53 #include <compat/freebsd/freebsd_util.h>
54 
55 #define	ARRAY_LENGTH(array)	(sizeof(array)/sizeof(array[0]))
56 
57 const char freebsd_emul_path[] = "/emul/freebsd";
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 	FREEBSD_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 		FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
146 	else
147 		FREEBSD_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 	FREEBSD_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 	FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
180 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
389 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
462 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_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 	FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
625 	return sys_truncate(p, uap, retval);
626 }
627