freebsd_file.c revision 1.16
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 62static const char * convert_from_freebsd_mount_type __P((int)); 63 64static const char * 65convert_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 96int 97freebsd_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 135int 136freebsd_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 155int 156compat_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 171int 172freebsd_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 188int 189freebsd_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 203int 204freebsd_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 218int 219freebsd_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 235int 236freebsd_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 251int 252freebsd_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 268int 269freebsd_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 285int 286freebsd_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 301int 302freebsd_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 317int 318freebsd_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 333int 334compat_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 349int 350compat_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 365int 366freebsd_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 380int 381freebsd_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 397int 398freebsd_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 414int 415freebsd_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 438int 439freebsd_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 453int 454freebsd_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 470int 471compat_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 486int 487freebsd_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 502int 503freebsd_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 518int 519freebsd_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 533int 534freebsd_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 550int 551freebsd_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 567int 568freebsd_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 583int 584freebsd_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 599int 600freebsd_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 615int 616freebsd_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