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