freebsd_file.c revision 1.3
1/* $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos 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 * convert_from_freebsd_mount_type __P((int)); 58 59static char * 60convert_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 91int 92freebsd_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 129int 130freebsd_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 149int 150compat_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 165int 166freebsd_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 182int 183freebsd_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 197int 198freebsd_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 212int 213freebsd_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 229int 230freebsd_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 245int 246freebsd_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 262int 263freebsd_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 278int 279freebsd_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 294int 295freebsd_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 310int 311compat_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 326int 327compat_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 342int 343freebsd_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 357int 358freebsd_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 374int 375freebsd_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 391int 392freebsd_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 caddr_t sg = stackgap_init(p->p_emul); 403 404 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 405 return sys_execve(p, uap, retval); 406} 407 408int 409freebsd_sys_chroot(p, v, retval) 410 struct proc *p; 411 void *v; 412 register_t *retval; 413{ 414 struct freebsd_sys_chroot_args /* { 415 syscallarg(char *) path; 416 } */ *uap = v; 417 caddr_t sg = stackgap_init(p->p_emul); 418 419 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 420 return sys_chroot(p, uap, retval); 421} 422 423int 424freebsd_sys_rename(p, v, retval) 425 struct proc *p; 426 void *v; 427 register_t *retval; 428{ 429 struct freebsd_sys_rename_args /* { 430 syscallarg(char *) from; 431 syscallarg(char *) to; 432 } */ *uap = v; 433 caddr_t sg = stackgap_init(p->p_emul); 434 435 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from)); 436 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to)); 437 return sys_rename(p, uap, retval); 438} 439 440int 441compat_43_freebsd_sys_truncate(p, v, retval) 442 struct proc *p; 443 void *v; 444 register_t *retval; 445{ 446 struct compat_43_freebsd_sys_truncate_args /* { 447 syscallarg(char *) path; 448 syscallarg(long) length; 449 } */ *uap = v; 450 caddr_t sg = stackgap_init(p->p_emul); 451 452 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 453 return compat_43_sys_truncate(p, uap, retval); 454} 455 456int 457freebsd_sys_mkfifo(p, v, retval) 458 struct proc *p; 459 void *v; 460 register_t *retval; 461{ 462 struct freebsd_sys_mkfifo_args /* { 463 syscallarg(char *) path; 464 syscallarg(int) mode; 465 } */ *uap = v; 466 caddr_t sg = stackgap_init(p->p_emul); 467 468 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 469 return sys_mkfifo(p, uap, retval); 470} 471 472int 473freebsd_sys_mkdir(p, v, retval) 474 struct proc *p; 475 void *v; 476 register_t *retval; 477{ 478 struct freebsd_sys_mkdir_args /* { 479 syscallarg(char *) path; 480 syscallarg(int) mode; 481 } */ *uap = v; 482 caddr_t sg = stackgap_init(p->p_emul); 483 484 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 485 return sys_mkdir(p, uap, retval); 486} 487 488int 489freebsd_sys_rmdir(p, v, retval) 490 struct proc *p; 491 void *v; 492 register_t *retval; 493{ 494 struct freebsd_sys_rmdir_args /* { 495 syscallarg(char *) path; 496 } */ *uap = v; 497 caddr_t sg = stackgap_init(p->p_emul); 498 499 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 500 return sys_rmdir(p, uap, retval); 501} 502 503int 504freebsd_sys_statfs(p, v, retval) 505 struct proc *p; 506 void *v; 507 register_t *retval; 508{ 509 struct freebsd_sys_stat_args /* { 510 syscallarg(char *) path; 511 syscallarg(struct statfs *) buf; 512 } */ *uap = v; 513 caddr_t sg = stackgap_init(p->p_emul); 514 515 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 516 return sys_statfs(p, uap, retval); 517} 518 519#ifdef NFSCLIENT 520int 521freebsd_sys_getfh(p, v, retval) 522 struct proc *p; 523 void *v; 524 register_t *retval; 525{ 526 struct freebsd_sys_getfh_args /* { 527 syscallarg(char *) fname; 528 syscallarg(fhandle_t *) fhp; 529 } */ *uap = v; 530 caddr_t sg = stackgap_init(p->p_emul); 531 532 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname)); 533 return sys_getfh(p, uap, retval); 534} 535#endif /* NFSCLIENT */ 536 537int 538freebsd_sys_stat(p, v, retval) 539 struct proc *p; 540 void *v; 541 register_t *retval; 542{ 543 struct freebsd_sys_stat_args /* { 544 syscallarg(char *) path; 545 syscallarg(struct stat *) ub; 546 } */ *uap = v; 547 caddr_t sg = stackgap_init(p->p_emul); 548 549 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 550 return sys_stat(p, uap, retval); 551} 552 553int 554freebsd_sys_lstat(p, v, retval) 555 struct proc *p; 556 void *v; 557 register_t *retval; 558{ 559 struct freebsd_sys_lstat_args /* { 560 syscallarg(char *) path; 561 syscallarg(struct stat *) ub; 562 } */ *uap = v; 563 caddr_t sg = stackgap_init(p->p_emul); 564 565 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 566 return sys_lstat(p, uap, retval); 567} 568 569int 570freebsd_sys_pathconf(p, v, retval) 571 struct proc *p; 572 void *v; 573 register_t *retval; 574{ 575 struct freebsd_sys_pathconf_args /* { 576 syscallarg(char *) path; 577 syscallarg(int) name; 578 } */ *uap = v; 579 caddr_t sg = stackgap_init(p->p_emul); 580 581 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 582 return sys_pathconf(p, uap, retval); 583} 584 585int 586freebsd_sys_truncate(p, v, retval) 587 struct proc *p; 588 void *v; 589 register_t *retval; 590{ 591 struct freebsd_sys_truncate_args /* { 592 syscallarg(char *) path; 593 syscallarg(int) pad; 594 syscallarg(off_t) length; 595 } */ *uap = v; 596 caddr_t sg = stackgap_init(p->p_emul); 597 598 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 599 return sys_truncate(p, uap, retval); 600} 601