1 /* 2 * file related system call shims and definitions 3 * 4 * Copyright (c) 2013 Stacey D. Son 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef BSD_FILE_H 21 #define BSD_FILE_H 22 23 #include "qemu/path.h" 24 25 #define LOCK_PATH(p, arg) \ 26 do { \ 27 (p) = lock_user_string(arg); \ 28 if ((p) == NULL) { \ 29 return -TARGET_EFAULT; \ 30 } \ 31 } while (0) 32 33 #define UNLOCK_PATH(p, arg) unlock_user(p, arg, 0) 34 35 #define LOCK_PATH2(p1, arg1, p2, arg2) \ 36 do { \ 37 (p1) = lock_user_string(arg1); \ 38 if ((p1) == NULL) { \ 39 return -TARGET_EFAULT; \ 40 } \ 41 (p2) = lock_user_string(arg2); \ 42 if ((p2) == NULL) { \ 43 unlock_user(p1, arg1, 0); \ 44 return -TARGET_EFAULT; \ 45 } \ 46 } while (0) 47 48 #define UNLOCK_PATH2(p1, arg1, p2, arg2) \ 49 do { \ 50 unlock_user(p2, arg2, 0); \ 51 unlock_user(p1, arg1, 0); \ 52 } while (0) 53 54 struct iovec *lock_iovec(int type, abi_ulong target_addr, int count, int copy); 55 void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, int copy); 56 57 int safe_open(const char *path, int flags, mode_t mode); 58 int safe_openat(int fd, const char *path, int flags, mode_t mode); 59 60 ssize_t safe_read(int fd, void *buf, size_t nbytes); 61 ssize_t safe_pread(int fd, void *buf, size_t nbytes, off_t offset); 62 ssize_t safe_readv(int fd, const struct iovec *iov, int iovcnt); 63 ssize_t safe_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); 64 65 ssize_t safe_write(int fd, void *buf, size_t nbytes); 66 ssize_t safe_pwrite(int fd, void *buf, size_t nbytes, off_t offset); 67 ssize_t safe_writev(int fd, const struct iovec *iov, int iovcnt); 68 ssize_t safe_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); 69 70 /* read(2) */ 71 static abi_long do_bsd_read(abi_long arg1, abi_long arg2, abi_long arg3) 72 { 73 abi_long ret; 74 void *p; 75 76 p = lock_user(VERIFY_WRITE, arg2, arg3, 0); 77 if (p == NULL) { 78 return -TARGET_EFAULT; 79 } 80 ret = get_errno(safe_read(arg1, p, arg3)); 81 unlock_user(p, arg2, ret); 82 83 return ret; 84 } 85 86 /* pread(2) */ 87 static abi_long do_bsd_pread(void *cpu_env, abi_long arg1, 88 abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) 89 { 90 abi_long ret; 91 void *p; 92 93 p = lock_user(VERIFY_WRITE, arg2, arg3, 0); 94 if (p == NULL) { 95 return -TARGET_EFAULT; 96 } 97 if (regpairs_aligned(cpu_env) != 0) { 98 arg4 = arg5; 99 arg5 = arg6; 100 } 101 ret = get_errno(safe_pread(arg1, p, arg3, target_arg64(arg4, arg5))); 102 unlock_user(p, arg2, ret); 103 104 return ret; 105 } 106 107 /* readv(2) */ 108 static abi_long do_bsd_readv(abi_long arg1, abi_long arg2, abi_long arg3) 109 { 110 abi_long ret; 111 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); 112 113 if (vec != NULL) { 114 ret = get_errno(safe_readv(arg1, vec, arg3)); 115 unlock_iovec(vec, arg2, arg3, 1); 116 } else { 117 ret = -host_to_target_errno(errno); 118 } 119 120 return ret; 121 } 122 123 /* preadv(2) */ 124 static abi_long do_bsd_preadv(void *cpu_env, abi_long arg1, 125 abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) 126 { 127 abi_long ret; 128 struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 1); 129 130 if (vec != NULL) { 131 if (regpairs_aligned(cpu_env) != 0) { 132 arg4 = arg5; 133 arg5 = arg6; 134 } 135 ret = get_errno(safe_preadv(arg1, vec, arg3, target_arg64(arg4, arg5))); 136 unlock_iovec(vec, arg2, arg3, 0); 137 } else { 138 ret = -host_to_target_errno(errno); 139 } 140 141 return ret; 142 } 143 144 /* write(2) */ 145 static abi_long do_bsd_write(abi_long arg1, abi_long arg2, abi_long arg3) 146 { 147 abi_long nbytes, ret; 148 void *p; 149 150 /* nbytes < 0 implies that it was larger than SIZE_MAX. */ 151 nbytes = arg3; 152 if (nbytes < 0) { 153 return -TARGET_EINVAL; 154 } 155 p = lock_user(VERIFY_READ, arg2, nbytes, 1); 156 if (p == NULL) { 157 return -TARGET_EFAULT; 158 } 159 ret = get_errno(safe_write(arg1, p, arg3)); 160 unlock_user(p, arg2, 0); 161 162 return ret; 163 } 164 165 /* pwrite(2) */ 166 static abi_long do_bsd_pwrite(void *cpu_env, abi_long arg1, 167 abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) 168 { 169 abi_long ret; 170 void *p; 171 172 p = lock_user(VERIFY_READ, arg2, arg3, 1); 173 if (p == NULL) { 174 return -TARGET_EFAULT; 175 } 176 if (regpairs_aligned(cpu_env) != 0) { 177 arg4 = arg5; 178 arg5 = arg6; 179 } 180 ret = get_errno(safe_pwrite(arg1, p, arg3, target_arg64(arg4, arg5))); 181 unlock_user(p, arg2, 0); 182 183 return ret; 184 } 185 186 /* writev(2) */ 187 static abi_long do_bsd_writev(abi_long arg1, abi_long arg2, abi_long arg3) 188 { 189 abi_long ret; 190 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); 191 192 if (vec != NULL) { 193 ret = get_errno(safe_writev(arg1, vec, arg3)); 194 unlock_iovec(vec, arg2, arg3, 0); 195 } else { 196 ret = -host_to_target_errno(errno); 197 } 198 199 return ret; 200 } 201 202 /* pwritev(2) */ 203 static abi_long do_bsd_pwritev(void *cpu_env, abi_long arg1, 204 abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) 205 { 206 abi_long ret; 207 struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); 208 209 if (vec != NULL) { 210 if (regpairs_aligned(cpu_env) != 0) { 211 arg4 = arg5; 212 arg5 = arg6; 213 } 214 ret = get_errno(safe_pwritev(arg1, vec, arg3, target_arg64(arg4, arg5))); 215 unlock_iovec(vec, arg2, arg3, 0); 216 } else { 217 ret = -host_to_target_errno(errno); 218 } 219 220 return ret; 221 } 222 223 /* open(2) */ 224 static abi_long do_bsd_open(abi_long arg1, abi_long arg2, abi_long arg3) 225 { 226 abi_long ret; 227 void *p; 228 229 LOCK_PATH(p, arg1); 230 ret = get_errno(safe_open(path(p), target_to_host_bitmask(arg2, 231 fcntl_flags_tbl), arg3)); 232 UNLOCK_PATH(p, arg1); 233 234 return ret; 235 } 236 237 /* openat(2) */ 238 static abi_long do_bsd_openat(abi_long arg1, abi_long arg2, 239 abi_long arg3, abi_long arg4) 240 { 241 abi_long ret; 242 void *p; 243 244 LOCK_PATH(p, arg2); 245 ret = get_errno(safe_openat(arg1, path(p), 246 target_to_host_bitmask(arg3, fcntl_flags_tbl), arg4)); 247 UNLOCK_PATH(p, arg2); 248 249 return ret; 250 } 251 252 /* close(2) */ 253 static abi_long do_bsd_close(abi_long arg1) 254 { 255 return get_errno(close(arg1)); 256 } 257 258 /* fdatasync(2) */ 259 static abi_long do_bsd_fdatasync(abi_long arg1) 260 { 261 return get_errno(fdatasync(arg1)); 262 } 263 264 /* fsync(2) */ 265 static abi_long do_bsd_fsync(abi_long arg1) 266 { 267 return get_errno(fsync(arg1)); 268 } 269 270 /* closefrom(2) */ 271 static abi_long do_bsd_closefrom(abi_long arg1) 272 { 273 closefrom(arg1); /* returns void */ 274 return get_errno(0); 275 } 276 277 /* revoke(2) */ 278 static abi_long do_bsd_revoke(abi_long arg1) 279 { 280 abi_long ret; 281 void *p; 282 283 LOCK_PATH(p, arg1); 284 ret = get_errno(revoke(p)); /* XXX path(p)? */ 285 UNLOCK_PATH(p, arg1); 286 287 return ret; 288 } 289 290 /* access(2) */ 291 static abi_long do_bsd_access(abi_long arg1, abi_long arg2) 292 { 293 abi_long ret; 294 void *p; 295 296 LOCK_PATH(p, arg1); 297 ret = get_errno(access(path(p), arg2)); 298 UNLOCK_PATH(p, arg1); 299 300 return ret; 301 } 302 303 /* eaccess(2) */ 304 static abi_long do_bsd_eaccess(abi_long arg1, abi_long arg2) 305 { 306 abi_long ret; 307 void *p; 308 309 LOCK_PATH(p, arg1); 310 ret = get_errno(eaccess(path(p), arg2)); 311 UNLOCK_PATH(p, arg1); 312 313 return ret; 314 } 315 316 /* faccessat(2) */ 317 static abi_long do_bsd_faccessat(abi_long arg1, abi_long arg2, 318 abi_long arg3, abi_long arg4) 319 { 320 abi_long ret; 321 void *p; 322 323 LOCK_PATH(p, arg2); 324 ret = get_errno(faccessat(arg1, p, arg3, arg4)); /* XXX path(p)? */ 325 UNLOCK_PATH(p, arg2); 326 327 return ret; 328 } 329 330 /* chdir(2) */ 331 static abi_long do_bsd_chdir(abi_long arg1) 332 { 333 abi_long ret; 334 void *p; 335 336 LOCK_PATH(p, arg1); 337 ret = get_errno(chdir(p)); /* XXX path(p)? */ 338 UNLOCK_PATH(p, arg1); 339 340 return ret; 341 } 342 343 /* fchdir(2) */ 344 static abi_long do_bsd_fchdir(abi_long arg1) 345 { 346 return get_errno(fchdir(arg1)); 347 } 348 349 /* rename(2) */ 350 static abi_long do_bsd_rename(abi_long arg1, abi_long arg2) 351 { 352 abi_long ret; 353 void *p1, *p2; 354 355 LOCK_PATH2(p1, arg1, p2, arg2); 356 ret = get_errno(rename(p1, p2)); /* XXX path(p1), path(p2) */ 357 UNLOCK_PATH2(p1, arg1, p2, arg2); 358 359 return ret; 360 } 361 362 /* renameat(2) */ 363 static abi_long do_bsd_renameat(abi_long arg1, abi_long arg2, 364 abi_long arg3, abi_long arg4) 365 { 366 abi_long ret; 367 void *p1, *p2; 368 369 LOCK_PATH2(p1, arg2, p2, arg4); 370 ret = get_errno(renameat(arg1, p1, arg3, p2)); 371 UNLOCK_PATH2(p1, arg2, p2, arg4); 372 373 return ret; 374 } 375 376 /* link(2) */ 377 static abi_long do_bsd_link(abi_long arg1, abi_long arg2) 378 { 379 abi_long ret; 380 void *p1, *p2; 381 382 LOCK_PATH2(p1, arg1, p2, arg2); 383 ret = get_errno(link(p1, p2)); /* XXX path(p1), path(p2) */ 384 UNLOCK_PATH2(p1, arg1, p2, arg2); 385 386 return ret; 387 } 388 389 /* linkat(2) */ 390 static abi_long do_bsd_linkat(abi_long arg1, abi_long arg2, 391 abi_long arg3, abi_long arg4, abi_long arg5) 392 { 393 abi_long ret; 394 void *p1, *p2; 395 396 LOCK_PATH2(p1, arg2, p2, arg4); 397 ret = get_errno(linkat(arg1, p1, arg3, p2, arg5)); 398 UNLOCK_PATH2(p1, arg2, p2, arg4); 399 400 return ret; 401 } 402 403 /* unlink(2) */ 404 static abi_long do_bsd_unlink(abi_long arg1) 405 { 406 abi_long ret; 407 void *p; 408 409 LOCK_PATH(p, arg1); 410 ret = get_errno(unlink(p)); /* XXX path(p) */ 411 UNLOCK_PATH(p, arg1); 412 413 return ret; 414 } 415 416 /* unlinkat(2) */ 417 static abi_long do_bsd_unlinkat(abi_long arg1, abi_long arg2, 418 abi_long arg3) 419 { 420 abi_long ret; 421 void *p; 422 423 LOCK_PATH(p, arg2); 424 ret = get_errno(unlinkat(arg1, p, arg3)); /* XXX path(p) */ 425 UNLOCK_PATH(p, arg2); 426 427 return ret; 428 } 429 430 /* mkdir(2) */ 431 static abi_long do_bsd_mkdir(abi_long arg1, abi_long arg2) 432 { 433 abi_long ret; 434 void *p; 435 436 LOCK_PATH(p, arg1); 437 ret = get_errno(mkdir(p, arg2)); /* XXX path(p) */ 438 UNLOCK_PATH(p, arg1); 439 440 return ret; 441 } 442 443 /* mkdirat(2) */ 444 static abi_long do_bsd_mkdirat(abi_long arg1, abi_long arg2, 445 abi_long arg3) 446 { 447 abi_long ret; 448 void *p; 449 450 LOCK_PATH(p, arg2); 451 ret = get_errno(mkdirat(arg1, p, arg3)); 452 UNLOCK_PATH(p, arg2); 453 454 return ret; 455 } 456 457 /* rmdir(2) */ 458 static abi_long do_bsd_rmdir(abi_long arg1) 459 { 460 abi_long ret; 461 void *p; 462 463 LOCK_PATH(p, arg1); 464 ret = get_errno(rmdir(p)); /* XXX path(p)? */ 465 UNLOCK_PATH(p, arg1); 466 467 return ret; 468 } 469 470 /* undocumented __getcwd(char *buf, size_t len) system call */ 471 static abi_long do_bsd___getcwd(abi_long arg1, abi_long arg2) 472 { 473 abi_long ret; 474 void *p; 475 476 p = lock_user(VERIFY_WRITE, arg1, arg2, 0); 477 if (p == NULL) { 478 return -TARGET_EFAULT; 479 } 480 ret = safe_syscall(SYS___getcwd, p, arg2); 481 unlock_user(p, arg1, ret == 0 ? strlen(p) + 1 : 0); 482 483 return get_errno(ret); 484 } 485 486 /* dup(2) */ 487 static abi_long do_bsd_dup(abi_long arg1) 488 { 489 return get_errno(dup(arg1)); 490 } 491 492 /* dup2(2) */ 493 static abi_long do_bsd_dup2(abi_long arg1, abi_long arg2) 494 { 495 return get_errno(dup2(arg1, arg2)); 496 } 497 498 /* truncate(2) */ 499 static abi_long do_bsd_truncate(void *cpu_env, abi_long arg1, 500 abi_long arg2, abi_long arg3, abi_long arg4) 501 { 502 abi_long ret; 503 void *p; 504 505 LOCK_PATH(p, arg1); 506 if (regpairs_aligned(cpu_env) != 0) { 507 arg2 = arg3; 508 arg3 = arg4; 509 } 510 ret = get_errno(truncate(p, target_arg64(arg2, arg3))); 511 UNLOCK_PATH(p, arg1); 512 513 return ret; 514 } 515 516 /* ftruncate(2) */ 517 static abi_long do_bsd_ftruncate(void *cpu_env, abi_long arg1, 518 abi_long arg2, abi_long arg3, abi_long arg4) 519 { 520 if (regpairs_aligned(cpu_env) != 0) { 521 arg2 = arg3; 522 arg3 = arg4; 523 } 524 return get_errno(ftruncate(arg1, target_arg64(arg2, arg3))); 525 } 526 527 /* acct(2) */ 528 static abi_long do_bsd_acct(abi_long arg1) 529 { 530 abi_long ret; 531 void *p; 532 533 if (arg1 == 0) { 534 ret = get_errno(acct(NULL)); 535 } else { 536 LOCK_PATH(p, arg1); 537 ret = get_errno(acct(path(p))); 538 UNLOCK_PATH(p, arg1); 539 } 540 return ret; 541 } 542 543 /* sync(2) */ 544 static abi_long do_bsd_sync(void) 545 { 546 sync(); 547 return 0; 548 } 549 550 /* mount(2) */ 551 static abi_long do_bsd_mount(abi_long arg1, abi_long arg2, abi_long arg3, 552 abi_long arg4) 553 { 554 abi_long ret; 555 void *p1, *p2; 556 557 LOCK_PATH2(p1, arg1, p2, arg2); 558 /* 559 * XXX arg4 should be locked, but it isn't clear how to do that since it may 560 * be not be a NULL-terminated string. 561 */ 562 if (arg4 == 0) { 563 ret = get_errno(mount(p1, p2, arg3, NULL)); /* XXX path(p2)? */ 564 } else { 565 ret = get_errno(mount(p1, p2, arg3, g2h_untagged(arg4))); /* XXX path(p2)? */ 566 } 567 UNLOCK_PATH2(p1, arg1, p2, arg2); 568 569 return ret; 570 } 571 572 /* unmount(2) */ 573 static abi_long do_bsd_unmount(abi_long arg1, abi_long arg2) 574 { 575 abi_long ret; 576 void *p; 577 578 LOCK_PATH(p, arg1); 579 ret = get_errno(unmount(p, arg2)); /* XXX path(p)? */ 580 UNLOCK_PATH(p, arg1); 581 582 return ret; 583 } 584 585 /* nmount(2) */ 586 static abi_long do_bsd_nmount(abi_long arg1, abi_long count, 587 abi_long flags) 588 { 589 abi_long ret; 590 struct iovec *vec = lock_iovec(VERIFY_READ, arg1, count, 1); 591 592 if (vec != NULL) { 593 ret = get_errno(nmount(vec, count, flags)); 594 unlock_iovec(vec, arg1, count, 0); 595 } else { 596 return -TARGET_EFAULT; 597 } 598 599 return ret; 600 } 601 602 /* symlink(2) */ 603 static abi_long do_bsd_symlink(abi_long arg1, abi_long arg2) 604 { 605 abi_long ret; 606 void *p1, *p2; 607 608 LOCK_PATH2(p1, arg1, p2, arg2); 609 ret = get_errno(symlink(p1, p2)); /* XXX path(p1), path(p2) */ 610 UNLOCK_PATH2(p1, arg1, p2, arg2); 611 612 return ret; 613 } 614 615 /* symlinkat(2) */ 616 static abi_long do_bsd_symlinkat(abi_long arg1, abi_long arg2, 617 abi_long arg3) 618 { 619 abi_long ret; 620 void *p1, *p2; 621 622 LOCK_PATH2(p1, arg1, p2, arg3); 623 ret = get_errno(symlinkat(p1, arg2, p2)); /* XXX path(p1), path(p2) */ 624 UNLOCK_PATH2(p1, arg1, p2, arg3); 625 626 return ret; 627 } 628 629 /* readlink(2) */ 630 static abi_long do_bsd_readlink(CPUArchState *env, abi_long arg1, 631 abi_long arg2, abi_long arg3) 632 { 633 abi_long ret; 634 void *p1, *p2; 635 636 LOCK_PATH(p1, arg1); 637 p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); 638 if (p2 == NULL) { 639 UNLOCK_PATH(p1, arg1); 640 return -TARGET_EFAULT; 641 } 642 if (strcmp(p1, "/proc/curproc/file") == 0) { 643 CPUState *cpu = env_cpu(env); 644 TaskState *ts = (TaskState *)cpu->opaque; 645 strncpy(p2, ts->bprm->fullpath, arg3); 646 ret = MIN((abi_long)strlen(ts->bprm->fullpath), arg3); 647 } else { 648 ret = get_errno(readlink(path(p1), p2, arg3)); 649 } 650 unlock_user(p2, arg2, ret); 651 UNLOCK_PATH(p1, arg1); 652 653 return ret; 654 } 655 656 /* readlinkat(2) */ 657 static abi_long do_bsd_readlinkat(abi_long arg1, abi_long arg2, 658 abi_long arg3, abi_long arg4) 659 { 660 abi_long ret; 661 void *p1, *p2; 662 663 LOCK_PATH(p1, arg2); 664 p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); 665 if (p2 == NULL) { 666 UNLOCK_PATH(p1, arg2); 667 return -TARGET_EFAULT; 668 } 669 ret = get_errno(readlinkat(arg1, p1, p2, arg4)); 670 unlock_user(p2, arg3, ret); 671 UNLOCK_PATH(p1, arg2); 672 673 return ret; 674 } 675 676 /* chmod(2) */ 677 static abi_long do_bsd_chmod(abi_long arg1, abi_long arg2) 678 { 679 abi_long ret; 680 void *p; 681 682 LOCK_PATH(p, arg1); 683 ret = get_errno(chmod(p, arg2)); /* XXX path(p)? */ 684 UNLOCK_PATH(p, arg1); 685 686 return ret; 687 } 688 689 /* fchmod(2) */ 690 static abi_long do_bsd_fchmod(abi_long arg1, abi_long arg2) 691 { 692 return get_errno(fchmod(arg1, arg2)); 693 } 694 695 /* lchmod(2) */ 696 static abi_long do_bsd_lchmod(abi_long arg1, abi_long arg2) 697 { 698 abi_long ret; 699 void *p; 700 701 LOCK_PATH(p, arg1); 702 ret = get_errno(lchmod(p, arg2)); /* XXX path(p)? */ 703 UNLOCK_PATH(p, arg1); 704 705 return ret; 706 } 707 708 /* fchmodat(2) */ 709 static abi_long do_bsd_fchmodat(abi_long arg1, abi_long arg2, 710 abi_long arg3, abi_long arg4) 711 { 712 abi_long ret; 713 void *p; 714 715 LOCK_PATH(p, arg2); 716 ret = get_errno(fchmodat(arg1, p, arg3, arg4)); 717 UNLOCK_PATH(p, arg2); 718 719 return ret; 720 } 721 722 /* pre-ino64 mknod(2) */ 723 static abi_long do_bsd_freebsd11_mknod(abi_long arg1, abi_long arg2, abi_long arg3) 724 { 725 abi_long ret; 726 void *p; 727 728 LOCK_PATH(p, arg1); 729 ret = get_errno(syscall(SYS_freebsd11_mknod, p, arg2, arg3)); 730 UNLOCK_PATH(p, arg1); 731 732 return ret; 733 } 734 735 /* pre-ino64 mknodat(2) */ 736 static abi_long do_bsd_freebsd11_mknodat(abi_long arg1, abi_long arg2, 737 abi_long arg3, abi_long arg4) 738 { 739 abi_long ret; 740 void *p; 741 742 LOCK_PATH(p, arg2); 743 ret = get_errno(syscall(SYS_freebsd11_mknodat, arg1, p, arg3, arg4)); 744 UNLOCK_PATH(p, arg2); 745 746 return ret; 747 } 748 749 /* post-ino64 mknodat(2) */ 750 static abi_long do_bsd_mknodat(void *cpu_env, abi_long arg1, 751 abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, 752 abi_long arg6) 753 { 754 abi_long ret; 755 void *p; 756 757 LOCK_PATH(p, arg2); 758 /* 32-bit arch's use two 32 registers for 64 bit return value */ 759 if (regpairs_aligned(cpu_env) != 0) { 760 ret = get_errno(mknodat(arg1, p, arg3, target_arg64(arg5, arg6))); 761 } else { 762 ret = get_errno(mknodat(arg1, p, arg3, target_arg64(arg4, arg5))); 763 } 764 UNLOCK_PATH(p, arg2); 765 766 return ret; 767 } 768 769 /* chown(2) */ 770 static abi_long do_bsd_chown(abi_long arg1, abi_long arg2, abi_long arg3) 771 { 772 abi_long ret; 773 void *p; 774 775 LOCK_PATH(p, arg1); 776 ret = get_errno(chown(p, arg2, arg3)); /* XXX path(p)? */ 777 UNLOCK_PATH(p, arg1); 778 779 return ret; 780 } 781 782 /* fchown(2) */ 783 static abi_long do_bsd_fchown(abi_long arg1, abi_long arg2, 784 abi_long arg3) 785 { 786 return get_errno(fchown(arg1, arg2, arg3)); 787 } 788 789 /* lchown(2) */ 790 static abi_long do_bsd_lchown(abi_long arg1, abi_long arg2, 791 abi_long arg3) 792 { 793 abi_long ret; 794 void *p; 795 796 LOCK_PATH(p, arg1); 797 ret = get_errno(lchown(p, arg2, arg3)); /* XXX path(p)? */ 798 UNLOCK_PATH(p, arg1); 799 800 return ret; 801 } 802 803 /* fchownat(2) */ 804 static abi_long do_bsd_fchownat(abi_long arg1, abi_long arg2, 805 abi_long arg3, abi_long arg4, abi_long arg5) 806 { 807 abi_long ret; 808 void *p; 809 810 LOCK_PATH(p, arg2); 811 ret = get_errno(fchownat(arg1, p, arg3, arg4, arg5)); /* XXX path(p)? */ 812 UNLOCK_PATH(p, arg2); 813 814 return ret; 815 } 816 817 /* chflags(2) */ 818 static abi_long do_bsd_chflags(abi_long arg1, abi_long arg2) 819 { 820 abi_long ret; 821 void *p; 822 823 LOCK_PATH(p, arg1); 824 ret = get_errno(chflags(p, arg2)); /* XXX path(p)? */ 825 UNLOCK_PATH(p, arg1); 826 827 return ret; 828 } 829 830 /* lchflags(2) */ 831 static abi_long do_bsd_lchflags(abi_long arg1, abi_long arg2) 832 { 833 abi_long ret; 834 void *p; 835 836 LOCK_PATH(p, arg1); 837 ret = get_errno(lchflags(p, arg2)); /* XXX path(p)? */ 838 UNLOCK_PATH(p, arg1); 839 840 return ret; 841 } 842 843 /* fchflags(2) */ 844 static abi_long do_bsd_fchflags(abi_long arg1, abi_long arg2) 845 { 846 return get_errno(fchflags(arg1, arg2)); 847 } 848 849 /* chroot(2) */ 850 static abi_long do_bsd_chroot(abi_long arg1) 851 { 852 abi_long ret; 853 void *p; 854 855 LOCK_PATH(p, arg1); 856 ret = get_errno(chroot(p)); /* XXX path(p)? */ 857 UNLOCK_PATH(p, arg1); 858 859 return ret; 860 } 861 862 /* flock(2) */ 863 static abi_long do_bsd_flock(abi_long arg1, abi_long arg2) 864 { 865 return get_errno(flock(arg1, arg2)); 866 } 867 868 /* mkfifo(2) */ 869 static abi_long do_bsd_mkfifo(abi_long arg1, abi_long arg2) 870 { 871 abi_long ret; 872 void *p; 873 874 LOCK_PATH(p, arg1); 875 ret = get_errno(mkfifo(p, arg2)); /* XXX path(p)? */ 876 UNLOCK_PATH(p, arg1); 877 878 return ret; 879 } 880 881 /* mkfifoat(2) */ 882 static abi_long do_bsd_mkfifoat(abi_long arg1, abi_long arg2, 883 abi_long arg3) 884 { 885 abi_long ret; 886 void *p; 887 888 LOCK_PATH(p, arg2); 889 ret = get_errno(mkfifoat(arg1, p, arg3)); 890 UNLOCK_PATH(p, arg2); 891 892 return ret; 893 } 894 895 /* pathconf(2) */ 896 static abi_long do_bsd_pathconf(abi_long arg1, abi_long arg2) 897 { 898 abi_long ret; 899 void *p; 900 901 LOCK_PATH(p, arg1); 902 ret = get_errno(pathconf(p, arg2)); /* XXX path(p)? */ 903 UNLOCK_PATH(p, arg1); 904 905 return ret; 906 } 907 908 /* lpathconf(2) */ 909 static abi_long do_bsd_lpathconf(abi_long arg1, abi_long arg2) 910 { 911 abi_long ret; 912 void *p; 913 914 LOCK_PATH(p, arg1); 915 ret = get_errno(lpathconf(p, arg2)); /* XXX path(p)? */ 916 UNLOCK_PATH(p, arg1); 917 918 return ret; 919 } 920 921 /* fpathconf(2) */ 922 static abi_long do_bsd_fpathconf(abi_long arg1, abi_long arg2) 923 { 924 return get_errno(fpathconf(arg1, arg2)); 925 } 926 927 /* undelete(2) */ 928 static abi_long do_bsd_undelete(abi_long arg1) 929 { 930 abi_long ret; 931 void *p; 932 933 LOCK_PATH(p, arg1); 934 ret = get_errno(undelete(p)); /* XXX path(p)? */ 935 UNLOCK_PATH(p, arg1); 936 937 return ret; 938 } 939 940 #endif /* BSD_FILE_H */ 941