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