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