// 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 <assert.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>

#include <zircon/assert.h>
#include <zircon/device/device.h>
#include <zircon/device/ioctl.h>
#include <zircon/device/vfs.h>
#include <zircon/syscalls.h>

#include <fbl/function.h>
#include <lib/fidl/cpp/builder.h>
#include <lib/fidl/cpp/message.h>
#include <lib/fidl/cpp/string_view.h>
#include <lib/fidl/cpp/vector_view.h>
#include <fdio/debug.h>
#include <fdio/io.fidl.h>
#include <fdio/io.h>
#include <fdio/remoteio.h>
#include <fdio/util.h>
#include <fdio/vfs.h>
#include <lib/zx/channel.h>

#include "private-fidl.h"

#define MXDEBUG 0

namespace {

void discard_handles(const zx_handle_t* handles, size_t count) {
    while (count-- > 0) {
        zx_handle_close(*handles++);
    }
}

// Convert a message to a primary object, validating that
// there are enough bytes to do this conversion.
//
// Returns nullptr if this conversion is invalid.
template <typename T>
T* to_primary(const fidl::Message* msg) {
    if (msg->bytes().actual() < sizeof(T)) {
        fprintf(stderr, "%s: Message (%u bytes) is smaller than primary (%zu bytes)\n",
                __PRETTY_FUNCTION__, msg->bytes().actual(), sizeof(T));
        return nullptr;
    }
    return reinterpret_cast<T*>(msg->bytes().data());
}

// Semantic sugar for creating a new FIDL request object
// and setting the ordinal.
template <typename T, uint32_t Ordinal>
T* new_request(zxrio_t* rio, fidl::Builder* builder) {
    T* request = builder->New<T>();
    request->hdr.ordinal = Ordinal;
    return request;
}

template <typename T>
void* get_secondary(T* request) {
    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(request) +
                                   FIDL_ALIGN(sizeof(T)));
}

void* next_secondary(void* secondary, size_t size) {
    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(secondary) +
                                   FIDL_ALIGN(size));
}

// A small wrapper for "Call" which extracts the appropriate
// response status.
//
// Since outgoing / incoming handles are contained in fidl::Message,
// they will be automatically closed whenever it goes out of scope.
zx_status_t fidl_call(zx_handle_t h, fidl::Message* message) {
    zx_status_t rs = 0;
    zx_status_t r = message->Call(h, 0, ZX_TIME_INFINITE, &rs, message);
    if (r == ZX_ERR_CALL_FAILED) {
        return rs == ZX_OK ? ZX_ERR_IO : rs;
    } else if (r != ZX_OK) {
        return r;
    }
    return ZX_OK;
}

