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