// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sdk/lib/fdio/unistd.h"

#include <dirent.h>
#include <fcntl.h>
#include <fidl/fuchsia.io/cpp/wire.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/io.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/unsafe.h>
#include <lib/fdio/vfs.h>
#include <lib/stdcompat/string_view.h>
#include <lib/zx/result.h>
#include <lib/zxio/ops.h>
#include <lib/zxio/posix_mode.h>
#include <lib/zxio/types.h>
#include <poll.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
#include <threads.h>
#include <utime.h>
#include <zircon/compiler.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <cstdarg>
#include <thread>
#include <utility>
#include <variant>

#include <fbl/auto_lock.h>
#include <fbl/string_buffer.h>
#include <safemath/checked_math.h>

#include "sdk/lib/fdio/cleanpath.h"
#include "sdk/lib/fdio/fdio_unistd.h"
#include "sdk/lib/fdio/internal.h"
#include "sdk/lib/fdio/namespace/namespace.h"
#include "sdk/lib/fdio/zxio.h"

namespace fio = fuchsia_io;

static_assert(IOFLAG_CLOEXEC == FD_CLOEXEC, "Unexpected fdio flags value");

// non-thread-safe emulation of unistd io functions using the fdio transports

// Verify the O_* flags which align with fuchsia.io.
static_assert(O_PATH == static_cast<uint32_t>(fio::wire::OpenFlags::kNodeReference),
              "Open Flag mismatch");
static_assert(O_CREAT == static_cast<uint32_t>(fio::wire::OpenFlags::kCreate),
              "Open Flag mismatch");
static_assert(O_EXCL == static_cast<uint32_t>(fio::wire::OpenFlags::kCreateIfAbsent),
              "Open Flag mismatch");
static_assert(O_TRUNC == static_cast<uint32_t>(fio::wire::OpenFlags::kTruncate),
              "Open Flag mismatch");
static_assert(O_DIRECTORY == static_cast<uint32_t>(fio::wire::OpenFlags::kDirectory),
              "Open Flag mismatch");
static_assert(O_APPEND == static_cast<uint32_t>(fio::wire::OpenFlags::kAppend),
              "Open Flag mismatch");

// The mask of "1:1" flags which match between both open flag representations.
constexpr fio::wire::OpenFlags kZxioFsMask =
    fio::wire::OpenFlags::kNodeReference | fio::wire::OpenFlags::kCreate |
    fio::wire::OpenFlags::kCreateIfAbsent | fio::wire::OpenFlags::kTruncate |
    fio::wire::OpenFlags::kDirectory | fio::wire::OpenFlags::kAppend |
    fio::wire::OpenFlags::kCloneSameRights;

constexpr fio::wire::OpenFlags kZxioFsFlags =
    kZxioFsMask | fio::wire::OpenFlags::kPosixWritable | fio::wire::OpenFlags::kPosixExecutable |
    fio::wire::OpenFlags::kNotDirectory | fio::wire::OpenFlags::kCloneSameRights;