// zxrio_decode_request always takes ownership of the incoming handles.
//
// If ClearHandlesUnsafe is not called on the msg, all provided handles
// will automatically be closed by the destructor of |msg|.
zx_status_t zxrio_decode_request(fidl::Message* msg) {
    if (!msg->has_header()) {
        fprintf(stderr, "zxrio_decode_request: Missing header\n");
        return ZX_ERR_IO;
    }
    uint32_t op = msg->ordinal();
    const uint32_t hcount = msg->handles().actual();
    const zx_handle_t* handles = msg->handles().data();
    const uint32_t dsz = msg->bytes().actual();
    void* data = msg->bytes().data();

    if (!ZXRIO_FIDL_MSG(op)) {
        // Legacy RIO messages
        // Now, "msg->hcount" can be trusted once again.
        zxrio_msg_t* rio_msg = reinterpret_cast<zxrio_msg_t*>(data);
        memcpy(rio_msg->handle, handles, sizeof(zx_handle_t) * hcount);
        rio_msg->hcount = hcount;
        if (!is_rio_message_reply_valid(rio_msg, dsz)) {
            fprintf(stderr, "decoding: Invalid legacy msg: 0x%x\n", op);
            return ZX_ERR_INVALID_ARGS;
        }
        if (rio_msg->hcount != ZXRIO_HC(op)) {
            fprintf(stderr, "decoding: Unexpected # of handles\n");
            return ZX_ERR_IO;
        }

        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }

    // FIDL objects which require additional secondary object validation
    switch (op) {
    case ZXFIDL_CLONE: {
        fuchsia_io_ObjectCloneRequest* request = to_primary<fuchsia_io_ObjectCloneRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (hcount != 1 || request->object != FIDL_HANDLE_PRESENT) {
            fprintf(stderr, "ZXFIDL_CLONE failed: Missing handle\n");
            return ZX_ERR_IO;
        }
        request->object = handles[0];
        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }
    case ZXFIDL_OPEN: {
        fuchsia_io_DirectoryOpenRequest* request = to_primary<fuchsia_io_DirectoryOpenRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (hcount != 1 || request->object != FIDL_HANDLE_PRESENT) {
            fprintf(stderr, "ZXFIDL_OPEN failed: Missing handle\n");
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(request->path.size) +
                   FIDL_ALIGN(sizeof(fuchsia_io_DirectoryOpenRequest)) != dsz) {
            fprintf(stderr, "ZXFIDL_OPEN failed: Bad secondary size\n");
            return ZX_ERR_IO;
        } else if ((request->path.data != (void*) FIDL_ALLOC_PRESENT)) {
            fprintf(stderr, "ZXFIDL_OPEN failed: Bad secondary pointer\n");
            return ZX_ERR_IO;
        }

        request->object = handles[0];
        request->path.data = static_cast<char*>(get_secondary(request));
        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }
    case ZXFIDL_WRITE: {
        fuchsia_io_FileWriteRequest* request = to_primary<fuchsia_io_FileWriteRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(request->data.count) +
                   FIDL_ALIGN(sizeof(fuchsia_io_FileWriteRequest)) != dsz) {
            fprintf(stderr, "ZXFIDL_WRITE failed: bad secondary\n");
            return ZX_ERR_IO;
        } else if (request->data.data != (void*) FIDL_ALLOC_PRESENT) {
            fprintf(stderr, "ZXFIDL_WRITE failed: bad secondary pointer\n");
            return ZX_ERR_IO;
        }
        request->data.data = get_secondary(request);
        return ZX_OK;
    }
    case ZXFIDL_IOCTL: {
        fuchsia_io_NodeIoctlRequest* request = to_primary<fuchsia_io_NodeIoctlRequest>(msg);
        if (request == nullptr) {
            fprintf(stderr, "ZXFIDL_IOCTL failed: missing response space\n");
            return ZX_ERR_IO;
        } else if ((request->handles.data != (void*) FIDL_ALLOC_PRESENT) ||
            (request->in.data != (void*) FIDL_ALLOC_PRESENT)) {
            fprintf(stderr, "ZXFIDL_IOCTL failed: missing necessary vector\n");
            return ZX_ERR_IO;
        }
        if (hcount != request->handles.count) {
            fprintf(stderr, "ZXFIDL_IOCTL failed: bad hcount\n");
            return ZX_ERR_IO;
        }
        request->handles.data = get_secondary(request);
        zx_handle_t* hptr = reinterpret_cast<zx_handle_t*>(request->handles.data);
        for (size_t i = 0; i < request->handles.count; i++) {
            if (hptr[i] != FIDL_HANDLE_PRESENT) {
                fprintf(stderr, "ZXFIDL_IOCTL: Handles are required; must be present\n");
                return ZX_ERR_IO;
            }
        }

        switch (IOCTL_KIND(request->opcode)) {
        case IOCTL_KIND_SET_HANDLE:
            if (request->handles.count != 1) {
                fprintf(stderr, "ZXFIDL_IOCTL: bad hcount (expected to set one)\n");
                return ZX_ERR_IO;
            }
            break;
        case IOCTL_KIND_SET_TWO_HANDLES:
            if (request->handles.count != 2) {
                fprintf(stderr, "ZXFIDL_IOCTL: bad hcount (expected to set two)\n");
                return ZX_ERR_IO;
            }
            break;
        case IOCTL_KIND_GET_HANDLE:
        case IOCTL_KIND_GET_TWO_HANDLES:
        case IOCTL_KIND_GET_THREE_HANDLES:
        default:
            if (request->handles.count != 0) {
                fprintf(stderr, "ZXFIDL_IOCTL: bad hcount (expected to set none)\n");
                return ZX_ERR_IO;
            }
        }

        size_t secondary_size = FIDL_ALIGN(request->handles.count * sizeof(zx_handle_t)) +
                                FIDL_ALIGN(request->in.count);
        if (FIDL_ALIGN(sizeof(fuchsia_io_NodeIoctlRequest)) + secondary_size != dsz) {
            fprintf(stderr, "ZXFIDL_IOCTL failed: bad secondary size\n");
            return ZX_ERR_IO;
        }

        // Patch up handles, pointers
        memcpy(request->handles.data, handles, hcount * sizeof(zx_handle_t));
        request->in.data = next_secondary(request->handles.data, hcount * sizeof(zx_handle_t));
        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }
    case ZXFIDL_UNLINK: {
        fuchsia_io_DirectoryUnlinkRequest* request =
            to_primary<fuchsia_io_DirectoryUnlinkRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(request->path.size) +
                   FIDL_ALIGN(sizeof(fuchsia_io_DirectoryUnlinkRequest)) != dsz) {
            fprintf(stderr, "ZXFIDL_UNLINK failed: bad secondary\n");
            return ZX_ERR_IO;
        } else if (request->path.data != (void*) FIDL_ALLOC_PRESENT) {
            fprintf(stderr, "ZXFIDL_UNLINK failed: bad secondary pointer\n");
            return ZX_ERR_IO;
        }
        request->path.data = static_cast<char*>(get_secondary(request));
        return ZX_OK;
    }
    case ZXFIDL_WRITE_AT: {
        fuchsia_io_FileWriteAtRequest* request = to_primary<fuchsia_io_FileWriteAtRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(request->data.count) +
                   FIDL_ALIGN(sizeof(fuchsia_io_FileWriteAtRequest)) != dsz) {
            fprintf(stderr, "ZXFIDL_WRITE_AT failed: bad secondary\n");
            return ZX_ERR_IO;
        } else if (request->data.data != (void*) FIDL_ALLOC_PRESENT) {
            fprintf(stderr, "ZXFIDL_WRITE_AT failed: bad secondary pointer\n");
            return ZX_ERR_IO;
        }
        request->data.data = get_secondary(request);
        return ZX_OK;
    }
    case ZXFIDL_RENAME: {
        fuchsia_io_DirectoryRenameRequest* request = to_primary<fuchsia_io_DirectoryRenameRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(sizeof(fuchsia_io_DirectoryRenameRequest)) +
                   FIDL_ALIGN(request->src.size) + FIDL_ALIGN(request->dst.size)
                   != dsz) {
            fprintf(stderr, "ZXFIDL_RENAME failed: Bad secondary\n");
            return ZX_ERR_IO;
        } else if (request->src.data != (void*) FIDL_ALLOC_PRESENT ||
                   request->dst_parent_token != FIDL_HANDLE_PRESENT ||
                   request->dst.data != (void*) FIDL_ALLOC_PRESENT) {
            fprintf(stderr, "ZXFIDL_RENAME failed: Bad secondary pointer\n");
            return ZX_ERR_IO;
        }

        request->src.data = static_cast<char*>(get_secondary(request));
        request->dst_parent_token = handles[0];
        request->dst.data = static_cast<char*>(next_secondary(request->src.data,
                                                              request->src.size));
        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }
    case ZXFIDL_LINK: {
        fuchsia_io_DirectoryLinkRequest* request = to_primary<fuchsia_io_DirectoryLinkRequest>(msg);
        if (request == nullptr) {
            return ZX_ERR_IO;
        } else if (FIDL_ALIGN(sizeof(fuchsia_io_DirectoryLinkRequest)) +
                   FIDL_ALIGN(request->src.size) + FIDL_ALIGN(request->dst.size)
                   != dsz) {
            fprintf(stderr, "ZXFIDL_LINK failed: Bad secondary\n");
            return ZX_ERR_IO;
        } else if (request->src.data != (void*) FIDL_ALLOC_PRESENT ||
                   request->dst_parent_token != FIDL_HANDLE_PRESENT ||
                   request->dst.data != (void*) FIDL_ALLOC_PRESENT) {
            fprintf(stderr, "ZXFIDL_LINK failed: Bad secondary pointer\n");
            return ZX_ERR_IO;
        }

        request->src.data = static_cast<char*>(get_secondary(request));
        request->dst_parent_token = handles[0];
        request->dst.data = static_cast<char*>(next_secondary(request->src.data,
                                                              request->src.size));
        msg->ClearHandlesUnsafe();
        return ZX_OK;
    }
    }

    return ZX_OK;
}

