| // Copyright 2020 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/fdio_unistd.h" | 
 |  | 
 | #include <fbl/auto_lock.h> | 
 |  | 
 | #include "sdk/lib/fdio/internal.h" | 
 |  | 
 | std::optional<int> bind_to_fd(const fbl::RefPtr<fdio>& io) { | 
 |   fbl::AutoLock lock(&fdio_lock); | 
 |   return bind_to_fd_locked(io); | 
 | } | 
 |  | 
 | std::optional<int> bind_to_fd_locked(const fbl::RefPtr<fdio>& io) { | 
 |   for (size_t fd = 0; fd < fdio_fdtab.size(); ++fd) { | 
 |     if (fdio_fdtab[fd].try_set(io)) { | 
 |       return fd; | 
 |     } | 
 |   } | 
 |   return std::nullopt; | 
 | } | 
 |  | 
 | namespace { | 
 |  | 
 | fdio_slot* slot_locked(int fd) __TA_REQUIRES(fdio_lock) { | 
 |   if ((fd < 0) || (fd >= FDIO_MAX_FD)) { | 
 |     return nullptr; | 
 |   } | 
 |   return &fdio_fdtab[fd]; | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | fbl::RefPtr<fdio> fd_to_io(int fd) { | 
 |   fbl::AutoLock lock(&fdio_lock); | 
 |   return fd_to_io_locked(fd); | 
 | } | 
 |  | 
 | fbl::RefPtr<fdio> fd_to_io_locked(int fd) { | 
 |   fdio_slot* slot = slot_locked(fd); | 
 |   if (slot == nullptr) { | 
 |     return nullptr; | 
 |   } | 
 |   return slot->get(); | 
 | } | 
 |  | 
 | fbl::RefPtr<fdio> unbind_from_fd(int fd) { | 
 |   fbl::AutoLock lock(&fdio_lock); | 
 |   return unbind_from_fd_locked(fd); | 
 | } | 
 |  | 
 | fbl::RefPtr<fdio> unbind_from_fd_locked(int fd) __TA_REQUIRES(fdio_lock) { | 
 |   fdio_slot* slot = slot_locked(fd); | 
 |   if (slot == nullptr) { | 
 |     return nullptr; | 
 |   } | 
 |   return slot->release(); | 
 | } | 
 |  | 
 | // TODO(fxbug.dev/30921): determine complete correct mapping | 
 | int fdio_status_to_errno(zx_status_t status) { | 
 |   switch (status) { | 
 |     case ZX_ERR_NOT_FOUND: | 
 |       return ENOENT; | 
 |     case ZX_ERR_NO_MEMORY: | 
 |       return ENOMEM; | 
 |     case ZX_ERR_INVALID_ARGS: | 
 |       return EINVAL; | 
 |     case ZX_ERR_BUFFER_TOO_SMALL: | 
 |       return EINVAL; | 
 |     case ZX_ERR_TIMED_OUT: | 
 |       return ETIMEDOUT; | 
 |     case ZX_ERR_UNAVAILABLE: | 
 |       return EBUSY; | 
 |     case ZX_ERR_ALREADY_EXISTS: | 
 |       return EEXIST; | 
 |     case ZX_ERR_PEER_CLOSED: | 
 |       return EPIPE; | 
 |     case ZX_ERR_BAD_STATE: | 
 |       return EPIPE; | 
 |     case ZX_ERR_BAD_PATH: | 
 |       return ENAMETOOLONG; | 
 |     case ZX_ERR_IO: | 
 |       return EIO; | 
 |     case ZX_ERR_NOT_FILE: | 
 |       return EISDIR; | 
 |     case ZX_ERR_NOT_DIR: | 
 |       return ENOTDIR; | 
 |     case ZX_ERR_NOT_SUPPORTED: | 
 |       return ENOTSUP; | 
 |     case ZX_ERR_WRONG_TYPE: | 
 |       return ENOTSUP; | 
 |     case ZX_ERR_OUT_OF_RANGE: | 
 |       return EINVAL; | 
 |     case ZX_ERR_NO_RESOURCES: | 
 |       return ENOMEM; | 
 |     case ZX_ERR_BAD_HANDLE: | 
 |       return EBADF; | 
 |     case ZX_ERR_ACCESS_DENIED: | 
 |       return EACCES; | 
 |     case ZX_ERR_SHOULD_WAIT: | 
 |       return EAGAIN; | 
 |     case ZX_ERR_FILE_BIG: | 
 |       return EFBIG; | 
 |     case ZX_ERR_NO_SPACE: | 
 |       return ENOSPC; | 
 |     case ZX_ERR_NOT_EMPTY: | 
 |       return ENOTEMPTY; | 
 |     case ZX_ERR_IO_REFUSED: | 
 |       return ECONNREFUSED; | 
 |     case ZX_ERR_IO_INVALID: | 
 |       return EIO; | 
 |     case ZX_ERR_CANCELED: | 
 |       return EBADF; | 
 |     case ZX_ERR_PROTOCOL_NOT_SUPPORTED: | 
 |       return EPROTONOSUPPORT; | 
 |     case ZX_ERR_ADDRESS_UNREACHABLE: | 
 |       return ENETUNREACH; | 
 |     case ZX_ERR_ADDRESS_IN_USE: | 
 |       return EADDRINUSE; | 
 |     case ZX_ERR_NOT_CONNECTED: | 
 |       return ENOTCONN; | 
 |     case ZX_ERR_CONNECTION_REFUSED: | 
 |       return ECONNREFUSED; | 
 |     case ZX_ERR_CONNECTION_RESET: | 
 |       return ECONNRESET; | 
 |     case ZX_ERR_CONNECTION_ABORTED: | 
 |       return ECONNABORTED; | 
 |  | 
 |     // No specific translation, so return a generic value. | 
 |     default: | 
 |       return EIO; | 
 |   } | 
 | } |