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