// Simplify a common pattern of encoding:
// Cast to the response message, set the size to the response message size, and
// insert the status into the response.
template <typename T>
T* encode_response_status(void* msg, zx_status_t status, uint32_t* sz) {
    T* response = static_cast<T*>(msg);
    *sz = sizeof(T);
    response->s = status;
    return response;
}

zx_status_t zxrio_encode_response(zx_status_t status, zxrio_msg_t* msg, uint32_t* sz,
                                  zx_handle_t* handles, uint32_t* hcount) {
    *hcount = 0;
    switch (msg->op) {
    case ZXFIDL_CLOSE: {
        encode_response_status<fuchsia_io_ObjectCloseResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_READ: {
        auto response = encode_response_status<fuchsia_io_FileReadResponse>(msg, status, sz);
        response->data.data = (void*) FIDL_ALLOC_PRESENT;
        if (response->s != ZX_OK) {
            response->data.count = 0;
        }
        *sz += static_cast<uint32_t>(FIDL_ALIGN(response->data.count));
        break;
    }
    case ZXFIDL_WRITE: {
        auto response = encode_response_status<fuchsia_io_FileWriteResponse>(msg, status, sz);
        if (response->s != ZX_OK) {
            response->actual = 0;
        }
        break;
    }
    case ZXFIDL_SEEK: {
        encode_response_status<fuchsia_io_FileSeekResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_STAT: {
        encode_response_status<fuchsia_io_NodeGetAttrResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_SETATTR: {
        encode_response_status<fuchsia_io_NodeSetAttrResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_READDIR: {
        auto response = encode_response_status<fuchsia_io_DirectoryReadDirentsResponse>(msg, status, sz);
        response->dirents.data = (void*) FIDL_ALLOC_PRESENT;
        if (response->s != ZX_OK) {
            response->dirents.count = 0;
        }
        *sz += static_cast<uint32_t>(FIDL_ALIGN(response->dirents.count));
        break;
    }
    case ZXFIDL_IOCTL: {
        auto response = encode_response_status<fuchsia_io_NodeIoctlResponse>(msg, status, sz);
        if (response->s != ZX_OK) {
            response->handles.count = 0;
            response->out.count = 0;
        }
        memcpy(handles, response->handles.data, response->handles.count * sizeof(zx_handle_t));

        zx_handle_t* hptr = reinterpret_cast<zx_handle_t*>(response->handles.data);
        for (size_t i = 0; i < response->handles.count; i++) {
            hptr[i] = FIDL_HANDLE_PRESENT;
        }
        *hcount = static_cast<uint32_t>(response->handles.count);
        response->handles.data = (void*) FIDL_ALLOC_PRESENT;
        response->out.data = (void*) FIDL_ALLOC_PRESENT;
        *sz += static_cast<uint32_t>(FIDL_ALIGN(response->handles.count * sizeof(zx_handle_t)) +
                                     FIDL_ALIGN(response->out.count));
        break;
    }
    case ZXFIDL_UNLINK: {
        encode_response_status<fuchsia_io_DirectoryUnlinkResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_READ_AT: {
        auto response = encode_response_status<fuchsia_io_FileReadAtResponse>(msg, status, sz);
        response->data.data = (void*) FIDL_ALLOC_PRESENT;
        if (response->s != ZX_OK) {
            response->data.count = 0;
        }
        *sz += static_cast<uint32_t>(response->data.count);
        break;
    }
    case ZXFIDL_WRITE_AT: {
        auto response = encode_response_status<fuchsia_io_FileWriteAtResponse>(msg, status, sz);
        if (response->s != ZX_OK) {
            response->actual = 0;
        }
        break;
    }
    case ZXFIDL_TRUNCATE: {
        encode_response_status<fuchsia_io_FileTruncateResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_RENAME: {
        encode_response_status<fuchsia_io_DirectoryRenameResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_SYNC: {
        encode_response_status<fuchsia_io_NodeSyncResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_LINK: {
        encode_response_status<fuchsia_io_DirectoryLinkResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_REWIND: {
        encode_response_status<fuchsia_io_DirectoryRewindResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_GET_VMO: {
        auto response = encode_response_status<fuchsia_io_FileGetVmoResponse>(msg, status, sz);
        if (response->s != ZX_OK) {
            response->vmo = FIDL_HANDLE_ABSENT;
        } else {
            handles[0] = response->vmo;
            *hcount = 1;
            response->vmo = FIDL_HANDLE_PRESENT;
        }
        break;
    }
    case ZXFIDL_GET_FLAGS: {
        encode_response_status<fuchsia_io_FileGetFlagsResponse>(msg, status, sz);
        break;
    }
    case ZXFIDL_SET_FLAGS: {
        encode_response_status<fuchsia_io_FileSetFlagsResponse>(msg, status, sz);
        break;
    }
    default:
        if (ZXRIO_FIDL_MSG(msg->op)) {
            fprintf(stderr, "Unsupported FIDL operation: 0x%x\n", msg->op);
            return ZX_ERR_NOT_SUPPORTED;
        }
        msg->arg = status;
        if ((msg->arg < 0) || !is_rio_message_valid(msg)) {
            // in the event of an error response or bad message
            // release all the handles and data payload
            discard_handles(msg->handle, msg->hcount);
            msg->datalen = 0;
            msg->hcount = 0;
            // specific errors are prioritized over the bad
            // message case which we represent as ZX_ERR_INTERNAL
            // to differentiate from ZX_ERR_IO on the near side
            // TODO(ZX-974): consider a better error code
            msg->arg = (msg->arg < 0) ? msg->arg : ZX_ERR_INTERNAL;
        }
        *sz = static_cast<uint32_t>(ZXRIO_HDR_SZ + msg->datalen);
        *hcount = msg->hcount;
        memcpy(handles, msg->handle, sizeof(zx_handle_t) * msg->hcount);
    }
    return ZX_OK;
}

} // namespace

bool is_rio_message_valid(zxrio_msg_t* msg) {
    if ((msg->datalen > FDIO_CHUNK_SIZE) || (msg->hcount > FDIO_MAX_HANDLES)) {
        return false;
    }
    return true;
}

bool is_rio_message_reply_valid(zxrio_msg_t* msg, uint32_t size) {
    if ((size < ZXRIO_HDR_SZ) || (msg->datalen != (size - ZXRIO_HDR_SZ))) {
        return false;
    }
    return is_rio_message_valid(msg);
}

zx_status_t zxrio_read_request(zx_handle_t h, zxrio_msg_t* rio_msg) {
    zx_status_t r;
    zx_handle_t handles[FDIO_MAX_HANDLES];
    fidl::Message msg(fidl::BytePart((uint8_t*) rio_msg, sizeof(zxrio_msg_t)),
                      fidl::HandlePart(handles, static_cast<uint32_t>(fbl::count_of(handles))));
    if ((r = msg.Read(h, 0)) != ZX_OK) {
        return r;
    }

    if ((r = zxrio_decode_request(&msg)) != ZX_OK) {
        fprintf(stderr, "zxrio_read_request failed to decode\n");
        return ZX_ERR_INVALID_ARGS;
    }

    return r;
}

zx_status_t zxrio_write_response(zx_handle_t h, zx_status_t status, zxrio_msg_t* msg) {
    // Encode
    uint32_t sz = 0;
    zx_handle_t handles[FDIO_MAX_HANDLES];
    uint32_t hcount = 0;
    if (zxrio_encode_response(status, msg, &sz, handles, &hcount) != ZX_OK) {
        fprintf(stderr, "zxrio_write_response: Failed to encode response\n");
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Transmit
    if ((status = zx_channel_write(h, 0, msg, sz, handles, hcount)) != ZX_OK) {
        discard_handles(handles, hcount);
    }

    return status;
}

// Always consumes cnxn.
zx_status_t fidl_clone_request(zx_handle_t srv, zx_handle_t cnxn, uint32_t flags) {
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    fidl::HandlePart handles(&cnxn, 1, 1);

    // Setup the request message header
    fuchsia_io_ObjectCloneRequest* request = builder.New<fuchsia_io_ObjectCloneRequest>();
    request->hdr.ordinal = ZXFIDL_CLONE;
    request->flags = flags;
    request->object = FIDL_HANDLE_PRESENT;

    fidl::Message message(builder.Finalize(), fbl::move(handles));
    return message.Write(srv, 0);
}

zx_status_t fidl_open_request(zx_handle_t srv, zx_handle_t cnxn, uint32_t flags,
                              uint32_t mode, const char* path, size_t pathlen) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    fidl::HandlePart handles(&cnxn, 1, 1);

    // Setup the request message header
    fuchsia_io_DirectoryOpenRequest* request = builder.New<fuchsia_io_DirectoryOpenRequest>();
    request->hdr.ordinal = ZXFIDL_OPEN;

    // Setup the request message primary
    request->flags = flags;
    request->mode = mode;
    request->path.data = (char*) FIDL_ALLOC_PRESENT;
    request->path.size = pathlen;
    request->object = FIDL_HANDLE_PRESENT;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(pathlen));
    memcpy(secondary, path, pathlen);

    fidl::Message message(builder.Finalize(), fbl::move(handles));
    return message.Write(srv, 0);
}

zx_status_t fidl_close(zxrio_t* rio) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    new_request<fuchsia_io_ObjectCloseRequest, ZXFIDL_CLOSE>(rio, &builder);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_ObjectCloseResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_write(zxrio_t* rio, const void* data, uint64_t length,
                       uint64_t* actual) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileWriteRequest, ZXFIDL_WRITE>(rio, &builder);

    // Setup the request message primary
    request->data.count = length;
    request->data.data = (void*) FIDL_ALLOC_PRESENT;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(length));
    memcpy(secondary, data, length);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileWriteResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    if (response->actual > length) {
        return ZX_ERR_IO;
    }
    *actual = response->actual;
    return response->s;
}

zx_status_t fidl_writeat(zxrio_t* rio, const void* data, uint64_t length,
                         off_t offset, uint64_t* actual) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileWriteAtRequest, ZXFIDL_WRITE_AT>(rio, &builder);

    // Setup the request message primary
    request->data.count = length;
    request->data.data = (void*) FIDL_ALLOC_PRESENT;
    request->offset = offset;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(length));
    memcpy(secondary, data, length);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileWriteAtResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    if (response->actual > length) {
        return ZX_ERR_IO;
    }
    *actual = response->actual;
    return response->s;
}

zx_status_t fidl_read(zxrio_t* rio, void* data, uint64_t length, uint64_t* actual) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileReadRequest, ZXFIDL_READ>(rio, &builder);

    // Setup the request message primary
    request->count = length;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(length));
    memcpy(secondary, data, length);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileReadResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }
    if ((response->data.data != (void*) FIDL_ALLOC_PRESENT) ||
        (message.bytes().actual() != FIDL_ALIGN(sizeof(fuchsia_io_FileReadResponse)) +
         FIDL_ALIGN(response->data.count))) {
        return ZX_ERR_IO;
    }
    response->data.data = get_secondary(response);

    // Extract data
    if (response->data.count > length) {
        return ZX_ERR_IO;
    }
    memcpy(data, response->data.data, response->data.count);
    *actual = response->data.count;
    return response->s;
}

zx_status_t fidl_readat(zxrio_t* rio, void* data, uint64_t length, off_t offset,
                        uint64_t* actual) {

    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileReadAtRequest, ZXFIDL_READ_AT>(rio, &builder);

    // Setup the request message primary
    request->count = length;
    request->offset = offset;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(length));
    memcpy(secondary, data, length);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileReadAtResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }
    if ((response->data.data != (void*) FIDL_ALLOC_PRESENT) ||
        (message.bytes().actual() != FIDL_ALIGN(sizeof(fuchsia_io_FileReadAtResponse)) +
         FIDL_ALIGN(response->data.count))) {
        return ZX_ERR_IO;
    }
    response->data.data = get_secondary(response);

    // Extract data
    if (response->data.count > length) {
        return ZX_ERR_IO;
    }
    memcpy(data, response->data.data, response->data.count);
    *actual = response->data.count;
    return response->s;
}