// Verify that the remaining O_* flags don't overlap with the ZXIO_FS flags.
static_assert(!(O_RDONLY & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_WRONLY & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_RDWR & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_NONBLOCK & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_DSYNC & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_SYNC & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_RSYNC & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_NOFOLLOW & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_CLOEXEC & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_NOCTTY & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_ASYNC & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_DIRECT & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_LARGEFILE & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_NOATIME & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");
static_assert(!(O_TMPFILE & static_cast<uint32_t>(kZxioFsFlags)),
              "Unexpected collision with static_cast<uint32_t>(kZxioFsFlags)");

static fio::wire::OpenFlags fdio_flags_to_zxio(uint32_t flags) {
  fio::wire::OpenFlags rights = {};
  switch (flags & O_ACCMODE) {
    case O_RDONLY:
      rights |= fio::wire::OpenFlags::kRightReadable;
      break;
    case O_WRONLY:
      rights |= fio::wire::OpenFlags::kRightWritable;
      break;
    case O_RDWR:
      rights |= fio::wire::OpenFlags::kRightReadable | fio::wire::OpenFlags::kRightWritable;
      break;
  }

  fio::wire::OpenFlags result = rights | fio::wire::OpenFlags::kDescribe |
                                (static_cast<fio::wire::OpenFlags>(flags) & kZxioFsMask);

  if (!(result & fio::wire::OpenFlags::kNodeReference)) {
    result |= fio::wire::OpenFlags::kPosixWritable | fio::wire::OpenFlags::kPosixExecutable;
  }
  return result;
}

static uint32_t zxio_flags_to_fdio(fio::wire::OpenFlags flags) {
  uint32_t result = 0;
  if ((flags & (fio::wire::OpenFlags::kRightReadable | fio::wire::OpenFlags::kRightWritable)) ==
      (fio::wire::OpenFlags::kRightReadable | fio::wire::OpenFlags::kRightWritable)) {
    result |= O_RDWR;
  } else if (flags & fio::wire::OpenFlags::kRightWritable) {
    result |= O_WRONLY;
  } else {
    result |= O_RDONLY;
  }

  result |= static_cast<uint32_t>(flags & kZxioFsMask);
  return result;
}

fdio_ptr fdio_iodir(int dirfd, std::string_view& in_out_path) {
  const bool root = cpp20::starts_with(in_out_path, '/');
  if (root) {
    // Since we are sending a request to the root handle, the
    // rest of the in_out_path should be canonicalized as a relative
    // path (relative to this root handle).
    while (cpp20::starts_with(in_out_path, '/')) {
      in_out_path.remove_prefix(1);
      if (in_out_path.empty()) {
        in_out_path = std::string_view(".");
      }
    }
  }
  const fbl::AutoLock lock(&fdio_lock);
  if (root) {
    return fdio_root_handle.get();
  }
  if (dirfd == AT_FDCWD) {
    return fdio_cwd_handle.get();
  }
  return fd_to_io_locked(dirfd);
}

static int close_impl(int fd, bool should_wait) {
  fdio_ptr io = unbind_from_fd(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  std::variant reference = GetLastReference(std::move(io));
  auto* ptr = std::get_if<fdio::last_reference>(&reference);
  if (ptr) {
    return STATUS(ptr->Close(should_wait));
  }
  return 0;
}

namespace fdio_internal {

zx::result<fdio_ptr> open_at_impl(int dirfd, const char* path, int flags, uint32_t mode,
                                  bool enforce_eisdir) {
  // Emulate EISDIR behavior from
  // http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html
  const bool flags_incompatible_with_directory =
      ((flags & ~O_PATH & O_ACCMODE) != O_RDONLY) || (flags & O_CREAT);
  fio::wire::OpenFlags fio_flags = fdio_flags_to_zxio(static_cast<uint32_t>(flags));
  if (S_ISDIR(mode)) {
    fio_flags |= fio::wire::OpenFlags::kDirectory;
  }

  return open_at_impl(dirfd, path, fio_flags,
                      {
                          .disallow_directory = enforce_eisdir && flags_incompatible_with_directory,
                          .allow_absolute_path = true,
                      });
}

zx::result<fdio_ptr> open_at_impl(int dirfd, const char* path, fio::wire::OpenFlags flags,
                                  OpenAtOptions options) {
  if (path == nullptr) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }
  if (path[0] == '\0') {
    return zx::error(ZX_ERR_NOT_FOUND);
  }

  fdio_internal::PathBuffer clean_buffer;
  bool has_ending_slash;
  const bool cleaned = CleanPath(path, &clean_buffer, &has_ending_slash);
  if (!cleaned) {
    return zx::error(ZX_ERR_BAD_PATH);
  }

  std::string_view clean = clean_buffer;

  // Some callers such as the fdio_open_..._at() family do not permit absolute paths.
  if (!options.allow_absolute_path && cpp20::starts_with(clean, '/')) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }

  const fdio_ptr iodir = fdio_iodir(dirfd, clean);
  if (iodir == nullptr) {
    return zx::error(ZX_ERR_BAD_HANDLE);
  }

  if (options.disallow_directory && has_ending_slash) {
    return zx::error(ZX_ERR_NOT_FILE);
  }

  if (has_ending_slash) {
    flags |= fio::wire::OpenFlags::kDirectory;
  }

  if (!(flags & fio::wire::OpenFlags::kDirectory)) {
    // At this point we're not sure if the path refers to a directory.
    // To emulate EISDIR behavior, if the flags are not compatible with directory,
    // use this flag to instruct open to error if the path turns out to be a directory.
    // Otherwise, opening a directory with O_RDWR will incorrectly succeed.
    if (options.disallow_directory) {
      flags |= fio::wire::OpenFlags::kNotDirectory;
    }
  }
  if (flags & fio::wire::OpenFlags::kNodeReference) {
    flags &= fio::wire::kOpenFlagsAllowedWithNodeReference;
  }
  return iodir->open(clean, flags);
}

// Open |path| from the |dirfd| directory, enforcing the POSIX EISDIR error condition. Specifically,
// ZX_ERR_NOT_FILE will be returned when opening a directory with write access/O_CREAT.
zx::result<fdio_ptr> open_at(int dirfd, const char* path, int flags, uint32_t mode) {
  return open_at_impl(dirfd, path, flags, mode, true);
}

// Open |path| from the |dirfd| directory, but allow creating directories/opening them with
// write access. Note that this differs from POSIX behavior.
zx::result<fdio_ptr> open_at_ignore_eisdir(int dirfd, const char* path, int flags, uint32_t mode) {
  return open_at_impl(dirfd, path, flags, mode, false);
}

// Open |path| from the current working directory, respecting EISDIR.
zx::result<fdio_ptr> open(const char* path, int flags, uint32_t mode) {
  return open_at(AT_FDCWD, path, flags, mode);
}

void update_cwd_path(const char* path) __TA_REQUIRES(fdio_cwd_lock) {
  if (path[0] == '/') {
    // it's "absolute", but we'll still parse it as relative (from /)
    // so that we normalize the path (resolving, ., .., //, etc)
    fdio_cwd_path.Set("/");
    path++;
  }

  size_t seglen;
  const char* next;
  for (; path[0]; path = next) {
    next = strchr(path, '/');
    if (next == nullptr) {
      seglen = strlen(path);
      next = path + seglen;
    } else {
      seglen = next - path;
      next++;
    }
    if (seglen == 0) {
      // empty segment, skip
      continue;
    }
    if ((seglen == 1) && (path[0] == '.')) {
      // no-change segment, skip
      continue;
    }
    if ((seglen == 2) && (path[0] == '.') && (path[1] == '.')) {
      // parent directory, remove the trailing path segment from cwd_path
      char* x = strrchr(fdio_cwd_path.data(), '/');
      if (x == nullptr) {
        // shouldn't ever happen
        goto wat;
      }
      // remove the current trailing path segment from cwd
      if (x == fdio_cwd_path.data()) {
        // but never remove the first /
        fdio_cwd_path[1] = 0;
      } else {
        x[0] = 0;
      }
      continue;
    }
    // regular path segment, append to cwd_path
    const size_t len = fdio_cwd_path.length();
    if ((len + seglen + 2) >= PATH_MAX) {
      // doesn't fit, shouldn't happen, but...
      goto wat;
    }
    if (len != 1) {
      // if len is 1, path is "/", so don't append a '/'
      fdio_cwd_path.Append('/');
    }
    fdio_cwd_path.Append(path, seglen);
  }
  return;

wat:
  fdio_cwd_path.Set("(unknown");
}

// Buffer used to store a single path component and its null terminator.
using NameBuffer = fbl::StringBuffer<NAME_MAX>;

// Opens the directory containing path
//
// Returns the last component of the path in `out`.  If `is_dir_out` is nullptr,
// a trailing slash will be added to the name if the last component happens to
// be a directory.  Otherwise, `is_dir_out` will be set to indicate whether the
// last component is a directory.
zx::result<fdio_ptr> opendir_containing_at(int dirfd, const char* path, NameBuffer* out,
                                           bool* is_dir_out) {
  if (path == nullptr) {
    return zx::error(ZX_ERR_INVALID_ARGS);
  }

  fdio_internal::PathBuffer clean_buffer;
  bool is_dir;
  const bool cleaned = fdio_internal::CleanPath(path, &clean_buffer, &is_dir);
  if (!cleaned) {
    return zx::error(ZX_ERR_BAD_PATH);
  }
  std::string_view clean = clean_buffer;

  const fdio_ptr iodir = fdio_iodir(dirfd, clean);
  if (iodir == nullptr) {
    return zx::error(ZX_ERR_BAD_HANDLE);
  }

  // Split the clean path into everything up to the last slash and the last component.
  std::string_view name = clean;
  std::string_view base;
  auto last_slash = clean.rfind('/');
  if (last_slash != std::string_view::npos) {
    name.remove_prefix(last_slash + 1);
    base = clean.substr(0, last_slash);
  }

  if (name.length() + (is_dir ? 1 : 0) > NAME_MAX) {
    return zx::error(ZX_ERR_BAD_PATH);
  }

  // Copy the trailing 'name' to out.
  out->Append(name);
  if (is_dir_out) {
    *is_dir_out = is_dir;
  } else if (is_dir) {
    // TODO(https://fxbug.dev/42113044): Propagate whether path is directory without using
    // trailing backslash to simplify server-side path parsing.
    // This might require refactoring trailing backslash checks out of
    // lower filesystem layers and associated FIDL APIs.

    out->Append('/');
  }

  if (base.empty() && !cpp20::starts_with(name, '/')) {
    base = ".";
  }

  return iodir->open(base, fdio_flags_to_zxio(O_RDONLY | O_DIRECTORY));
}

}  // namespace fdio_internal

// hook into libc process startup
// this is called prior to main to set up the fdio world
// and thus does not use the fdio_lock
//
// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/libc.h
extern "C" __EXPORT void __libc_extensions_init(uint32_t handle_count, zx_handle_t handle[],
                                                uint32_t handle_info[], uint32_t name_count,
                                                char** names) __TA_NO_THREAD_SAFETY_ANALYSIS {
  {
    const zx_status_t status = fdio_ns_create(&fdio_root_ns);
    ZX_ASSERT_MSG(status == ZX_OK, "Failed to create root namespace: %s",
                  zx_status_get_string(status));
  }

  fdio_ptr use_for_stdio = nullptr;

  // extract handles we care about
  for (uint32_t n = 0; n < handle_count; n++) {
    const unsigned arg = PA_HND_ARG(handle_info[n]);
    const zx_handle_t h = handle[n];

    // precalculate the fd from |arg|, for FDIO cases to use.
    const unsigned arg_fd = arg & (~FDIO_FLAG_USE_FOR_STDIO);

    switch (PA_HND_TYPE(handle_info[n])) {
      case PA_FD: {
        zx::result io = fdio::create(zx::handle(h));
        if (io.is_error()) {
          continue;
        }
        ZX_ASSERT_MSG(arg_fd < FDIO_MAX_FD,
                      "unreasonably large fd number %u in PA_FD (must be less than %u)", arg_fd,
                      FDIO_MAX_FD);
        ZX_ASSERT_MSG(fdio_fdtab[arg_fd].try_set(io.value()), "duplicate fd number %u in PA_FD",
                      arg_fd);

        if (arg & FDIO_FLAG_USE_FOR_STDIO) {
          use_for_stdio = std::move(io.value());
        }

        handle[n] = 0;
        handle_info[n] = 0;

        break;
      }
      case PA_NS_DIR:
        if (arg < name_count) {
          if (zx_status_t status = fdio_ns_bind(fdio_root_ns, names[arg], h); status != ZX_OK) {
            ZX_PANIC("fdio_ns_bind(%s): %s", names[arg], zx_status_get_string(status));
          }
        }
        // we always continue here to not steal the
        // handles from higher level code that may
        // also need access to the namespace
        continue;
      default:
        // unknown handle, leave it alone
        continue;
    }
  }

  {
    const char* cwd = getenv("PWD");
    fdio_internal::update_cwd_path(cwd ? cwd : "/");
  }

  if (use_for_stdio == nullptr) {
    zx::result null = fdio_internal::zxio::create_null();
    ZX_ASSERT_MSG(null.is_ok(), "%s", null.status_string());
    use_for_stdio = std::move(null.value());
  }

  // configure stdin/out/err if not init'd
  for (uint32_t n = 0; n < 3; n++) {
    fdio_fdtab[n].try_set(use_for_stdio);
  }

  fdio_ptr default_io = nullptr;
  auto get_default = [&default_io]() {
    if (default_io == nullptr) {
      zx::result default_result = fdio_internal::zxio::create();
      ZX_ASSERT_MSG(default_result.is_ok(), "%s", default_result.status_string());
      default_io = std::move(default_result.value());
    }
    return default_io;
  };

  zx::result root = fdio_ns_open_root(fdio_root_ns);
  if (root.is_ok()) {
    ZX_ASSERT(fdio_root_handle.try_set(root.value()));
    zx::result cwd = fdio_internal::open(fdio_cwd_path.c_str(), O_RDONLY | O_DIRECTORY, 0);
    if (cwd.is_ok()) {
      ZX_ASSERT(fdio_cwd_handle.try_set(cwd.value()));
    } else {
      ZX_ASSERT(fdio_cwd_handle.try_set(get_default()));
    }
  } else {
    ZX_ASSERT(fdio_root_handle.try_set(get_default()));
    ZX_ASSERT(fdio_cwd_handle.try_set(get_default()));
  }
}

// Clean up during process teardown. This runs after atexit hooks in
// libc. It continues to hold the fdio lock until process exit, to
// prevent other threads from racing on file descriptors.
//
// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/libc.h
extern "C" __EXPORT void __libc_extensions_fini(void) __TA_ACQUIRE(fdio_lock) {
  mtx_lock(&fdio_lock);
  [[maybe_unused]] auto root = fdio_root_handle.release();
  [[maybe_unused]] auto cwd = fdio_cwd_handle.release();
  for (auto& var : fdio_fdtab) {
    [[maybe_unused]] const fdio_ptr io = var.release();
  }
}

__EXPORT
zx_status_t fdio_ns_get_installed(fdio_ns_t** ns) {
  zx_status_t status = ZX_OK;
  const fbl::AutoLock lock(&fdio_lock);
  if (fdio_root_ns == nullptr) {
    status = ZX_ERR_NOT_FOUND;
  } else {
    *ns = fdio_root_ns;
  }
  return status;
}

zx_status_t fdio_wait(const fdio_ptr& io, uint32_t events, zx::time deadline,
                      uint32_t* out_pending) {
  zx_handle_t h = ZX_HANDLE_INVALID;
  zx_signals_t signals = 0;
  io->wait_begin(events, &h, &signals);
  if (h == ZX_HANDLE_INVALID) {
    // Wait operation is not applicable to the handle.
    return ZX_ERR_WRONG_TYPE;
  }

  zx_signals_t pending;
  const zx_status_t status = zx_object_wait_one(h, signals, deadline.get(), &pending);
  if (status == ZX_OK || status == ZX_ERR_TIMED_OUT) {
    io->wait_end(pending, &events);
    if (out_pending != nullptr) {
      *out_pending = events;
    }
  }

  return status;
}

static zx_status_t fdio_stat(const fdio_ptr& io, struct stat* s) {
  zxio_node_attributes_t attr = {.has = {
                                     .protocols = true,
                                     .abilities = true,
                                     .id = true,
                                     .content_size = true,
                                     .storage_size = true,
                                     .link_count = true,
                                     .creation_time = true,
                                     .modification_time = true,
                                 }};
  const zx_status_t status = io->get_attr(&attr);
  if (status != ZX_OK) {
    return status;
  }

  memset(s, 0, sizeof(struct stat));
  s->st_mode = zxio_get_posix_mode(attr.protocols, attr.abilities);
  s->st_ino = attr.has.id ? attr.id : fio::wire::kInoUnknown;
  s->st_size = attr.content_size;
  s->st_blksize = VNATTR_BLKSIZE;
  s->st_blocks = attr.storage_size / VNATTR_BLKSIZE;
  s->st_nlink = attr.link_count;
  s->st_ctim.tv_sec = attr.creation_time / ZX_SEC(1);
  s->st_ctim.tv_nsec = attr.creation_time % ZX_SEC(1);
  s->st_mtim.tv_sec = attr.modification_time / ZX_SEC(1);
  s->st_mtim.tv_nsec = attr.modification_time % ZX_SEC(1);
  return ZX_OK;
}

// The functions from here on provide implementations of fd and path
// centric posix-y io operations.

// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/stdio_impl.h
extern "C" __EXPORT zx_status_t _mmap_get_vmo_from_context(int mmap_prot, int mmap_flags,
                                                           void* context, zx_handle_t* out_vmo) {
  assert(context != nullptr);
  assert(out_vmo != nullptr);
  fdio_t* io = static_cast<fdio_t*>(context);

  // Convert mmap flags into respective ZXIO flags.
  zxio_vmo_flags_t zxio_flags = 0;

  // Handle protection bits and mode flags.
  zxio_flags |= (mmap_prot & PROT_READ) ? ZXIO_VMO_READ : 0;
  zxio_flags |= (mmap_prot & PROT_WRITE) ? ZXIO_VMO_WRITE : 0;
  zxio_flags |= (mmap_prot & PROT_EXEC) ? ZXIO_VMO_EXECUTE : 0;
  zxio_flags |= (mmap_flags & MAP_PRIVATE) ? ZXIO_VMO_PRIVATE_CLONE : 0;
  // We cannot specify ZXIO_VMO_SHARED_BUFFER as not all filesystems support shared mappings.
  // This does not affect behavior of filesystems that do not support writable shared mappings.
  // Filesystems which support PROT_WRITE + MAP_SHARED can enable the `supports_mmap_shared_write`
  // option in the fs_test suite to validate this case.

  return zxio_vmo_get(&io->zxio_storage().io, zxio_flags, out_vmo);
}

// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/stdio_impl.h
extern "C" __EXPORT zx_status_t _mmap_on_mapped(void* context, void* ptr) {
  assert(context != nullptr);
  fdio_t* io = static_cast<fdio_t*>(context);
  return zxio_on_mapped(&io->zxio_storage().io, ptr);
}

__EXPORT
int unlinkat(int dirfd, const char* path, int flags) {
  fdio_internal::NameBuffer name;
  bool is_dir;
  zx::result io = fdio_internal::opendir_containing_at(dirfd, path, &name, &is_dir);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  if (is_dir) {
    flags |= AT_REMOVEDIR;
  }
  return STATUS(io->unlink(name, flags));
}

__EXPORT
ssize_t readv(int fd, const struct iovec* iov, int iovcnt) {
  struct msghdr msg = {};
  msg.msg_iov = const_cast<struct iovec*>(iov);
  msg.msg_iovlen = iovcnt;
  return recvmsg(fd, &msg, 0);
}

__EXPORT
ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
  struct msghdr msg = {};
  msg.msg_iov = const_cast<struct iovec*>(iov);
  msg.msg_iovlen = iovcnt;
  return sendmsg(fd, &msg, 0);
}

