freebsd_file.c revision 1.9
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 57const char freebsd_emul_path[] = "/emul/freebsd"; 58 59static char * convert_from_freebsd_mount_type __P((int)); 60 61static char * 62convert_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 93int 94freebsd_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 131int 132freebsd_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 151int 152compat_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 167int 168freebsd_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 184int 185freebsd_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 199int 200freebsd_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 214int 215freebsd_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 231int 232freebsd_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 247int 248freebsd_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 264int 265freebsd_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 281int 282freebsd_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 297int 298freebsd_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 313int 314freebsd_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 329int 330compat_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 345int 346compat_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 361int 362freebsd_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 376int 377freebsd_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 393int 394freebsd_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 410int 411freebsd_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 434int 435freebsd_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 449int 450freebsd_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 466int 467compat_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 482int 483freebsd_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 498int 499freebsd_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 514int 515freebsd_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 529int 530freebsd_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 546int 547freebsd_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 563int 564freebsd_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 579int 580freebsd_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 595int 596freebsd_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 611int 612freebsd_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