static_assert(SEEK_SET == fuchsia_io_SeekOrigin_Start, "");
static_assert(SEEK_CUR == fuchsia_io_SeekOrigin_Current, "");
static_assert(SEEK_END == fuchsia_io_SeekOrigin_End, "");

zx_status_t fidl_seek(zxrio_t* rio, off_t offset, int whence, off_t* out) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileSeekRequest, ZXFIDL_SEEK>(rio, &builder);

    // Setup the request message primary
    request->offset = offset;
    request->start = whence;

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileSeekResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    } else if (response->s != ZX_OK) {
        return response->s;
    }

    return ZX_OK;
}

zx_status_t fidl_stat(zxrio_t* rio, size_t len, vnattr_t* out, size_t* out_sz) {
    ZX_DEBUG_ASSERT(len >= sizeof(vnattr_t));

    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    new_request<fuchsia_io_NodeGetAttrRequest, ZXFIDL_STAT>(rio, &builder);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_NodeGetAttrResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    } else if (response->s != ZX_OK) {
        return response->s;
    }

    // Translate NodeAttributes --> vnattr
    out->mode = response->attributes.mode;
    out->inode = response->attributes.id;
    out->size = response->attributes.content_size;
    out->blksize = VNATTR_BLKSIZE;
    out->blkcount = response->attributes.storage_size / VNATTR_BLKSIZE;
    out->nlink = response->attributes.link_count;
    out->create_time = response->attributes.creation_time;
    out->modify_time = response->attributes.modification_time;

    *out_sz = sizeof(vnattr_t);
    return ZX_OK;
}

