blob: 06772b6da0ca08840ed2acc12fb66c9fa8ce59e6 [file] [log] [blame]
// Copyright 2018 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 <fuchsia/io/c/fidl.h>
#include <lib/zxio/inception.h>
#include <lib/zxio/ops.h>
#include <string.h>
#include <zircon/syscalls.h>
static zx_status_t zxio_remote_release(zxio_t* io, zx_handle_t* out_node) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_handle_t node = rio->control;
rio->control = ZX_HANDLE_INVALID;
if (rio->event != ZX_HANDLE_INVALID) {
zx_handle_t h = rio->event;
rio->event = ZX_HANDLE_INVALID;
zx_handle_close(h);
}
*out_node = node;
return ZX_OK;
}
static zx_status_t zxio_remote_close(zxio_t* io) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_NodeClose(rio->control, &status);
zx_handle_t h = rio->control;
rio->control = ZX_HANDLE_INVALID;
zx_handle_close(h);
if (rio->event != ZX_HANDLE_INVALID) {
zx_handle_t h = rio->event;
rio->event = ZX_HANDLE_INVALID;
zx_handle_close(h);
}
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_clone_async(zxio_t* io, uint32_t flags, zx_handle_t request) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
return fuchsia_io_NodeClone(rio->control, flags, request);
}
static zx_status_t zxio_remote_sync(zxio_t* io) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_NodeSync(rio->control, &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_attr_get(zxio_t* io, zxio_node_attr_t* out_attr) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_NodeGetAttr(rio->control, &status, out_attr);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_attr_set(zxio_t* io, uint32_t flags, const zxio_node_attr_t* attr) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_NodeSetAttr(rio->control, flags, attr, &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_read(zxio_t* io, void* buffer, size_t capacity, size_t* out_actual) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
size_t actual = 0u;
zx_status_t io_status, status;
io_status = fuchsia_io_FileRead(rio->control, capacity, &status,
static_cast<uint8_t*>(buffer), capacity,
&actual);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (actual > capacity) {
return ZX_ERR_IO;
}
*out_actual = actual;
return ZX_OK;
}
static zx_status_t zxio_remote_read_at(zxio_t* io, size_t offset, void* buffer, size_t capacity, size_t* out_actual) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
size_t actual = 0u;
zx_status_t io_status, status;
io_status = fuchsia_io_FileReadAt(rio->control, capacity, offset, &status,
static_cast<uint8_t*>(buffer), capacity,
&actual);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (actual > capacity) {
return ZX_ERR_IO;
}
*out_actual = actual;
return ZX_OK;
}
static zx_status_t zxio_remote_write(zxio_t* io, const void* buffer, size_t capacity, size_t* out_actual) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
size_t actual = 0u;
zx_status_t io_status, status;
io_status = fuchsia_io_FileWrite(rio->control, static_cast<const uint8_t*>(buffer),
capacity, &status, &actual);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (actual > capacity) {
return ZX_ERR_IO;
}
*out_actual = actual;
return ZX_OK;
}
static zx_status_t zxio_remote_write_at(zxio_t* io, size_t offset, const void* buffer, size_t capacity, size_t* out_actual) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
size_t actual = 0u;
zx_status_t io_status, status;
io_status = fuchsia_io_FileWriteAt(rio->control, static_cast<const uint8_t*>(buffer),
capacity, offset, &status, &actual);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (actual > capacity) {
return ZX_ERR_IO;
}
*out_actual = actual;
return ZX_OK;
}
static zx_status_t zxio_remote_seek(zxio_t* io, size_t offset, zxio_seek_origin_t start, size_t* out_offset) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_FileSeek(rio->control, offset, start, &status, out_offset);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_truncate(zxio_t* io, size_t length) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_FileTruncate(rio->control, length, &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_flags_get(zxio_t* io, uint32_t* out_flags) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_FileGetFlags(rio->control, &status, out_flags);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_flags_set(zxio_t* io, uint32_t flags) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_FileSetFlags(rio->control, flags, &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_vmo_get(zxio_t* io, uint32_t flags, zx_handle_t* out_vmo, size_t* out_size) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_handle_t vmo = ZX_HANDLE_INVALID;
zx_status_t io_status, status;
io_status = fuchsia_io_FileGetVmo(rio->control, flags, &status, &vmo);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (vmo == ZX_HANDLE_INVALID) {
return ZX_ERR_IO;
}
*out_vmo = vmo;
return ZX_OK;
}
static zx_status_t zxio_remote_open(zxio_t* io, uint32_t flags, uint32_t mode, const char* path, zxio_t** out_io) {
return ZX_ERR_NOT_SUPPORTED;
}
static zx_status_t zxio_remote_open_async(zxio_t* io, uint32_t flags, uint32_t mode, const char* path, zx_handle_t request) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
return fuchsia_io_DirectoryOpen(rio->control, flags, mode, path, strlen(path), request);
}
static zx_status_t zxio_remote_unlink(zxio_t* io, const char* path) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryUnlink(rio->control, path, strlen(path), &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_token_get(zxio_t* io, zx_handle_t* out_token) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryGetToken(rio->control, &status, out_token);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_rename(zxio_t* io, const char* src_path, zx_handle_t dst_token, const char* dst_path) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryRename(rio->control, src_path, strlen(src_path), dst_token,
dst_path, strlen(dst_path), &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_link(zxio_t* io, const char* src_path, zx_handle_t dst_token, const char* dst_path) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryLink(rio->control, src_path, strlen(src_path), dst_token,
dst_path, strlen(dst_path), &status);
return io_status != ZX_OK ? io_status : status;
}
static zx_status_t zxio_remote_readdir(zxio_t* io, void* buffer, size_t capacity, size_t* out_actual) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
size_t actual = 0u;
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryReadDirents(rio->control, capacity, &status,
static_cast<uint8_t*>(buffer),
capacity, &actual);
if (io_status != ZX_OK) {
return io_status;
}
if (status != ZX_OK) {
return status;
}
if (actual > capacity) {
return ZX_ERR_IO;
}
*out_actual = actual;
return status;
}
static zx_status_t zxio_remote_rewind(zxio_t* io) {
zxio_remote_t* rio = reinterpret_cast<zxio_remote_t*>(io);
zx_status_t io_status, status;
io_status = fuchsia_io_DirectoryRewind(rio->control, &status);
return io_status != ZX_OK ? io_status : status;
}
static const zxio_ops_t zxio_remote_ops = {
.release = zxio_remote_release,
.close = zxio_remote_close,
.clone_async = zxio_remote_clone_async,
.sync = zxio_remote_sync,
.attr_get = zxio_remote_attr_get,
.attr_set = zxio_remote_attr_set,
.read = zxio_remote_read,
.read_at = zxio_remote_read_at,
.write = zxio_remote_write,
.write_at = zxio_remote_write_at,
.seek = zxio_remote_seek,
.truncate = zxio_remote_truncate,
.flags_get = zxio_remote_flags_get,
.flags_set = zxio_remote_flags_set,
.vmo_get = zxio_remote_vmo_get,
.open = zxio_remote_open,
.open_async = zxio_remote_open_async,
.unlink = zxio_remote_unlink,
.token_get = zxio_remote_token_get,
.rename = zxio_remote_rename,
.link = zxio_remote_link,
.readdir = zxio_remote_readdir,
.rewind = zxio_remote_rewind,
};
zx_status_t zxio_remote_init(zxio_remote_t* rio, zx_handle_t control,
zx_handle_t event) {
zxio_init(&rio->io, &zxio_remote_ops);
rio->control = control;
rio->event = event;
return ZX_OK;
}