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