zx_status_t fidl_setattr(zxrio_t* rio, const vnattr_t* attr) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_NodeSetAttrRequest, ZXFIDL_SETATTR>(rio, &builder);

    // Setup the request message primary
    // TODO(smklein): Replace with autogenerated constants
    const uint32_t kFlagCreationTime = 1;
    const uint32_t kFlagModificationTime = 2;
    static_assert(kFlagCreationTime == ATTR_CTIME, "SetAttr flags unaligned");
    static_assert(kFlagModificationTime == ATTR_MTIME, "SetAttr flags unaligned");
    request->flags = attr->valid;
    request->attributes.creation_time = attr->create_time;
    request->attributes.modification_time = attr->modify_time;

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_NodeSetAttrResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }
    return response->s;
}

zx_status_t fidl_sync(zxrio_t* rio) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    new_request<fuchsia_io_NodeSyncRequest, ZXFIDL_SYNC>(rio, &builder);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_NodeSyncResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_readdirents(zxrio_t* rio, void* data, size_t length, size_t* out_sz) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_DirectoryReadDirentsRequest, ZXFIDL_READDIR>(rio, &builder);

    // Setup the request message primary
    request->max_out = length;

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_DirectoryReadDirentsResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }
    if ((response->dirents.data != (void*) FIDL_ALLOC_PRESENT) ||
        (message.bytes().actual() != FIDL_ALIGN(sizeof(fuchsia_io_DirectoryReadDirentsResponse)) +
         FIDL_ALIGN(response->dirents.count))) {
        fprintf(stderr, "fidl_readdirents failed to decode response\n");
        return ZX_ERR_IO;
    }
    response->dirents.data = get_secondary(response);

    // Extract data
    if (response->dirents.count > length) {
        return ZX_ERR_IO;
    }
    memcpy(data, response->dirents.data, response->dirents.count);
    *out_sz = response->dirents.count;
    return response->s;
}

