Skip to content
This repository has been archived by the owner on Feb 25, 2025. It is now read-only.

Commit

Permalink
Avoid channel clone (#43181)
Browse files Browse the repository at this point in the history
Use fdio_fd_transfer instead of fdio_fd_clone.
  • Loading branch information
tamird authored Jun 26, 2023
1 parent 9768d16 commit 0da06de
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 47 deletions.
1 change: 1 addition & 0 deletions shell/platform/fuchsia/dart-pkg/zircon/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ source_set("zircon") {
]

deps = [
"$fuchsia_sdk_root/fidl:fuchsia.io",
"$fuchsia_sdk_root/pkg:async-cpp",
"$fuchsia_sdk_root/pkg:async-default",
"$fuchsia_sdk_root/pkg:async-loop-cpp",
Expand Down
98 changes: 53 additions & 45 deletions shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

#include <array>

#include <fcntl.h>
#include <fuchsia/io/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/io.h>
#include <lib/fdio/limits.h>
#include <lib/fdio/namespace.h>
Expand Down Expand Up @@ -172,17 +173,25 @@ fdio_ns_t* GetNamespace() {
return reinterpret_cast<fdio_ns_t*>(fdio_ns_ptr);
}

fml::UniqueFD FdFromPath(std::string path) {
// Get a VMO for the file.
fdio_ns_t* ns = reinterpret_cast<fdio_ns_t*>(GetNamespace());
fml::UniqueFD dirfd(fdio_ns_opendir(ns));
if (!dirfd.is_valid())
return fml::UniqueFD();

const char* c_path = path.c_str();
if (path.length() > 0 && c_path[0] == '/')
c_path = &c_path[1];
return fml::UniqueFD(openat(dirfd.get(), c_path, O_RDONLY));
zx_status_t FdFromPath(const char* path, fml::UniqueFD& fd) {
fml::UniqueFD dir_fd(fdio_ns_opendir(GetNamespace()));
if (!dir_fd.is_valid()) {
// TODO: can we return errno?
return ZX_ERR_IO;
}
if (path != nullptr && *path == '/') {
path++;
}
int raw_fd;
if (zx_status_t status = fdio_open_fd_at(
dir_fd.get(), path,
static_cast<uint32_t>(fuchsia::io::OpenFlags::RIGHT_READABLE),
&raw_fd);
status != ZX_OK) {
return status;
}
fd.reset(raw_fd);
return ZX_OK;
}

} // namespace
Expand All @@ -207,36 +216,30 @@ zx_status_t System::ConnectToService(std::string path,
channel->ReleaseHandle());
}

zx::channel System::CloneChannelFromFileDescriptor(int fd) {
zx::handle handle;
zx_status_t status = fdio_fd_clone(fd, handle.reset_and_get_address());
if (status != ZX_OK)
return zx::channel();

zx_info_handle_basic_t info = {};
status =
handle.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), NULL, NULL);

if (status != ZX_OK || info.type != ZX_OBJ_TYPE_CHANNEL)
return zx::channel();

return zx::channel(handle.release());
}

Dart_Handle System::ChannelFromFile(std::string path) {
fml::UniqueFD fd = FdFromPath(path);
if (!fd.is_valid()) {
return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_IO));
fml::UniqueFD fd;
if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
return ConstructDartObject(kHandleResult, ToDart(status));
}

// Get channel from fd.
zx::channel channel = CloneChannelFromFileDescriptor(fd.get());
if (!channel) {
return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_IO));
zx::handle handle;
if (zx_status_t status =
fdio_fd_transfer(fd.release(), handle.reset_and_get_address());
status != ZX_OK) {
return ConstructDartObject(kHandleResult, ToDart(status));
}
zx_info_handle_basic_t info;
if (zx_status_t status = handle.get_info(ZX_INFO_HANDLE_BASIC, &info,
sizeof(info), nullptr, nullptr);
status != ZX_OK) {
return ConstructDartObject(kHandleResult, ToDart(status));
}
if (info.type != ZX_OBJ_TYPE_CHANNEL) {
return ConstructDartObject(kHandleResult, ToDart(ZX_ERR_WRONG_TYPE));
}

return ConstructDartObject(kHandleResult, ToDart(ZX_OK),
ToDart(Handle::Create(channel.release())));
ToDart(Handle::Create(handle.release())));
}

zx_status_t System::ChannelWrite(fml::RefPtr<Handle> channel,
Expand Down Expand Up @@ -451,20 +454,25 @@ Dart_Handle System::VmoCreate(uint64_t size, uint32_t options) {
}

Dart_Handle System::VmoFromFile(std::string path) {
fml::UniqueFD fd = FdFromPath(path);
if (!fd.is_valid())
return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
fml::UniqueFD fd;
if (zx_status_t status = FdFromPath(path.c_str(), fd); status != ZX_OK) {
return ConstructDartObject(kHandleResult, ToDart(status));
}

struct stat stat_struct;
if (fstat(fd.get(), &stat_struct) == -1)
if (fstat(fd.get(), &stat_struct) != 0) {
// TODO: can we return errno?
return ConstructDartObject(kFromFileResult, ToDart(ZX_ERR_IO));
zx_handle_t vmo = ZX_HANDLE_INVALID;
zx_status_t status = fdio_get_vmo_clone(fd.get(), &vmo);
if (status != ZX_OK)
}
zx::vmo vmo;
if (zx_status_t status =
fdio_get_vmo_clone(fd.get(), vmo.reset_and_get_address());
status != ZX_OK) {
return ConstructDartObject(kFromFileResult, ToDart(status));
}

return ConstructDartObject(kFromFileResult, ToDart(status),
ToDart(Handle::Create(vmo)),
return ConstructDartObject(kFromFileResult, ToDart(ZX_OK),
ToDart(Handle::Create(vmo.release())),
ToDart(stat_struct.st_size));
}

Expand Down
2 changes: 0 additions & 2 deletions shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ class System : public fml::RefCountedThreadSafe<System>,

private:
static void VmoMapFinalizer(void* isolate_callback_data, void* peer);

static zx::channel CloneChannelFromFileDescriptor(int fd);
};

} // namespace dart
Expand Down

0 comments on commit 0da06de

Please sign in to comment.