__EXPORT
ssize_t preadv(int fd, const struct iovec* iov, int iovcnt, off_t offset) {
  zx_off_t zx_offset;
  if (!safemath::MakeCheckedNum(offset).AssignIfValid(&zx_offset)) {
    return ERRNO(EINVAL);
  }
  if (iovcnt > IOV_MAX) {
    return ERRNO(EINVAL);
  }
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  const bool blocking = (io->ioflag() & IOFLAG_NONBLOCK) == 0;
  const zx::time deadline = zx::deadline_after(io->rcvtimeo());

  zx_iovec_t zx_iov[iovcnt];
  for (int i = 0; i < iovcnt; ++i) {
    zx_iov[i] = {
        .buffer = iov[i].iov_base,
        .capacity = iov[i].iov_len,
    };
  }

  for (;;) {
    size_t actual;
    zx_status_t status =
        zxio_readv_at(&io->zxio_storage().io, zx_offset, zx_iov, iovcnt, 0, &actual);
    if (status == ZX_ERR_SHOULD_WAIT && blocking) {
      status = fdio_wait(io, FDIO_EVT_READABLE, deadline, nullptr);
      if (status == ZX_OK) {
        continue;
      }
      if (status == ZX_ERR_TIMED_OUT) {
        status = ZX_ERR_SHOULD_WAIT;
      }
    }
    if (status != ZX_OK) {
      return ERROR(status);
    }
    return actual;
  }
}

__EXPORT
ssize_t pwritev(int fd, const struct iovec* iov, int iovcnt, off_t offset) {
  zx_off_t zx_offset;
  if (!safemath::MakeCheckedNum(offset).AssignIfValid(&zx_offset)) {
    return ERRNO(EINVAL);
  }
  if (iovcnt > IOV_MAX) {
    return ERRNO(EINVAL);
  }
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  const bool blocking = (io->ioflag() & IOFLAG_NONBLOCK) == 0;
  const zx::time deadline = zx::deadline_after(io->sndtimeo());

  zx_iovec_t zx_iov[iovcnt];
  for (int i = 0; i < iovcnt; ++i) {
    zx_iov[i] = {
        .buffer = iov[i].iov_base,
        .capacity = iov[i].iov_len,
    };
  }

  for (;;) {
    size_t actual;
    zx_status_t status =
        zxio_writev_at(&io->zxio_storage().io, zx_offset, zx_iov, iovcnt, 0, &actual);
    if (status == ZX_ERR_SHOULD_WAIT && blocking) {
      status = fdio_wait(io, FDIO_EVT_WRITABLE, deadline, nullptr);
      if (status == ZX_OK) {
        continue;
      }
      if (status == ZX_ERR_TIMED_OUT) {
        status = ZX_ERR_SHOULD_WAIT;
      }
    }
    if (status != ZX_OK) {
      return ERROR(status);
    }
    return actual;
  }
}

__EXPORT
ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
  struct iovec iov = {};
  iov.iov_base = buf;
  iov.iov_len = count;
  return preadv(fd, &iov, 1, offset);
}

__EXPORT
ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
  struct iovec iov = {};
  iov.iov_base = const_cast<void*>(buf);
  iov.iov_len = count;
  return pwritev(fd, &iov, 1, offset);
}

__EXPORT
ssize_t read(int fd, void* buf, size_t count) {
  struct iovec iov = {};
  iov.iov_base = buf;
  iov.iov_len = count;
  return readv(fd, &iov, 1);
}

__EXPORT
ssize_t write(int fd, const void* buf, size_t count) {
  struct iovec iov = {};
  iov.iov_base = const_cast<void*>(buf);
  iov.iov_len = count;
  return writev(fd, &iov, 1);
}

__EXPORT
int close(int fd) { return close_impl(fd, /*should_wait=*/true); }

__EXPORT
int dup2(int oldfd, int newfd) {
  if (newfd < 0 || newfd >= FDIO_MAX_FD) {
    return ERRNO(EBADF);
  }
  // Don't release under lock.
  fdio_ptr io_to_close = nullptr;
  {
    const fbl::AutoLock lock(&fdio_lock);
    const fdio_ptr io = fd_to_io_locked(oldfd);
    if (io == nullptr) {
      return ERRNO(EBADF);
    }
    io_to_close = fdio_fdtab[newfd].replace(io);
  }
  return newfd;
}