zx_status_t fidl_rewind(zxrio_t* rio) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    new_request<fuchsia_io_DirectoryRewindRequest, ZXFIDL_REWIND>(rio, &builder);
    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_DirectoryRewindResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }
    return response->s;
}

zx_status_t fidl_unlink(zxrio_t* rio, const char* name, size_t namelen) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    fuchsia_io_DirectoryUnlinkRequest* request =
            new_request<fuchsia_io_DirectoryUnlinkRequest, ZXFIDL_UNLINK>(rio, &builder);

    // Setup the request message primary
    request->path.size = namelen;
    request->path.data = (char*) FIDL_ALLOC_PRESENT;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(namelen));
    memcpy(secondary, name, namelen);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());

    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_DirectoryUnlinkResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_truncate(zxrio_t* rio, uint64_t length) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileTruncateRequest, ZXFIDL_TRUNCATE>(rio, &builder);

    // Setup the request message primary
    request->length = length;

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileTruncateResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_rename(zxrio_t* rio, const char* src, size_t srclen,
                        zx_handle_t dst_token, const char* dst, size_t dstlen) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    fidl::HandlePart handles(&dst_token, 1, 1);

    // Setup the request message header
    auto request = new_request<fuchsia_io_DirectoryRenameRequest, ZXFIDL_RENAME>(rio, &builder);

    // Setup the request message primary
    request->src.size = srclen;
    request->src.data = (char*) FIDL_ALLOC_PRESENT;
    request->dst_parent_token = FIDL_HANDLE_PRESENT;
    request->dst.size = dstlen;
    request->dst.data = (char*) FIDL_ALLOC_PRESENT;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(srclen));
    memcpy(secondary, src, srclen);
    secondary = builder.NewArray<char>(static_cast<uint32_t>(dstlen));
    memcpy(secondary, dst, dstlen);

    fidl::Message message(builder.Finalize(), fbl::move(handles));
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_DirectoryRenameResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_link(zxrio_t* rio, const char* src, size_t srclen,
                      zx_handle_t dst_token, const char* dst, size_t dstlen) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    fidl::HandlePart handles(&dst_token, 1, 1);

    // Setup the request message header
    auto request = new_request<fuchsia_io_DirectoryLinkRequest, ZXFIDL_LINK>(rio, &builder);

    // Setup the request message primary
    request->src.size = srclen;
    request->src.data = (char*) FIDL_ALLOC_PRESENT;
    request->dst_parent_token = FIDL_HANDLE_PRESENT;
    request->dst.size = dstlen;
    request->dst.data = (char*) FIDL_ALLOC_PRESENT;

    // Setup the request message secondary
    char* secondary = builder.NewArray<char>(static_cast<uint32_t>(srclen));
    memcpy(secondary, src, srclen);
    secondary = builder.NewArray<char>(static_cast<uint32_t>(dstlen));
    memcpy(secondary, dst, dstlen);

    fidl::Message message(builder.Finalize(), fbl::move(handles));
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_DirectoryLinkResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}

