freebsd_file.c revision 1.1
1/* $NetBSD: freebsd_file.c,v 1.1 1995/10/10 01:19:30 mycroft 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 * 58convert_from_freebsd_mount_type(type) 59 int type; 60{ 61 static char *netbsd_mount_type[] = { 62 NULL, /* 0 = MOUNT_NONE */ 63 "ufs", /* 1 = UNIX "Fast" Filesystem */ 64 "nfs", /* 2 = Network Filesystem */ 65 "mfs", /* 3 = Memory Filesystem */ 66 "msdos", /* 4 = MSDOS Filesystem */ 67 "lfs", /* 5 = Log-based Filesystem */ 68 "lofs", /* 6 = Loopback filesystem */ 69 "fdesc", /* 7 = File Descriptor Filesystem */ 70 "portal", /* 8 = Portal Filesystem */ 71 "null", /* 9 = Minimal Filesystem Layer */ 72 "umap", /* 10 = User/Group Identifier Remapping Filesystem */ 73 "kernfs", /* 11 = Kernel Information Filesystem */ 74 "procfs", /* 12 = /proc Filesystem */ 75 "afs", /* 13 = Andrew Filesystem */ 76 "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */ 77 "union", /* 15 = Union (translucent) Filesystem */ 78 NULL, /* 16 = "devfs" - existing device Filesystem */ 79#if 0 /* These filesystems don't exist in FreeBSD */ 80 "adosfs", /* ?? = AmigaDOS Filesystem */ 81#endif 82 }; 83 84 if (type < 0 || type >= ARRAY_LENGTH(netbsd_mount_type)) 85 return (NULL); 86 return (netbsd_mount_type[type]); 87} 88 89int 90freebsd_sys_mount(p, v, retval) 91 struct proc *p; 92 void *v; 93 register_t *retval; 94{ 95 struct freebsd_sys_mount_args /* { 96 syscallarg(int) type; 97 syscallarg(char *) path; 98 syscallarg(int) flags; 99 syscallarg(caddr_t) data; 100 } */ *uap = v; 101 int error; 102 char *type, *s; 103 caddr_t sg = stackgap_init(p->p_emul); 104 struct sys_mount_args bma; 105 106 if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL) 107 return ENODEV; 108 s = stackgap_alloc(&sg, MFSNAMELEN + 1); 109 if (error = copyout(type, s, strlen(type) + 1)) 110 return error; 111 SCARG(&bma, type) = s; 112 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 113 SCARG(&bma, path) = SCARG(uap, path); 114 SCARG(&bma, flags) = SCARG(uap, flags); 115 SCARG(&bma, data) = SCARG(uap, data); 116 return sys_mount(p, &bma, retval); 117} 118 119/* 120 * The following syscalls are only here because of the alternate path check. 121 */ 122 123/* XXX - UNIX domain: int freebsd_sys_bind(int s, caddr_t name, int namelen); */ 124/* XXX - UNIX domain: int freebsd_sys_connect(int s, caddr_t name, int namelen); */ 125 126 127int 128freebsd_sys_open(p, v, retval) 129 struct proc *p; 130 void *v; 131 register_t *retval; 132{ 133 struct freebsd_sys_open_args /* { 134 syscallarg(char *) path; 135 syscallarg(int) flags; 136 syscallarg(int) mode; 137 } */ *uap = v; 138 caddr_t sg = stackgap_init(p->p_emul); 139 140 if (SCARG(uap, flags) & O_CREAT) 141 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 142 else 143 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 144 return sys_open(p, uap, retval); 145} 146 147int 148compat_43_freebsd_sys_creat(p, v, retval) 149 struct proc *p; 150 void *v; 151 register_t *retval; 152{ 153 struct compat_43_freebsd_sys_creat_args /* { 154 syscallarg(char *) path; 155 syscallarg(int) mode; 156 } */ *uap = v; 157 caddr_t sg = stackgap_init(p->p_emul); 158 159 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 160 return compat_43_sys_creat(p, uap, retval); 161} 162 163int 164freebsd_sys_link(p, v, retval) 165 struct proc *p; 166 void *v; 167 register_t *retval; 168{ 169 struct freebsd_sys_link_args /* { 170 syscallarg(char *) path; 171 syscallarg(char *) link; 172 } */ *uap = v; 173 caddr_t sg = stackgap_init(p->p_emul); 174 175 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 176 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link)); 177 return sys_link(p, uap, retval); 178} 179 180int 181freebsd_sys_unlink(p, v, retval) 182 struct proc *p; 183 void *v; 184 register_t *retval; 185{ 186 struct freebsd_sys_unlink_args /* { 187 syscallarg(char *) path; 188 } */ *uap = v; 189 caddr_t sg = stackgap_init(p->p_emul); 190 191 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 192 return sys_unlink(p, uap, retval); 193} 194 195int 196freebsd_sys_chdir(p, v, retval) 197 struct proc *p; 198 void *v; 199 register_t *retval; 200{ 201 struct freebsd_sys_chdir_args /* { 202 syscallarg(char *) path; 203 } */ *uap = v; 204 caddr_t sg = stackgap_init(p->p_emul); 205 206 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 207 return sys_chdir(p, uap, retval); 208} 209 210int 211freebsd_sys_mknod(p, v, retval) 212 struct proc *p; 213 void *v; 214 register_t *retval; 215{ 216 struct freebsd_sys_mknod_args /* { 217 syscallarg(char *) path; 218 syscallarg(int) mode; 219 syscallarg(int) dev; 220 } */ *uap = v; 221 caddr_t sg = stackgap_init(p->p_emul); 222 223 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 224 return sys_mknod(p, uap, retval); 225} 226 227int 228freebsd_sys_chmod(p, v, retval) 229 struct proc *p; 230 void *v; 231 register_t *retval; 232{ 233 struct freebsd_sys_chmod_args /* { 234 syscallarg(char *) path; 235 syscallarg(int) mode; 236 } */ *uap = v; 237 caddr_t sg = stackgap_init(p->p_emul); 238 239 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 240 return sys_chmod(p, uap, retval); 241} 242 243int 244freebsd_sys_chown(p, v, retval) 245 struct proc *p; 246 void *v; 247 register_t *retval; 248{ 249 struct freebsd_sys_chown_args /* { 250 syscallarg(char *) path; 251 syscallarg(int) uid; 252 syscallarg(int) gid; 253 } */ *uap = v; 254 caddr_t sg = stackgap_init(p->p_emul); 255 256 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 257 return sys_chown(p, uap, retval); 258} 259 260int 261freebsd_sys_unmount(p, v, retval) 262 struct proc *p; 263 void *v; 264 register_t *retval; 265{ 266 struct freebsd_sys_unmount_args /* { 267 syscallarg(char *) path; 268 syscallarg(int) flags; 269 } */ *uap = v; 270 caddr_t sg = stackgap_init(p->p_emul); 271 272 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 273 return sys_unmount(p, uap, retval); 274} 275 276int 277freebsd_sys_access(p, v, retval) 278 struct proc *p; 279 void *v; 280 register_t *retval; 281{ 282 struct freebsd_sys_access_args /* { 283 syscallarg(char *) path; 284 syscallarg(int) flags; 285 } */ *uap = v; 286 caddr_t sg = stackgap_init(p->p_emul); 287 288 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 289 return sys_access(p, uap, retval); 290} 291 292int 293freebsd_sys_chflags(p, v, retval) 294 struct proc *p; 295 void *v; 296 register_t *retval; 297{ 298 struct freebsd_sys_chflags_args /* { 299 syscallarg(char *) path; 300 syscallarg(int) flags; 301 } */ *uap = v; 302 caddr_t sg = stackgap_init(p->p_emul); 303 304 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 305 return sys_chflags(p, uap, retval); 306} 307 308int 309compat_43_freebsd_sys_stat(p, v, retval) 310 struct proc *p; 311 void *v; 312 register_t *retval; 313{ 314 struct compat_43_freebsd_sys_stat_args /* { 315 syscallarg(char *) path; 316 syscallarg(struct ostat *) ub; 317 } */ *uap = v; 318 caddr_t sg = stackgap_init(p->p_emul); 319 320 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 321 return compat_43_sys_stat(p, uap, retval); 322} 323 324int 325compat_43_freebsd_sys_lstat(p, v, retval) 326 struct proc *p; 327 void *v; 328 register_t *retval; 329{ 330 struct compat_43_freebsd_sys_lstat_args /* { 331 syscallarg(char *) path; 332 syscallarg(struct ostat *) ub; 333 } */ *uap = v; 334 caddr_t sg = stackgap_init(p->p_emul); 335 336 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 337 return compat_43_sys_lstat(p, uap, retval); 338} 339 340int 341freebsd_sys_revoke(p, v, retval) 342 struct proc *p; 343 void *v; 344 register_t *retval; 345{ 346 struct freebsd_sys_revoke_args /* { 347 syscallarg(char *) path; 348 } */ *uap = v; 349 caddr_t sg = stackgap_init(p->p_emul); 350 351 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 352 return sys_revoke(p, uap, retval); 353} 354 355int 356freebsd_sys_symlink(p, v, retval) 357 struct proc *p; 358 void *v; 359 register_t *retval; 360{ 361 struct freebsd_sys_symlink_args /* { 362 syscallarg(char *) path; 363 syscallarg(char *) link; 364 } */ *uap = v; 365 caddr_t sg = stackgap_init(p->p_emul); 366 367 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 368 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link)); 369 return sys_symlink(p, uap, retval); 370} 371 372int 373freebsd_sys_readlink(p, v, retval) 374 struct proc *p; 375 void *v; 376 register_t *retval; 377{ 378 struct freebsd_sys_readlink_args /* { 379 syscallarg(char *) path; 380 syscallarg(char *) buf; 381 syscallarg(int) count; 382 } */ *uap = v; 383 caddr_t sg = stackgap_init(p->p_emul); 384 385 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 386 return sys_readlink(p, uap, retval); 387} 388 389int 390freebsd_sys_execve(p, v, retval) 391 struct proc *p; 392 void *v; 393 register_t *retval; 394{ 395 struct freebsd_sys_execve_args /* { 396 syscallarg(char *) path; 397 syscallarg(char **) argp; 398 syscallarg(char **) envp; 399 } */ *uap = v; 400 caddr_t sg = stackgap_init(p->p_emul); 401 402 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 403 return sys_execve(p, uap, retval); 404} 405 406int 407freebsd_sys_chroot(p, v, retval) 408 struct proc *p; 409 void *v; 410 register_t *retval; 411{ 412 struct freebsd_sys_chroot_args /* { 413 syscallarg(char *) path; 414 } */ *uap = v; 415 caddr_t sg = stackgap_init(p->p_emul); 416 417 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 418 return sys_chroot(p, uap, retval); 419} 420 421int 422freebsd_sys_rename(p, v, retval) 423 struct proc *p; 424 void *v; 425 register_t *retval; 426{ 427 struct freebsd_sys_rename_args /* { 428 syscallarg(char *) from; 429 syscallarg(char *) to; 430 } */ *uap = v; 431 caddr_t sg = stackgap_init(p->p_emul); 432 433 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from)); 434 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to)); 435 return sys_rename(p, uap, retval); 436} 437 438int 439compat_43_freebsd_sys_truncate(p, v, retval) 440 struct proc *p; 441 void *v; 442 register_t *retval; 443{ 444 struct compat_43_freebsd_sys_truncate_args /* { 445 syscallarg(char *) path; 446 syscallarg(long) length; 447 } */ *uap = v; 448 caddr_t sg = stackgap_init(p->p_emul); 449 450 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 451 return compat_43_sys_truncate(p, uap, retval); 452} 453 454int 455freebsd_sys_mkfifo(p, v, retval) 456 struct proc *p; 457 void *v; 458 register_t *retval; 459{ 460 struct freebsd_sys_mkfifo_args /* { 461 syscallarg(char *) path; 462 syscallarg(int) mode; 463 } */ *uap = v; 464 caddr_t sg = stackgap_init(p->p_emul); 465 466 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 467 return sys_mkfifo(p, uap, retval); 468} 469 470int 471freebsd_sys_mkdir(p, v, retval) 472 struct proc *p; 473 void *v; 474 register_t *retval; 475{ 476 struct freebsd_sys_mkdir_args /* { 477 syscallarg(char *) path; 478 syscallarg(int) mode; 479 } */ *uap = v; 480 caddr_t sg = stackgap_init(p->p_emul); 481 482 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path)); 483 return sys_mkdir(p, uap, retval); 484} 485 486int 487freebsd_sys_rmdir(p, v, retval) 488 struct proc *p; 489 void *v; 490 register_t *retval; 491{ 492 struct freebsd_sys_rmdir_args /* { 493 syscallarg(char *) path; 494 } */ *uap = v; 495 caddr_t sg = stackgap_init(p->p_emul); 496 497 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 498 return sys_rmdir(p, uap, retval); 499} 500 501int 502freebsd_sys_statfs(p, v, retval) 503 struct proc *p; 504 void *v; 505 register_t *retval; 506{ 507 struct freebsd_sys_stat_args /* { 508 syscallarg(char *) path; 509 syscallarg(struct statfs *) buf; 510 } */ *uap = v; 511 caddr_t sg = stackgap_init(p->p_emul); 512 513 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 514 return sys_statfs(p, uap, retval); 515} 516 517#ifdef NFSCLIENT 518int 519freebsd_sys_getfh(p, v, retval) 520 struct proc *p; 521 void *v; 522 register_t *retval; 523{ 524 struct freebsd_sys_getfh_args /* { 525 syscallarg(char *) fname; 526 syscallarg(fhandle_t *) fhp; 527 } */ *uap = v; 528 caddr_t sg = stackgap_init(p->p_emul); 529 530 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname)); 531 return sys_getfh(p, uap, retval); 532} 533#endif /* NFSCLIENT */ 534 535int 536freebsd_sys_stat(p, v, retval) 537 struct proc *p; 538 void *v; 539 register_t *retval; 540{ 541 struct freebsd_sys_stat_args /* { 542 syscallarg(char *) path; 543 syscallarg(struct stat *) ub; 544 } */ *uap = v; 545 caddr_t sg = stackgap_init(p->p_emul); 546 547 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 548 return sys_stat(p, uap, retval); 549} 550 551int 552freebsd_sys_lstat(p, v, retval) 553 struct proc *p; 554 void *v; 555 register_t *retval; 556{ 557 struct freebsd_sys_lstat_args /* { 558 syscallarg(char *) path; 559 syscallarg(struct stat *) ub; 560 } */ *uap = v; 561 caddr_t sg = stackgap_init(p->p_emul); 562 563 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 564 return sys_lstat(p, uap, retval); 565} 566 567int 568freebsd_sys_pathconf(p, v, retval) 569 struct proc *p; 570 void *v; 571 register_t *retval; 572{ 573 struct freebsd_sys_pathconf_args /* { 574 syscallarg(char *) path; 575 syscallarg(int) name; 576 } */ *uap = v; 577 caddr_t sg = stackgap_init(p->p_emul); 578 579 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 580 return sys_pathconf(p, uap, retval); 581} 582 583int 584freebsd_sys_truncate(p, v, retval) 585 struct proc *p; 586 void *v; 587 register_t *retval; 588{ 589 struct freebsd_sys_truncate_args /* { 590 syscallarg(char *) path; 591 syscallarg(int) pad; 592 syscallarg(off_t) length; 593 } */ *uap = v; 594 caddr_t sg = stackgap_init(p->p_emul); 595 596 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path)); 597 return sys_truncate(p, uap, retval); 598} 599