blob: e5e46b83aeefb65a66c4aabc255f1a1b08fbc873 [file] [log] [blame]
// Copyright 2019 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 <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <zircon/assert.h>
#include "internal.h"
__EXPORT
zx_status_t fdio_fd_create(zx_handle_t handle, int* fd_out) {
fdio_t* io = nullptr;
zx_status_t status = fdio_create(handle, &io);
if (status != ZX_OK) {
return status;
}
int fd = fdio_bind_to_fd(io, -1, 0);
if (fd < 0) {
fdio_release(io);
return ZX_ERR_BAD_STATE;
}
*fd_out = fd;
return ZX_OK;
}
__EXPORT
zx_status_t fdio_cwd_clone(zx_handle_t* out_handle) {
auto ops = fdio_get_ops(fdio_cwd_handle);
return ops->clone(fdio_cwd_handle, out_handle);
}
__EXPORT
zx_status_t fdio_fd_clone(int fd, zx_handle_t* out_handle) {
zx_status_t status;
fdio_t* io = nullptr;
if ((io = fdio_unsafe_fd_to_io(fd)) == nullptr) {
return ZX_ERR_INVALID_ARGS;
}
// TODO(fxbug.dev/30920): implement/honor close-on-exec flag
status = fdio_get_ops(io)->clone(io, out_handle);
fdio_release(io);
return status;
}
__EXPORT
zx_status_t fdio_fd_transfer(int fd, zx_handle_t* out_handle) {
zx_status_t status;
fdio_t* io = nullptr;
status = fdio_unbind_from_fd(fd, &io);
if (status != ZX_OK) {
return status;
}
// Unwrapping here is safe, because |fdio_unbind_from_fd| will only succeed
// if we have the last unique reference to |io|.
status = fdio_get_ops(io)->unwrap(io, out_handle);
fdio_release(io);
return status;
}