zx_status_t fidl_ioctl(zxrio_t* rio, uint32_t op, const void* in_buf,
                       size_t in_len, void* out_buf, size_t out_len,
                       size_t* out_actual) {

    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    zx_handle_t handle_buffer[FDIO_MAX_HANDLES];
    fidl::HandlePart handles(handle_buffer, FDIO_MAX_HANDLES);

    // Setup the request message header
    auto request = new_request<fuchsia_io_NodeIoctlRequest, ZXFIDL_IOCTL>(rio, &builder);

    // Setup the request message primary
    request->opcode = op;
    request->max_out = out_len;
    request->handles.count = 0;
    request->handles.data = (void*) FIDL_ALLOC_PRESENT;
    request->in.count = in_len;
    request->in.data = (void*) FIDL_ALLOC_PRESENT;

    switch (IOCTL_KIND(op)) {
    case IOCTL_KIND_GET_HANDLE:
        if (out_len < sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        break;
    case IOCTL_KIND_GET_TWO_HANDLES:
        if (out_len < 2 * sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        break;
    case IOCTL_KIND_GET_THREE_HANDLES:
        if (out_len < 3 * sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        break;
    case IOCTL_KIND_SET_HANDLE:
        if (in_len < sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        request->handles.count = 1;
        break;
    case IOCTL_KIND_SET_TWO_HANDLES:
        if (in_len < 2 * sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        request->handles.count = 2;
        break;
    }

    if (request->handles.count) {
        uint32_t hcount = static_cast<uint32_t>(request->handles.count);
        handles.set_actual(hcount);
        auto secondary = builder.NewArray<zx_handle_t>(hcount);
        for (size_t i = 0; i < hcount; i++) {
            handle_buffer[i] = *((zx_handle_t*) in_buf + i);
            secondary[i] = FIDL_HANDLE_PRESENT;
        }
    }
    if (in_len > 0) {
        auto secondary = builder.NewArray<char>(static_cast<uint32_t>(in_len));
        memcpy(secondary, in_buf, in_len);
    }

    fidl::Message message(builder.Finalize(), fbl::move(handles));

    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        fprintf(stderr, "ioctl fidl call failure: %d\n", r);
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_NodeIoctlResponse>(&message);
    if (response == nullptr) {
        fprintf(stderr, "failed to get ioctl primary\n");
        return ZX_ERR_IO;
    }

    // Validate primary
    if ((response->handles.data != (void*) FIDL_ALLOC_PRESENT) ||
        (response->out.data != (void*) FIDL_ALLOC_PRESENT)) {
        fprintf(stderr, "Ioctl: Decoding bad primary\n");
        return ZX_ERR_IO;
    }

    // Validate secondary
    if (response->handles.count != message.handles().actual()) {
        fprintf(stderr, "Ioctl: Decoding bad hcount\n");
        return ZX_ERR_IO;
    }
    const void* secondary = get_secondary(response);

    size_t expected_handles_len = FIDL_ALIGN(sizeof(zx_handle_t) *
                                             response->handles.count);
    size_t expected_data_len = FIDL_ALIGN(response->out.count);
    if (message.bytes().actual() != FIDL_ALIGN(sizeof(fuchsia_io_NodeIoctlResponse)) +
        expected_handles_len + expected_data_len) {
        fprintf(stderr, "Ioctl: Decoding bad output size\n");
        return ZX_ERR_IO;
    }

    if ((sizeof(zx_handle_t) * response->handles.count > out_len) ||
        (response->out.count > out_len)) {
        fprintf(stderr, "Ioctl: Decoding response larger than out_len\n");
        return ZX_ERR_IO;
    }

    if (response->s != ZX_OK) {
        return response->s;
    }

    size_t expected_handles = 0;
    switch (IOCTL_KIND(op)) {
    case IOCTL_KIND_GET_HANDLE:
        expected_handles = 1;
        break;
    case IOCTL_KIND_GET_TWO_HANDLES:
        expected_handles = 2;
        break;
    case IOCTL_KIND_GET_THREE_HANDLES:
        expected_handles = 3;
        break;
    }

    // Extract handles
    if (expected_handles != message.handles().actual()) {
        fprintf(stderr, "ioctl client decode: Unexpected Handle count\n");
        return ZX_ERR_IO;
    }

    // Extract handles on top of data
    *out_actual = 0;
    if (response->out.count > 0) {
        memcpy(out_buf, secondary, response->out.count);
        *out_actual = response->out.count;
    }
    memcpy(out_buf, message.handles().data(),
           message.handles().actual() * sizeof(zx_handle_t));
    if (*out_actual == 0) {
        *out_actual = message.handles().actual() * sizeof(zx_handle_t);
    }

    message.ClearHandlesUnsafe();
    return ZX_OK;
}

zx_status_t fidl_getvmo(zxrio_t* rio, uint32_t flags, zx_handle_t* out) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));
    fidl::HandlePart handles(out, 1);

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileGetVmoRequest, ZXFIDL_GET_VMO>(rio, &builder);

    // Setup the request message primary
    request->flags = flags;

    fidl::Message message(builder.Finalize(), fbl::move(handles));
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileGetVmoResponse>(&message);
    if (response == nullptr) {
        fprintf(stderr, "fidl_getvmo couldn't convert to primary\n");
        return ZX_ERR_IO;
    } else if (response->s != ZX_OK) {
        return response->s;
    } else if (message.handles().actual() != 1) {
        fprintf(stderr, "fidl_getvmo missing VMO\n");
        return ZX_ERR_IO;
    }

    // Already reading directly into |out|.
    if (response->vmo != FIDL_HANDLE_PRESENT) {
        fprintf(stderr, "fidl_getvmo: Missing response VMO\n");
        return ZX_ERR_IO;
    }
    message.ClearHandlesUnsafe();
    return ZX_OK;
}

zx_status_t fidl_getflags(zxrio_t* rio, uint32_t* outflags) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    new_request<fuchsia_io_FileGetFlagsRequest, ZXFIDL_GET_FLAGS>(rio, &builder);

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileGetFlagsResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    *outflags = response->flags;
    return response->s;
}

zx_status_t fidl_setflags(zxrio_t* rio, uint32_t flags) {
    // Prepare buffers for input & output
    char byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
    fidl::Builder builder(byte_buffer, sizeof(byte_buffer));

    // Setup the request message header
    auto request = new_request<fuchsia_io_FileSetFlagsRequest, ZXFIDL_SET_FLAGS>(rio, &builder);

    // Setup the request message primary
    request->flags = flags;

    fidl::Message message(builder.Finalize(), fidl::HandlePart());
    zx_status_t r = fidl_call(zxrio_handle(rio), &message);
    if (r != ZX_OK) {
        return r;
    }

    // Validate primary size
    auto response = to_primary<fuchsia_io_FileSetFlagsResponse>(&message);
    if (response == nullptr) {
        return ZX_ERR_IO;
    }

    return response->s;
}