__EXPORT
int dup(int oldfd) {
  const fbl::AutoLock lock(&fdio_lock);
  const fdio_ptr io = fd_to_io_locked(oldfd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  std::optional fd = bind_to_fd_locked(io);
  if (fd.has_value()) {
    return fd.value();
  }
  return ERRNO(EMFILE);
}

__EXPORT
int dup3(int oldfd, int newfd, int flags) {
  // dup3 differs from dup2 in that it fails with EINVAL, rather
  // than being a no op, on being given the same fd for both old and
  // new.
  if (oldfd == newfd) {
    return ERRNO(EINVAL);
  }

  if (flags != 0 && flags != O_CLOEXEC) {
    return ERRNO(EINVAL);
  }

  // TODO(https://fxbug.dev/42105837) Implement O_CLOEXEC.
  return dup2(oldfd, newfd);
}

__EXPORT
int fcntl(int fd, int cmd, ...) {
// Note that it is not safe to pull out the int out of the
// variadic arguments at the top level, as callers are not
// required to pass anything for many of the commands.
#define GET_INT_ARG(ARG)              \
  va_list args;                       \
  va_start(args, cmd);                \
  const int(ARG) = va_arg(args, int); \
  va_end(args)

  switch (cmd) {
    case F_DUPFD:
    case F_DUPFD_CLOEXEC: {
      // TODO(https://fxbug.dev/42105837) Implement CLOEXEC.
      GET_INT_ARG(starting_fd);
      if (starting_fd < 0) {
        return ERRNO(EINVAL);
      }
      const fbl::AutoLock lock(&fdio_lock);
      const fdio_ptr io = fd_to_io_locked(fd);
      if (io == nullptr) {
        return ERRNO(EBADF);
      }
      for (fd = starting_fd; fd < FDIO_MAX_FD; fd++) {
        if (fdio_fdtab[fd].try_set(io)) {
          return fd;
        }
      }
      return ERRNO(EMFILE);
    }
    case F_GETFD: {
      const fdio_ptr io = fd_to_io(fd);
      if (io == nullptr) {
        return ERRNO(EBADF);
      }
      const int flags = static_cast<int>(io->ioflag() & IOFLAG_FD_FLAGS);
      // POSIX mandates that the return value be nonnegative if successful.
      assert(flags >= 0);
      return flags;
    }
    case F_SETFD: {
      const fdio_ptr io = fd_to_io(fd);
      if (io == nullptr) {
        return ERRNO(EBADF);
      }
      GET_INT_ARG(flags);
      // TODO(https://fxbug.dev/42105837) Implement CLOEXEC.
      io->ioflag() &= ~IOFLAG_FD_FLAGS;
      io->ioflag() |= static_cast<uint32_t>(flags) & IOFLAG_FD_FLAGS;
      return 0;
    }
    case F_GETFL: {
      const fdio_ptr io = fd_to_io(fd);
      if (io == nullptr) {
        return ERRNO(EBADF);
      }
      fio::wire::OpenFlags flags;
      zx_status_t status = io->get_flags(&flags);
      if (status == ZX_ERR_NOT_SUPPORTED) {
        // We treat this as non-fatal, as it's valid for a remote to
        // simply not support FCNTL, but we still want to correctly
        // report the state of the (local) NONBLOCK flag
        flags = {};
        status = ZX_OK;
      }
      uint32_t fdio_flags = zxio_flags_to_fdio(flags);
      if (io->ioflag() & IOFLAG_NONBLOCK) {
        fdio_flags |= O_NONBLOCK;
      }
      if (status != ZX_OK) {
        return ERROR(status);
      }
      return fdio_flags;
    }
    case F_SETFL: {
      const fdio_ptr io = fd_to_io(fd);
      if (io == nullptr) {
        return ERRNO(EBADF);
      }
      GET_INT_ARG(fdio_flags);

      const fio::wire::OpenFlags flags = fdio_flags_to_zxio(fdio_flags & ~O_NONBLOCK);
      zx_status_t status = io->set_flags(flags);

      // Some remotes don't support setting flags; we
      // can adjust their local flags anyway if NONBLOCK
      // is the only bit being toggled.
      if (status == ZX_ERR_NOT_SUPPORTED && ((fdio_flags | O_NONBLOCK) == O_NONBLOCK)) {
        status = ZX_OK;
      }

      if (status != ZX_OK) {
        return ERROR(status);
      }
      if (fdio_flags & O_NONBLOCK) {
        io->ioflag() |= IOFLAG_NONBLOCK;
      } else {
        io->ioflag() &= ~IOFLAG_NONBLOCK;
      }
      return 0;
    }
    case F_GETOWN:
    case F_SETOWN:
      // TODO(kulakowski) Socket support.
      return ERRNO(ENOSYS);
    case F_GETLK:
    case F_SETLK:
    case F_SETLKW:
      // TODO(kulakowski) Advisory file locking support.
      return ERRNO(ENOSYS);
    default:
      return ERRNO(EINVAL);
  }

#undef GET_INT_ARG
}

__EXPORT
int flock(int fd, int operation) {
  zxio_advisory_lock_req_t lock_req;
  lock_req.wait = true;
  if (operation & LOCK_NB) {
    lock_req.wait = false;
    operation &= ~LOCK_NB;
  }
  switch (operation) {
    case LOCK_SH:
      lock_req.type = ADVISORY_LOCK_SHARED;
      break;
    case LOCK_EX:
      lock_req.type = ADVISORY_LOCK_EXCLUSIVE;
      break;
    case LOCK_UN:
      lock_req.type = ADVISORY_LOCK_UNLOCK;
      break;
    default: {
      return ERRNO(EINVAL);
    }
  }

  fdio_t* fdio = fdio_unsafe_fd_to_io(fd);
  if (fdio == nullptr) {
    return ERRNO(EBADF);
  }
  zxio_t* io = fdio_get_zxio(fdio);
  const zx_status_t status = zxio_get_ops(io)->advisory_lock(io, &lock_req);

  fdio_unsafe_release(fdio);
  return STATUS(status);
}

__EXPORT
off_t lseek(int fd, off_t offset, int whence) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }

  static_assert(SEEK_SET == ZXIO_SEEK_ORIGIN_START);
  static_assert(SEEK_CUR == ZXIO_SEEK_ORIGIN_CURRENT);
  static_assert(SEEK_END == ZXIO_SEEK_ORIGIN_END);

  size_t result = 0u;
  const zx_status_t status = zxio_seek(&io->zxio_storage().io, whence, offset, &result);
  if (status == ZX_ERR_WRONG_TYPE) {
    // Although 'ESPIPE' is a bit of a misnomer, it is the valid errno
    // for any fd which does not implement seeking (i.e., for pipes,
    // sockets, etc).
    return ERRNO(ESPIPE);
  }
  return status != ZX_OK ? ERROR(status) : static_cast<off_t>(result);
}

static int truncateat(int dirfd, const char* path, off_t len) {
  zx::result io = fdio_internal::open_at(dirfd, path, O_WRONLY, 0);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  if (len < 0) {
    return ERRNO(EINVAL);
  }
  return STATUS(io->truncate(static_cast<uint64_t>(len)));
}

__EXPORT
int truncate(const char* path, off_t len) { return truncateat(AT_FDCWD, path, len); }

__EXPORT
int ftruncate(int fd, off_t len) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  if (len < 0) {
    return ERRNO(EINVAL);
  }
  return STATUS(io->truncate(static_cast<uint64_t>(len)));
}

// Filesystem operations (such as rename and link) which act on multiple paths
// have some additional complexity on Zircon. These operations (eventually) act
// on two pairs of variables: a source parent vnode + name, and a target parent
// vnode + name. However, the loose coupling of these pairs can make their
// correspondence difficult, especially when accessing each parent vnode may
// involve crossing various filesystem boundaries.
//
// To resolve this problem, these kinds of operations involve:
// - Opening the source parent vnode directly.
// - Opening the target parent vnode directly, + acquiring a "vnode token".
// - Sending the real operation + names to the source parent vnode, along with
//   the "vnode token" representing the target parent vnode.
//
// Using zircon kernel primitives (cookies) to authenticate the vnode token, this
// allows these multi-path operations to mix absolute / relative paths and cross
// mount points with ease.
static int two_path_op_at(int olddirfd, const char* oldpath, int newdirfd, const char* newpath,
                          two_path_op fdio_t::*op_getter) {
  fdio_internal::NameBuffer oldname;
  zx::result io_oldparent =
      fdio_internal::opendir_containing_at(olddirfd, oldpath, &oldname, nullptr);
  if (io_oldparent.is_error()) {
    return ERROR(io_oldparent.status_value());
  }

  fdio_internal::NameBuffer newname;
  zx::result io_newparent =
      fdio_internal::opendir_containing_at(newdirfd, newpath, &newname, nullptr);
  if (io_newparent.is_error()) {
    return ERROR(io_newparent.status_value());
  }

  zx_handle_t token;
  const zx_status_t status = io_newparent->get_token(&token);
  if (status != ZX_OK) {
    return ERROR(status);
  }
  return STATUS((io_oldparent.value().get()->*op_getter)(oldname, token, newname));
}

__EXPORT
int renameat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath) {
  return two_path_op_at(olddirfd, oldpath, newdirfd, newpath, &fdio_t::rename);
}

__EXPORT
int rename(const char* oldpath, const char* newpath) {
  return two_path_op_at(AT_FDCWD, oldpath, AT_FDCWD, newpath, &fdio_t::rename);
}

__EXPORT
int linkat(int olddirfd, const char* oldpath, int newdirfd, const char* newpath, int flags) {
  // Accept AT_SYMLINK_FOLLOW, but ignore it because Fuchsia does not support symlinks yet.
  if (flags & ~AT_SYMLINK_FOLLOW) {
    return ERRNO(EINVAL);
  }

  return two_path_op_at(olddirfd, oldpath, newdirfd, newpath, &fdio_t::link);
}

