freebsd_file.c revision 1.8
1/* $NetBSD: freebsd_file.c,v 1.8 1997/10/18 16:30:25 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_lchown(p, v, retval) 264 struct proc *p; 265 void *v; 266 register_t *retval; 267{ 268 struct freebsd_sys_lchown_args /* { 269 syscallarg(char *) path; 270 syscallarg(int) uid; 271 syscallarg(int) gid; 272 } */ *uap = v; 273 caddr_t sg = stackgap_init(p->p_emul); 274 275 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 276 return sys_lchown(p, uap, retval); 277} 278 279int 280freebsd_sys_unmount(p, v, retval) 281 struct proc *p; 282 void *v; 283 register_t *retval; 284{ 285 struct freebsd_sys_unmount_args /* { 286 syscallarg(char *) path; 287 syscallarg(int) flags; 288 } */ *uap = v; 289 caddr_t sg = stackgap_init(p->p_emul); 290 291 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 292 return sys_unmount(p, uap, retval); 293} 294 295int 296freebsd_sys_access(p, v, retval) 297 struct proc *p; 298 void *v; 299 register_t *retval; 300{ 301 struct freebsd_sys_access_args /* { 302 syscallarg(char *) path; 303 syscallarg(int) flags; 304 } */ *uap = v; 305 caddr_t sg = stackgap_init(p->p_emul); 306 307 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 308 return sys_access(p, uap, retval); 309} 310 311int 312freebsd_sys_chflags(p, v, retval) 313 struct proc *p; 314 void *v; 315 register_t *retval; 316{ 317 struct freebsd_sys_chflags_args /* { 318 syscallarg(char *) path; 319 syscallarg(int) flags; 320 } */ *uap = v; 321 caddr_t sg = stackgap_init(p->p_emul); 322 323 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 324 return sys_chflags(p, uap, retval); 325} 326 327int 328compat_43_freebsd_sys_stat(p, v, retval) 329 struct proc *p; 330 void *v; 331 register_t *retval; 332{ 333 struct compat_43_freebsd_sys_stat_args /* { 334 syscallarg(char *) path; 335 syscallarg(struct stat43 *) ub; 336 } */ *uap = v; 337 caddr_t sg = stackgap_init(p->p_emul); 338 339 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 340 return compat_43_sys_stat(p, uap, retval); 341} 342 343int 344compat_43_freebsd_sys_lstat(p, v, retval) 345 struct proc *p; 346 void *v; 347 register_t *retval; 348{ 349 struct compat_43_freebsd_sys_lstat_args /* { 350 syscallarg(char *) path; 351 syscallarg(struct stat43 *) ub; 352 } */ *uap = v; 353 caddr_t sg = stackgap_init(p->p_emul); 354 355 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 356 return compat_43_sys_lstat(p, uap, retval); 357} 358 359int 360freebsd_sys_revoke(p, v, retval) 361 struct proc *p; 362 void *v; 363 register_t *retval; 364{ 365 struct freebsd_sys_revoke_args /* { 366 syscallarg(char *) path; 367 } */ *uap = v; 368 caddr_t sg = stackgap_init(p->p_emul); 369 370 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 371 return sys_revoke(p, uap, retval); 372} 373 374int 375freebsd_sys_symlink(p, v, retval) 376 struct proc *p; 377 void *v; 378 register_t *retval; 379{ 380 struct freebsd_sys_symlink_args /* { 381 syscallarg(char *) path; 382 syscallarg(char *) link; 383 } */ *uap = v; 384 caddr_t sg = stackgap_init(p->p_emul); 385 386 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 387 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link)); 388 return sys_symlink(p, uap, retval); 389} 390 391int 392freebsd_sys_readlink(p, v, retval) 393 struct proc *p; 394 void *v; 395 register_t *retval; 396{ 397 struct freebsd_sys_readlink_args /* { 398 syscallarg(char *) path; 399 syscallarg(char *) buf; 400 syscallarg(int) count; 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_readlink(p, uap, retval); 406} 407 408int 409freebsd_sys_execve(p, v, retval) 410 struct proc *p; 411 void *v; 412 register_t *retval; 413{ 414 struct freebsd_sys_execve_args /* { 415 syscallarg(char *) path; 416 syscallarg(char **) argp; 417 syscallarg(char **) envp; 418 } */ *uap = v; 419 struct sys_execve_args ap; 420 caddr_t sg; 421 422 sg = stackgap_init(p->p_emul); 423 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 424 425 SCARG(&ap, path) = SCARG(uap, path); 426 SCARG(&ap, argp) = SCARG(uap, argp); 427 SCARG(&ap, envp) = SCARG(uap, envp); 428 429 return sys_execve(p, &ap, retval); 430} 431 432int 433freebsd_sys_chroot(p, v, retval) 434 struct proc *p; 435 void *v; 436 register_t *retval; 437{ 438 struct freebsd_sys_chroot_args /* { 439 syscallarg(char *) path; 440 } */ *uap = v; 441 caddr_t sg = stackgap_init(p->p_emul); 442 443 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 444 return sys_chroot(p, uap, retval); 445} 446 447int 448freebsd_sys_rename(p, v, retval) 449 struct proc *p; 450 void *v; 451 register_t *retval; 452{ 453 struct freebsd_sys_rename_args /* { 454 syscallarg(char *) from; 455 syscallarg(char *) to; 456 } */ *uap = v; 457 caddr_t sg = stackgap_init(p->p_emul); 458 459 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from)); 460 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to)); 461 return sys_rename(p, uap, retval); 462} 463 464int 465compat_43_freebsd_sys_truncate(p, v, retval) 466 struct proc *p; 467 void *v; 468 register_t *retval; 469{ 470 struct compat_43_freebsd_sys_truncate_args /* { 471 syscallarg(char *) path; 472 syscallarg(long) length; 473 } */ *uap = v; 474 caddr_t sg = stackgap_init(p->p_emul); 475 476 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 477 return compat_43_sys_truncate(p, uap, retval); 478} 479 480int 481freebsd_sys_mkfifo(p, v, retval) 482 struct proc *p; 483 void *v; 484 register_t *retval; 485{ 486 struct freebsd_sys_mkfifo_args /* { 487 syscallarg(char *) path; 488 syscallarg(int) mode; 489 } */ *uap = v; 490 caddr_t sg = stackgap_init(p->p_emul); 491 492 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 493 return sys_mkfifo(p, uap, retval); 494} 495 496int 497freebsd_sys_mkdir(p, v, retval) 498 struct proc *p; 499 void *v; 500 register_t *retval; 501{ 502 struct freebsd_sys_mkdir_args /* { 503 syscallarg(char *) path; 504 syscallarg(int) mode; 505 } */ *uap = v; 506 caddr_t sg = stackgap_init(p->p_emul); 507 508 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 509 return sys_mkdir(p, uap, retval); 510} 511 512int 513freebsd_sys_rmdir(p, v, retval) 514 struct proc *p; 515 void *v; 516 register_t *retval; 517{ 518 struct freebsd_sys_rmdir_args /* { 519 syscallarg(char *) path; 520 } */ *uap = v; 521 caddr_t sg = stackgap_init(p->p_emul); 522 523 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 524 return sys_rmdir(p, uap, retval); 525} 526 527int 528freebsd_sys_statfs(p, v, retval) 529 struct proc *p; 530 void *v; 531 register_t *retval; 532{ 533 struct freebsd_sys_stat_args /* { 534 syscallarg(char *) path; 535 syscallarg(struct statfs *) buf; 536 } */ *uap = v; 537 caddr_t sg = stackgap_init(p->p_emul); 538 539 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 540 return sys_statfs(p, uap, retval); 541} 542 543#ifdef NFS 544int 545freebsd_sys_getfh(p, v, retval) 546 struct proc *p; 547 void *v; 548 register_t *retval; 549{ 550 struct freebsd_sys_getfh_args /* { 551 syscallarg(char *) fname; 552 syscallarg(fhandle_t *) fhp; 553 } */ *uap = v; 554 caddr_t sg = stackgap_init(p->p_emul); 555 556 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname)); 557 return sys_getfh(p, uap, retval); 558} 559#endif /* NFS */ 560 561int 562freebsd_sys_stat(p, v, retval) 563 struct proc *p; 564 void *v; 565 register_t *retval; 566{ 567 struct freebsd_sys_stat_args /* { 568 syscallarg(char *) path; 569 syscallarg(struct stat12 *) ub; 570 } */ *uap = v; 571 caddr_t sg = stackgap_init(p->p_emul); 572 573 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 574 return compat_12_sys_stat(p, uap, retval); 575} 576 577int 578freebsd_sys_lstat(p, v, retval) 579 struct proc *p; 580 void *v; 581 register_t *retval; 582{ 583 struct freebsd_sys_lstat_args /* { 584 syscallarg(char *) path; 585 syscallarg(struct stat12 *) ub; 586 } */ *uap = v; 587 caddr_t sg = stackgap_init(p->p_emul); 588 589 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 590 return compat_12_sys_lstat(p, uap, retval); 591} 592 593int 594freebsd_sys_pathconf(p, v, retval) 595 struct proc *p; 596 void *v; 597 register_t *retval; 598{ 599 struct freebsd_sys_pathconf_args /* { 600 syscallarg(char *) path; 601 syscallarg(int) name; 602 } */ *uap = v; 603 caddr_t sg = stackgap_init(p->p_emul); 604 605 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 606 return sys_pathconf(p, uap, retval); 607} 608 609int 610freebsd_sys_truncate(p, v, retval) 611 struct proc *p; 612 void *v; 613 register_t *retval; 614{ 615 struct freebsd_sys_truncate_args /* { 616 syscallarg(char *) path; 617 syscallarg(int) pad; 618 syscallarg(off_t) length; 619 } */ *uap = v; 620 caddr_t sg = stackgap_init(p->p_emul); 621 622 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 623 return sys_truncate(p, uap, retval); 624} 625