__EXPORT
int link(const char* oldpath, const char* newpath) {
  return two_path_op_at(AT_FDCWD, oldpath, AT_FDCWD, newpath, &fdio_t::link);
}

__EXPORT
int unlink(const char* path) { return unlinkat(AT_FDCWD, path, 0); }

static int vopenat(int dirfd, const char* path, int flags, va_list args) {
  uint32_t mode = 0;
  if (flags & O_CREAT) {
    if (flags & O_DIRECTORY) {
      // The behavior of open with O_CREAT | O_DIRECTORY is underspecified
      // in POSIX. To help avoid programmer error, we explicitly disallow
      // the combination.
      return ERRNO(EINVAL);
    }
    mode = va_arg(args, uint32_t) & 0777;
  }
  zx::result io = fdio_internal::open_at(dirfd, path, flags, mode);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  if (flags & O_NONBLOCK) {
    io->ioflag() |= IOFLAG_NONBLOCK;
  }
  std::optional fd = bind_to_fd(io.value());
  if (fd.has_value()) {
    return fd.value();
  }
  return ERRNO(EMFILE);
}

__EXPORT
int open(const char* path, int flags, ...) {
  va_list ap;
  va_start(ap, flags);
  const int ret = vopenat(AT_FDCWD, path, flags, ap);
  va_end(ap);
  return ret;
}

__EXPORT
int openat(int dirfd, const char* path, int flags, ...) {
  va_list ap;
  va_start(ap, flags);
  const int ret = vopenat(dirfd, path, flags, ap);
  va_end(ap);
  return ret;
}

__EXPORT
int mkdir(const char* path, mode_t mode) { return mkdirat(AT_FDCWD, path, mode); }

__EXPORT
int mkdirat(int dirfd, const char* path, mode_t mode) {
  mode = (mode & 0777) | S_IFDIR;

  return STATUS(fdio_internal::open_at_ignore_eisdir(dirfd, path, O_RDONLY | O_CREAT | O_EXCL, mode)
                    .status_value());
}

__EXPORT
int fsync(int fd) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  return STATUS(zxio_sync(&io->zxio_storage().io));
}

__EXPORT
int fdatasync(int fd) {
  // TODO(smklein): fdatasync does not need to flush metadata under certain
  // circumstances -- however, for now, this implementation will appear
  // functionally the same (if a little slower).
  return fsync(fd);
}

__EXPORT
int syncfs(int fd) {
  // TODO(smklein): Currently, fsync syncs the entire filesystem, not just
  // the target file descriptor. These functions should use different sync
  // mechanisms, where fsync is more fine-grained.
  return fsync(fd);
}

__EXPORT
int fstat(int fd, struct stat* s) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  return STATUS(fdio_stat(io, s));
}

int fstatat(int dirfd, std::string_view filename, struct stat* s, int flags) {
  zx::result io = fdio_internal::open_at(dirfd, filename.data(), O_PATH, 0);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  return STATUS(fdio_stat(io.value(), s));
}

__EXPORT
int fstatat(int dirfd, const char* fn, struct stat* s, int flags) {
  return fstatat(dirfd, std::string_view(fn), s, flags);
}

__EXPORT
int stat(const char* fn, struct stat* s) { return fstatat(AT_FDCWD, fn, s, 0); }

__EXPORT
int lstat(const char* path, struct stat* buf) { return stat(path, buf); }

static constexpr char kUnreachable[] = "(unreachable)";

__EXPORT
char* realpath(const char* __restrict filename, char* __restrict resolved) {
  const std::string_view filename_view(filename);

  bool do_stat = true;
  fdio_internal::PathBuffer abspath_buffer;
  if (!cpp20::starts_with(filename_view, '/')) {
    // Convert 'filename' from a relative path to an absolute path.
    {
      const fbl::AutoLock cwd_lock(&fdio_cwd_lock);
      if (fdio_cwd_path.length() + 1 + filename_view.length() >= PATH_MAX) {
        errno = ENAMETOOLONG;
        return nullptr;
      }
      if (std::string_view{fdio_cwd_path} == kUnreachable) {
        do_stat = false;
      }
      abspath_buffer.Append(fdio_cwd_path);
    }
    abspath_buffer.Append('/');
    abspath_buffer.Append(filename);
    filename = abspath_buffer.c_str();
  }
  fdio_internal::PathBuffer clean_buffer;
  {
    bool is_dir;
    const bool cleaned = fdio_internal::CleanPath(filename, &clean_buffer, &is_dir);
    if (!cleaned) {
      errno = EINVAL;
      return nullptr;
    }
  }
  if (do_stat) {
    struct stat s;
    const int ret = fstatat(AT_FDCWD, clean_buffer, &s, 0);
    if (ret < 0) {
      return nullptr;
    }
  }
  return resolved ? strcpy(resolved, clean_buffer.c_str()) : strdup(clean_buffer.c_str());
}

static zx_status_t zx_utimens(const fdio_ptr& io, const std::timespec times[2], int flags) {
  zxio_node_attributes_t attr = {};

  zx_time_t modification_time;
  // Extract modify time.
  if (times == nullptr || times[1].tv_nsec == UTIME_NOW) {
    std::timespec ts;
    if (!std::timespec_get(&ts, TIME_UTC)) {
      return ZX_ERR_UNAVAILABLE;
    }
    modification_time = zx_time_from_timespec(ts);
  } else {
    modification_time = zx_time_from_timespec(times[1]);
  }

  if (times == nullptr || times[1].tv_nsec != UTIME_OMIT) {
    // For setattr, tell which fields are valid.
    ZXIO_NODE_ATTR_SET(attr, modification_time, modification_time);
  }

  // set time(s) on underlying object
  return io->set_attr(&attr);
}

__EXPORT
int utimensat(int dirfd, const char* path, const struct timespec times[2], int flags) {
  // TODO(orr): AT_SYMLINK_NOFOLLOW
  if ((flags & AT_SYMLINK_NOFOLLOW) != 0) {
    // Allow this flag - don't return an error.  Fuchsia does not support
    // symlinks, so don't break utilities (like tar) that use this flag.
  }
  zx::result io = fdio_internal::open_at_ignore_eisdir(dirfd, path, O_WRONLY, 0);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  return STATUS(zx_utimens(io.value(), times, 0));
}

__EXPORT
int futimens(int fd, const struct timespec times[2]) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  return STATUS(zx_utimens(io, times, 0));
}

static int socketpair_create(int fd[2], uint32_t options, int flags) {
  constexpr int allowed_flags = O_NONBLOCK | O_CLOEXEC;
  if (flags & ~allowed_flags) {
    return ERRNO(EINVAL);
  }

  zx::result pair = fdio_internal::pipe::create_pair(options);
  if (pair.is_error()) {
    return ERROR(pair.status_value());
  }
  auto [left, right] = pair.value();
  std::array<fdio_ptr, 2> ios = {left, right};

  if (flags & O_NONBLOCK) {
    left->ioflag() |= IOFLAG_NONBLOCK;
    right->ioflag() |= IOFLAG_NONBLOCK;
  }

  if (flags & O_CLOEXEC) {
    left->ioflag() |= IOFLAG_CLOEXEC;
    right->ioflag() |= IOFLAG_CLOEXEC;
  }

  size_t n = 0;

  const fbl::AutoLock lock(&fdio_lock);
  for (int i = 0; i < static_cast<int>(fdio_fdtab.size()); ++i) {
    if (fdio_fdtab[i].try_set(ios[n])) {
      fd[n] = i;
      n++;
      if (n == 2) {
        return 0;
      }
    }
  }
  return ERRNO(EMFILE);
}

__EXPORT
int pipe2(int pipefd[2], int flags) { return socketpair_create(pipefd, 0, flags); }

__EXPORT
int pipe(int pipefd[2]) { return pipe2(pipefd, 0); }

__EXPORT
int socketpair(int domain, int type, int protocol, int fd[2]) {
  uint32_t options = 0;

  // Ignore SOCK_CLOEXEC.
  type = type & ~SOCK_CLOEXEC;

  switch (type) {
    case SOCK_DGRAM:
      options = ZX_SOCKET_DATAGRAM;
      break;
    case SOCK_STREAM:
      options = ZX_SOCKET_STREAM;
      break;
    default:
      errno = EPROTOTYPE;
      return -1;
  }

  if (domain != AF_UNIX) {
    errno = EAFNOSUPPORT;
    return -1;
  }
  if (protocol != 0) {
    errno = EPROTONOSUPPORT;
    return -1;
  }

  return socketpair_create(fd, options, 0);
}

__EXPORT
int faccessat(int dirfd, const char* filename, int amode, int flag) {
  // First, check that the flags and amode are valid.
  const int allowed_flags = AT_EACCESS;
  if (flag & (~allowed_flags)) {
    return ERRNO(EINVAL);
  }

  // amode is allowed to be either a subset of this mask, or just F_OK.
  const int allowed_modes = R_OK | W_OK | X_OK;
  if (amode != F_OK && (amode & (~allowed_modes))) {
    return ERRNO(EINVAL);
  }

  if (amode == F_OK) {
    // Check that the file exists a la fstatat.
    zx::result io = fdio_internal::open_at(dirfd, filename, O_PATH, 0);
    if (io.is_error()) {
      return ERROR(io.status_value());
    }
    struct stat s;
    return STATUS(fdio_stat(io.value(), &s));
  }

  // Check that the file has each of the permissions in mode.
  // Ignore X_OK, since it does not apply to our permission model
  amode &= ~X_OK;
  uint32_t rights_flags = 0;
  switch (amode & (R_OK | W_OK)) {
    case R_OK:
      rights_flags = O_RDONLY;
      break;
    case W_OK:
      rights_flags = O_WRONLY;
      break;
    case R_OK | W_OK:
      rights_flags = O_RDWR;
      break;
  }
  return STATUS(
      fdio_internal::open_at_ignore_eisdir(dirfd, filename, rights_flags, 0).status_value());
}

__EXPORT
char* getcwd(char* buf, size_t size) {
  fdio_internal::PathBuffer tmp;
  if (buf == nullptr) {
    buf = tmp.data();
    size = tmp.capacity() + 1;  // +1 to include null-terminating character
  } else if (size == 0) {
    errno = EINVAL;
    return nullptr;
  }

  char* out = nullptr;
  {
    const fbl::AutoLock lock(&fdio_cwd_lock);
    const size_t len = fdio_cwd_path.length() + 1;  // +1 to include null-terminating character

    // |size| is inclusive of null-terminating character.
    if (len <= size) {
      memcpy(buf, fdio_cwd_path.data(), len);
      out = buf;
    } else {
      errno = ERANGE;
    }
  }

  if (out == tmp.data()) {
    out = strdup(tmp.c_str());
  }
  return out;
}

void fdio_chdir(fdio_ptr io, const char* path) {
  const fbl::AutoLock cwd_lock(&fdio_cwd_lock);
  fdio_internal::update_cwd_path(path);
  const fbl::AutoLock lock(&fdio_lock);
  fdio_cwd_handle.replace(std::move(io));
}

__EXPORT
int chdir(const char* path) {
  zx::result io = fdio_internal::open(path, O_RDONLY | O_DIRECTORY, 0);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }
  fdio_chdir(io.value(), path);
  return 0;
}

static bool resolve_path(const char* relative, fdio_internal::PathBuffer* out_resolved) {
  bool is_dir = false;
  if (relative[0] == '/') {
    return fdio_internal::CleanPath(relative, out_resolved, &is_dir);
  }

  fdio_internal::PathBuffer buffer;
  {
    const fbl::AutoLock cwd_lock(&fdio_cwd_lock);
    buffer.Append(fdio_cwd_path);
  }
  const size_t cwd_length = buffer.length();
  const size_t relative_length = strlen(relative);

  if (cwd_length + relative_length + 2 > PATH_MAX) {
    return false;
  }

  buffer.Append('/');
  buffer.Append(relative, relative_length);
  return fdio_internal::CleanPath(buffer.c_str(), out_resolved, &is_dir);
}

__EXPORT
int chroot(const char* path) {
  fdio_internal::PathBuffer root_path;
  const bool resolved = resolve_path(path, &root_path);
  if (!resolved) {
    return ERRNO(ENAMETOOLONG);
  }

  zx::result io = fdio_internal::open(root_path.c_str(), O_RDONLY | O_DIRECTORY, 0);
  if (io.is_error()) {
    return ERROR(io.status_value());
  }

  // Don't release under lock.
  fdio_ptr old_root = nullptr;
  {
    // We acquire the |cwd_lock| after calling |fdio_internal::open| because we cannot hold this
    // lock for the duration of the |fdio_internal::open| call. We are careful to pass an absolute
    // path to |fdio_internal::open| to ensure that we're using a consistent value for the |cwd|
    // throughout the |chroot| operation. If there is a concurrent call to |chdir| during the
    // |fdio_internal::open| operation, then we could end up in an inconsistent state, but the only
    // inconsistency would be the name we apply to the cwd session in the new chrooted namespace.
    const fbl::AutoLock cwd_lock(&fdio_cwd_lock);
    const fbl::AutoLock lock(&fdio_lock);

    const zx_status_t status = fdio_ns_set_root(fdio_root_ns, io.value().get());
    if (status != ZX_OK) {
      return ERROR(status);
    }
    old_root = fdio_root_handle.replace(io.value());

    // We are now committed to the root.

    // If the new root path is a prefix of the cwd path, then we can express the current cwd as a
    // path in the new root by trimming off the prefix. Otherwise, we no longer have a name for the
    // cwd.
    if (root_path.length() > 1) {
      const std::string_view cwd_view(fdio_cwd_path);
      if (cwd_view.find(root_path) == 0u && fdio_cwd_path[root_path.length()] == '/') {
        fdio_cwd_path.RemovePrefix(root_path.length());
      } else {
        fdio_cwd_path.Set(kUnreachable);
      }
    }
  }

  return 0;
}

struct __dirstream {
  mtx_t lock;

  // fd number of the directory under iteration.
  int fd;

  // The iterator object for reading directory entries.
  // This is only allocated during an iteration.
  std::unique_ptr<zxio_dirent_iterator_t> iterator;

  // A single directory entry returned to user; updated by |readdir|.
  struct dirent de = {};
};

static DIR* internal_opendir(int fd) {
  DIR* dir = new __dirstream;
  mtx_init(&dir->lock, mtx_plain);
  dir->fd = fd;
  return dir;
}

__EXPORT
DIR* opendir(const char* name) {
  const int fd = open(name, O_RDONLY | O_DIRECTORY);
  if (fd < 0)
    return nullptr;
  DIR* dir = internal_opendir(fd);
  if (dir == nullptr) {
    close_impl(fd, /*should_wait=*/true);
  }
  return dir;
}

__EXPORT
DIR* fdopendir(int fd) {
  // Check the fd for validity, but we'll just store the fd
  // number so we don't save the fdio_t pointer.
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    errno = EBADF;
    return nullptr;
  }
  // TODO(mcgrathr): Technically this should verify that it's
  // really a directory and fail with ENOTDIR if not.  But
  // that's not so easy to do, so don't bother for now.
  return internal_opendir(fd);
}

__EXPORT
int closedir(DIR* dir) {
  if (dir->iterator) {
    const fdio_ptr io = fd_to_io(dir->fd);
    io->dirent_iterator_destroy(dir->iterator.get());
    dir->iterator.reset();
  }
  close_impl(dir->fd, /*should_wait=*/false);
  delete dir;
  return 0;
}

static zx_status_t lazy_init_dirent_iterator(DIR* dir, const fdio_ptr io) {
  if (dir->iterator != nullptr) {
    return ZX_OK;
  }

  dir->iterator = std::make_unique<zxio_dirent_iterator_t>();
  const zx_status_t status = io->dirent_iterator_init(dir->iterator.get(), &io->zxio_storage().io);
  if (status != ZX_OK) {
    dir->iterator.reset();
  }

  return status;
}

__EXPORT
struct dirent* readdir(DIR* dir) {
  const fbl::AutoLock lock(&dir->lock);
  struct dirent* de = &dir->de;

  const fdio_ptr io = fd_to_io(dir->fd);

  if (const zx_status_t status = lazy_init_dirent_iterator(dir, io); status != ZX_OK) {
    errno = fdio_status_to_errno(status);
    return nullptr;
  }

  // We need space for the maximum possible filename plus a null terminator.
  static_assert(sizeof(de->d_name) >= ZXIO_MAX_FILENAME + 1);
  zxio_dirent_t entry = {.name = de->d_name};
  const zx_status_t status = io->dirent_iterator_next(dir->iterator.get(), &entry);
  if (status == ZX_ERR_NOT_FOUND) {
    // Reached the end.
    return nullptr;
  }
  if (status != ZX_OK) {
    errno = fdio_status_to_errno(status);
    return nullptr;
  }
  // zxio doesn't null terminate this string, so we do.
  de->d_name[entry.name_length] = '\0';
  de->d_ino = entry.has.id ? entry.id : fio::wire::kInoUnknown;
  de->d_off = 0;
  // The d_reclen field is nonstandard, but existing code
  // may expect it to be useful as an upper bound on the
  // length of the name.
  de->d_reclen = static_cast<uint16_t>(offsetof(struct dirent, d_name) + entry.name_length + 1);
  if (entry.has.protocols) {
    de->d_type = ([](zxio_node_protocols_t protocols) -> unsigned char {
      if (protocols & ZXIO_NODE_PROTOCOL_DIRECTORY) {
        return DT_DIR;
      }
      if (protocols & ZXIO_NODE_PROTOCOL_FILE) {
        return DT_REG;
      }
      if (protocols & ZXIO_NODE_PROTOCOL_SYMLINK) {
        return DT_LNK;
      }
      if (protocols & ZXIO_NODE_PROTOCOL_CONNECTOR) {
        // There is no good analogue for FIDL services in POSIX land.
        return DT_UNKNOWN;
      }
      return DT_UNKNOWN;
    })(entry.protocols);
  } else {
    de->d_type = DT_UNKNOWN;
  }
  return de;
}

__EXPORT
void rewinddir(DIR* dir) {
  const fbl::AutoLock lock(&dir->lock);
  const fdio_ptr io = fd_to_io(dir->fd);

  // Always try to initialize and rewind the directory stream. If a client were to create |dir| via
  // |dup()|ing another file descriptor and then |fdopendir()|, |dir->iterator| will be
  // uninitialized but the underlying connection may be shared with the original descriptor. For
  // remote connections, the state of the directory stream pointer is held within the connection
  // (the connection is stateful), so |dir| will share the directory stream pointer with the
  // original file descriptor. Clients who call |rewinddir()| are expecting for that pointer to be
  // rewound.
  //
  // TODO(https://fxbug.dev/42071039): Remove this when separate |fuchsia.io/DirectoryIterator|s are
  // used to back different zxio iterators.
  if (const zx_status_t status = lazy_init_dirent_iterator(dir, io); status != ZX_OK) {
    // This function should not modify the errno and has no way to propagate error, so drop it.
    return;
  }

  io->dirent_iterator_rewind(dir->iterator.get());
}

__EXPORT
int dirfd(DIR* dir) { return dir->fd; }

__EXPORT
int isatty(int fd) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    errno = EBADF;
    return 0;
  }

  bool tty;
  const zx_status_t status = zxio_isatty(&io->zxio_storage().io, &tty);
  if (status != ZX_OK) {
    return ERROR(status);
  }
  if (tty) {
    return 1;
  }
  errno = ENOTTY;
  return 0;
}

__EXPORT
mode_t umask(mode_t mask) {
  mode_t oldmask;
  const fbl::AutoLock lock(&fdio_lock);
  oldmask = __fdio_global_state.umask;
  __fdio_global_state.umask = mask & 0777;
  return oldmask;
}

// TODO: getrlimit(RLIMIT_NOFILE, ...)
constexpr size_t kMaxPollNfds = 1024;

__EXPORT
int ppoll(struct pollfd* fds, nfds_t n, const struct timespec* timeout_ts,
          const sigset_t* sigmask) {
  if (sigmask) {
    return ERRNO(ENOSYS);
  }
  if (n > kMaxPollNfds || n < 0) {
    return ERRNO(EINVAL);
  }

  auto timeout = zx::duration::infinite();
  if (timeout_ts) {
    // Match Linux's validation strategy. See:
    //
    // https://github.com/torvalds/linux/blob/f40ddce/include/linux/time64.h#L84-L96
    //
    // https://github.com/torvalds/linux/blob/f40ddce/include/vdso/time64.h#L11
    if (timeout_ts->tv_sec < 0 || timeout_ts->tv_nsec < 0 || timeout_ts->tv_nsec >= 1000000000L) {
      return ERRNO(EINVAL);
    }
    timeout = zx::duration(*timeout_ts);
  }

  if (n == 0) {
    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout.to_nsecs()));
    return 0;
  }

  // TODO(https://fxbug.dev/42150923): investigate VLA alternatives.
  fdio_ptr ios[n];
  // |items| is the set of handles to wait on and will contain up to |n| entries. Some
  // FDs do not contain a handle or do not have any applicable Zircon signals, so we
  // won't populate an entry in |items| for these FDs. Thus |items| may have fewer
  // entries than |n|.
  zx_wait_item_t items[n];
  // |nitems| tracks the number of populated entries in |items|.
  size_t nitems = 0;
  // |items_set| keeps track of which entries in |fds| have a corresponding
  // entry in |items|. It is true for FDs that have an entry in |items|.
  bool items_set[n];

  for (nfds_t i = 0; i < n; ++i) {
    auto& pfd = fds[i];
    auto& io = ios[i];
    io = fd_to_io(pfd.fd);
    if (io == nullptr) {
      // fd is not opened
      pfd.revents = POLLNVAL;
      items_set[i] = false;
      continue;
    }

    zx_handle_t h = ZX_HANDLE_INVALID;
    zx_signals_t sigs = ZX_SIGNAL_NONE;
    io->wait_begin(pfd.events, &h, &sigs);
    if (sigs == ZX_SIGNAL_NONE) {
      // Skip waiting on this fd as there are no waitable signals.
      uint32_t events;
      io->wait_end(sigs, &events);
      pfd.revents = static_cast<int16_t>(events);
      items_set[i] = false;
      continue;
    }
    if (h == ZX_HANDLE_INVALID) {
      return ERROR(ZX_ERR_INVALID_ARGS);
    }
    pfd.revents = 0;
    items[nitems] = {
        .handle = h,
        .waitfor = sigs,
    };
    items_set[i] = true;
    ++nitems;
  }

  if (nitems != 0) {
    const zx_status_t status =
        zx::handle::wait_many(items, static_cast<uint32_t>(nitems), zx::deadline_after(timeout));
    // pending signals could be reported on ZX_ERR_TIMED_OUT case as well
    if (status != ZX_OK && status != ZX_ERR_TIMED_OUT) {
      return ERROR(status);
    }
  }

  int nfds = 0;
  // |items_index| is the index into the next entry in the |items| array. As not
  // all FDs in the wait set correspond to a kernel wait, the |items_index|
  // value corresponding to a particular FD can be lower than the index of that
  // FD in the |fds| array.
  size_t items_index = 0;
  for (nfds_t i = 0; i < n; ++i) {
    auto& pfd = fds[i];
    auto& io = ios[i];

    if (items_set[i]) {
      uint32_t events;
      io->wait_end(items[items_index].pending, &events);
      pfd.revents = static_cast<int16_t>(events);
      ++items_index;
    }
    // Mask unrequested events. Avoid clearing events that are ignored in pollfd::events.
    pfd.revents &= static_cast<int16_t>(pfd.events | POLLNVAL | POLLHUP | POLLERR);
    if (pfd.revents != 0) {
      ++nfds;
    }
  }

  return nfds;
}

__EXPORT
int poll(struct pollfd* fds, nfds_t n, int timeout) {
  struct timespec timeout_ts = {
      .tv_sec = timeout / 1000,
      .tv_nsec = (timeout % 1000) * 1000000,
  };
  struct timespec* ts = timeout >= 0 ? &timeout_ts : nullptr;
  return ppoll(fds, n, ts, nullptr);
}

__EXPORT
int select(int n, fd_set* __restrict rfds, fd_set* __restrict wfds, fd_set* __restrict efds,
           struct timeval* __restrict tv) {
  if (n > FD_SETSIZE || n < 0) {
    return ERRNO(EINVAL);
  }

  auto timeout = zx::duration::infinite();
  if (tv) {
    if (tv->tv_sec < 0 || tv->tv_usec < 0) {
      return ERRNO(EINVAL);
    }
    timeout = zx::sec(tv->tv_sec) + zx::usec(tv->tv_usec);
  }

  if (n == 0) {
    std::this_thread::sleep_for(std::chrono::nanoseconds(timeout.to_nsecs()));
    return 0;
  }

  // TODO(https://fxbug.dev/42150923): investigate VLA alternatives.
  fdio_ptr ios[n];
  zx_wait_item_t items[n];
  size_t nitems = 0;

  for (int fd = 0; fd < n; ++fd) {
    uint32_t events = 0;
    if (rfds && FD_ISSET(fd, rfds))
      events |= POLLIN;
    if (wfds && FD_ISSET(fd, wfds))
      events |= POLLOUT;
    if (efds && FD_ISSET(fd, efds))
      events |= POLLERR;

    auto& io = ios[fd];
    if (events == 0) {
      io = nullptr;
      continue;
    }

    io = fd_to_io(fd);
    if (io == nullptr) {
      return ERROR(ZX_ERR_INVALID_ARGS);
    }

    zx_handle_t h;
    zx_signals_t sigs;
    io->wait_begin(events, &h, &sigs);
    if (h == ZX_HANDLE_INVALID) {
      return ERROR(ZX_ERR_INVALID_ARGS);
    }
    items[nitems] = {
        .handle = h,
        .waitfor = sigs,
    };
    ++nitems;
  }

  const zx_status_t status =
      zx::handle::wait_many(items, static_cast<uint32_t>(nitems), zx::deadline_after(timeout));
  // pending signals could be reported on ZX_ERR_TIMED_OUT case as well
  if (status != ZX_OK && status != ZX_ERR_TIMED_OUT) {
    return ERROR(status);
  }

  int nfds = 0;
  size_t j = 0;
  for (int fd = 0; fd < n; fd++) {
    auto io = ios[fd];
    if (io == nullptr) {
      // skip an invalid entry
      continue;
    }
    if (j < nitems) {
      uint32_t events = 0;
      io->wait_end(items[j].pending, &events);
      if (rfds && FD_ISSET(fd, rfds)) {
        if (events & POLLIN) {
          ++nfds;
        } else {
          FD_CLR(fd, rfds);
        }
      }
      if (wfds && FD_ISSET(fd, wfds)) {
        if (events & POLLOUT) {
          ++nfds;
        } else {
          FD_CLR(fd, wfds);
        }
      }
      if (efds && FD_ISSET(fd, efds)) {
        if (events & POLLERR) {
          ++nfds;
        } else {
          FD_CLR(fd, efds);
        }
      }
    } else {
      if (rfds) {
        FD_CLR(fd, rfds);
      }
      if (wfds) {
        FD_CLR(fd, wfds);
      }
      if (efds) {
        FD_CLR(fd, efds);
      }
    }
    ++j;
  }

  return nfds;
}

__EXPORT
int ioctl(int fd, int req, ...) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }

  va_list ap;
  va_start(ap, req);
  const Errno e = io->posix_ioctl(req, ap);
  va_end(ap);
  if (e.is_error()) {
    return ERRNO(e.e);
  }
  return 0;
}

__EXPORT
ssize_t sendto(int fd, const void* buf, size_t buflen, int flags, const struct sockaddr* addr,
               socklen_t addrlen) {
  struct iovec iov;
  iov.iov_base = const_cast<void*>(buf);
  iov.iov_len = buflen;

  struct msghdr msg = {};
  msg.msg_name = const_cast<struct sockaddr*>(addr);
  msg.msg_namelen = addrlen;
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  return sendmsg(fd, &msg, flags);
}

__EXPORT
ssize_t recvfrom(int fd, void* __restrict buf, size_t buflen, int flags,
                 struct sockaddr* __restrict addr, socklen_t* __restrict addrlen) {
  struct iovec iov;
  iov.iov_base = buf;
  iov.iov_len = buflen;

  struct msghdr msg = {};
  msg.msg_name = addr;
  if (addrlen != nullptr) {
    msg.msg_namelen = *addrlen;
  }
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  const ssize_t n = recvmsg(fd, &msg, flags);
  if (addrlen != nullptr) {
    *addrlen = msg.msg_namelen;
  }
  return n;
}

__EXPORT
ssize_t sendmsg(int fd, const struct msghdr* msg, int flags) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  auto& ioflag = io->ioflag();
  // The |flags| are typically used to express intent *not* to issue SIGPIPE
  // via MSG_NOSIGNAL. Applications use this frequently to avoid having to
  // install additional signal handlers to handle cases where connection has
  // been closed by remote end. Signals aren't a notion on Fuchsia, so this
  // flag can be safely ignored.
  flags &= ~MSG_NOSIGNAL;
  const bool blocking = ((ioflag & IOFLAG_NONBLOCK) | (flags & MSG_DONTWAIT)) == 0;
  flags &= ~MSG_DONTWAIT;
  const zx::time deadline = zx::deadline_after(io->sndtimeo());
  for (;;) {
    size_t actual;
    int16_t out_code;
    zx_status_t status = io->sendmsg(msg, flags, &actual, &out_code);
    if (blocking) {
      switch (status) {
        case ZX_OK:
          if (out_code != EWOULDBLOCK) {
            break;
          }
          __FALLTHROUGH;
        case ZX_ERR_SHOULD_WAIT:
          status = fdio_wait(io, FDIO_EVT_WRITABLE, deadline, nullptr);
          if (status == ZX_OK) {
            continue;
          }
          if (status == ZX_ERR_TIMED_OUT) {
            status = ZX_ERR_SHOULD_WAIT;
          }
      }
    }
    if (status != ZX_OK) {
      if (status == ZX_ERR_OUT_OF_RANGE) {
        errno = EMSGSIZE;
        return -1;
      }
      return ERROR(status);
    }
    if (out_code) {
      return ERRNO(out_code);
    }
    return actual;
  }
}

__EXPORT
ssize_t recvmsg(int fd, struct msghdr* msg, int flags) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  auto& ioflag = io->ioflag();
  const bool blocking = ((ioflag & IOFLAG_NONBLOCK) | (flags & MSG_DONTWAIT)) == 0;
  flags &= ~MSG_DONTWAIT;
  const zx::time deadline = zx::deadline_after(io->rcvtimeo());
  for (;;) {
    size_t actual;
    int16_t out_code;
    zx_status_t status = io->recvmsg(msg, flags, &actual, &out_code);
    if (blocking) {
      switch (status) {
        case ZX_OK:
          if (out_code != EWOULDBLOCK) {
            break;
          }
          __FALLTHROUGH;
        case ZX_ERR_SHOULD_WAIT:
          status = fdio_wait(io, FDIO_EVT_READABLE, deadline, nullptr);
          if (status == ZX_OK) {
            continue;
          }
          if (status == ZX_ERR_TIMED_OUT) {
            status = ZX_ERR_SHOULD_WAIT;
          }
      }
    }
    if (status != ZX_OK) {
      return ERROR(status);
    }
    if (out_code) {
      return ERRNO(out_code);
    }
    return actual;
  }
}

__EXPORT
int shutdown(int fd, int how) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }

  zxio_shutdown_options_t options;
  switch (how) {
    case SHUT_RD:
      options = ZXIO_SHUTDOWN_OPTIONS_READ;
      break;
    case SHUT_WR:
      options = ZXIO_SHUTDOWN_OPTIONS_WRITE;
      break;
    case SHUT_RDWR:
      options = ZXIO_SHUTDOWN_OPTIONS_READ | ZXIO_SHUTDOWN_OPTIONS_WRITE;
      break;
    default:
      return ERRNO(EINVAL);
  }

  int16_t out_code;
  const zx_status_t status = zxio_shutdown(&io->zxio_storage().io, options, &out_code);
  if (status != ZX_OK) {
    return ERROR(status);
  }
  if (out_code) {
    return ERRNO(out_code);
  }
  return out_code;
}

// The common denominator between the Linux-y fstatfs and the POSIX
// fstatvfs, which align on most fields. The fs version is more easily
// computed from the fuchsia_io::FilesystemInfo, so this takes a struct statfs.
static int fs_stat(int fd, struct statfs* buf) {
  const fdio_ptr io = fd_to_io(fd);
  if (io == nullptr) {
    return ERRNO(EBADF);
  }
  zx_handle_t handle;
  const zx_status_t status = io->borrow_channel(&handle);
  if (status != ZX_OK) {
    return ERROR(status);
  }
  auto directory = fidl::UnownedClientEnd<fuchsia_io::Directory>(handle);
  if (!directory.is_valid()) {
    return ERRNO(ENOTSUP);
  }
  auto result = fidl::WireCall(directory)->QueryFilesystem();
  if (result.status() != ZX_OK) {
    return ERROR(result.status());
  }
  fidl::WireResponse<fuchsia_io::Directory::QueryFilesystem>* response = result.Unwrap();
  if (response->s != ZX_OK) {
    return ERROR(response->s);
  }
  fuchsia_io::wire::FilesystemInfo* info = response->info.get();
  if (info == nullptr) {
    return ERRNO(EIO);
  }

  info->name[fuchsia_io::wire::kMaxFsNameBuffer - 1] = '\0';

  struct statfs stats = {};

  if (info->block_size) {
    stats.f_bsize = info->block_size;
    stats.f_blocks = info->total_bytes / stats.f_bsize;
    stats.f_bfree = stats.f_blocks - info->used_bytes / stats.f_bsize;
  }
  stats.f_bavail = stats.f_bfree;
  stats.f_files = info->total_nodes;
  stats.f_ffree = info->total_nodes - info->used_nodes;
  stats.f_namelen = info->max_filename_size;
  stats.f_type = info->fs_type;
  stats.f_fsid.__val[0] = static_cast<int>(info->fs_id & 0xffffffff);
  stats.f_fsid.__val[1] = static_cast<int>(info->fs_id >> 32u);

  *buf = stats;
  return 0;
}

__EXPORT
int fstatfs(int fd, struct statfs* buf) { return fs_stat(fd, buf); }

__EXPORT
int statfs(const char* path, struct statfs* buf) {
  const int fd = open(path, O_RDONLY | O_CLOEXEC);
  if (fd < 0) {
    return fd;
  }
  const int rv = fstatfs(fd, buf);
  close_impl(fd, /*should_wait=*/true);
  return rv;
}

__EXPORT
int fstatvfs(int fd, struct statvfs* buf) {
  struct statfs stats = {};
  const int result = fs_stat(fd, &stats);
  if (result >= 0) {
    struct statvfs vstats = {};

    // The following fields are 1-1 between the Linux statfs
    // definition and the POSIX statvfs definition.
    vstats.f_bsize = stats.f_bsize;
    vstats.f_blocks = stats.f_blocks;
    vstats.f_bfree = stats.f_bfree;
    vstats.f_bavail = stats.f_bavail;

    vstats.f_files = stats.f_files;
    vstats.f_ffree = stats.f_ffree;

    vstats.f_flag = stats.f_flags;

    vstats.f_namemax = stats.f_namelen;

    // The following fields have slightly different semantics
    // between the two.

    // The two have different representations for the fsid.
    vstats.f_fsid = stats.f_fsid.__val[0] + ((static_cast<uint64_t>(stats.f_fsid.__val[1])) << 32);

    // The statvfs "fragment size" value best corresponds to the
    // FilesystemInfo "block size" value.
    vstats.f_frsize = stats.f_bsize;

    // The statvfs struct distinguishes between available files,
    // and available files for unprivileged processes. fuchsia.io
    // makes no such distinction, so use the same value for both.
    vstats.f_favail = stats.f_ffree;

    // Finally, the f_type and f_spare fields on struct statfs
    // have no equivalent for struct statvfs.

    *buf = vstats;
  }
  return result;
}

__EXPORT
int statvfs(const char* path, struct statvfs* buf) {
  const int fd = open(path, O_RDONLY | O_CLOEXEC);
  if (fd < 0) {
    return fd;
  }
  const int rv = fstatvfs(fd, buf);
  close_impl(fd, /*should_wait=*/true);
  return rv;
}

// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/libc.h
extern "C" __EXPORT int _fd_open_max(void) { return FDIO_MAX_FD; }

// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/libc.h
extern "C" __EXPORT void* _fd_get_context(int fd) { return fdio_unsafe_fd_to_io(fd); }

// extern "C" is required here, since the corresponding declaration is in an internal musl header:
// zircon/third_party/ulib/musl/src/internal/libc.h
extern "C" __EXPORT void _fd_release_context(void* context) {
  assert(context != nullptr);
  fdio_unsafe_release(static_cast<fdio_t*>(context));
}
