// Copyright 2016 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 <limits.h>
#include <poll.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <threads.h>

#include <zircon/device/device.h>
#include <zircon/device/ioctl.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <fdio/debug.h>
#include <fdio/io.h>
#include <fdio/namespace.h>
#include <fdio/remoteio.h>
#include <fdio/util.h>

#include "private-remoteio.h"

#define MXDEBUG 0

// POLL_MASK and POLL_SHIFT intend to convert the lower five POLL events into
// ZX_USER_SIGNALs and vice-versa. Other events need to be manually converted to
// an zx_signal_t, if they are desired.
#define POLL_SHIFT  24
#define POLL_MASK   0x1F

static_assert(ZX_USER_SIGNAL_0 == (1 << POLL_SHIFT), "");
static_assert((POLLIN << POLL_SHIFT) == DEVICE_SIGNAL_READABLE, "");
static_assert((POLLPRI << POLL_SHIFT) == DEVICE_SIGNAL_OOB, "");
static_assert((POLLOUT << POLL_SHIFT) == DEVICE_SIGNAL_WRITABLE, "");
static_assert((POLLERR << POLL_SHIFT) == DEVICE_SIGNAL_ERROR, "");
static_assert((POLLHUP << POLL_SHIFT) == DEVICE_SIGNAL_HANGUP, "");

static pthread_key_t rchannel_key;

static void rchannel_cleanup(void* data) {
    if (data == NULL) {
        return;
    }
    zx_handle_t* handles = (zx_handle_t*)data;
    if (handles[0] != ZX_HANDLE_INVALID)
        zx_handle_close(handles[0]);
    if (handles[1] != ZX_HANDLE_INVALID)
        zx_handle_close(handles[1]);
    free(handles);
}

void __fdio_rchannel_init(void) {
    if (pthread_key_create(&rchannel_key, &rchannel_cleanup) != 0)
        abort();
}

static const char* _opnames[] = ZXRIO_OPNAMES;
const char* fdio_opname(uint32_t op) {
    op = ZXRIO_OPNAME(op);
    if (op < ZXRIO_NUM_OPS) {
        return _opnames[op];
    } else {
        return "unknown";
    }
}

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

static bool is_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_message_valid(msg);
}

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

zx_status_t zxrio_handle_rpc(zx_handle_t h, zxrio_msg_t* msg, zxrio_cb_t cb, void* cookie) {
    zx_status_t r;

    // NOTE: hcount intentionally received out-of-bound from the message to
    // avoid letting "client-supplied" bytes override the REAL hcount value.
    uint32_t hcount = 0;
    uint32_t dsz = sizeof(zxrio_msg_t);
    if ((r = zx_channel_read(h, 0, msg, msg->handle, dsz, FDIO_MAX_HANDLES, &dsz, &hcount)) < 0) {
        return r;
    }
    // Now, "msg->hcount" can be trusted once again.
    msg->hcount = hcount;

    if (!is_message_reply_valid(msg, dsz)) {
        discard_handles(msg->handle, msg->hcount);
        return ZX_ERR_INVALID_ARGS;
    }

    bool is_close = (ZXRIO_OP(msg->op) == ZXRIO_CLOSE);

    xprintf("handle_rio: op=%s arg=%d len=%u hsz=%d\n",
            fdio_opname(msg->op), msg->arg, msg->datalen, msg->hcount);

    if ((msg->arg = cb(msg, cookie)) == ERR_DISPATCHER_INDIRECT) {
        // callback is handling the reply itself
        // and took ownership of the reply handle
        return ZX_OK;
    }
    if ((msg->arg < 0) || !is_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(MG-974): consider a better error code
        msg->arg = (msg->arg < 0) ? msg->arg : ZX_ERR_INTERNAL;
    }

    msg->op = ZXRIO_STATUS;
    if ((r = zx_channel_write(h, 0, msg, ZXRIO_HDR_SZ + msg->datalen, msg->handle, msg->hcount)) < 0) {
        discard_handles(msg->handle, msg->hcount);
    }
    if (is_close) {
        // signals to not perform a close callback
        return ERR_DISPATCHER_DONE;
    } else {
        return r;
    }
}

zx_status_t zxrio_handle_close(zxrio_cb_t cb, void* cookie) {
    zxrio_msg_t msg;

    // remote side was closed;
    msg.op = ZXRIO_CLOSE;
    msg.arg = 0;
    msg.datalen = 0;
    msg.hcount = 0;
    cb(&msg, cookie);
    return ZX_OK;
}

zx_status_t zxrio_handler(zx_handle_t h, void* _cb, void* cookie) {
    zxrio_cb_t cb = _cb;

    if (h == ZX_HANDLE_INVALID) {
        return zxrio_handle_close(cb, cookie);
    } else {
        zxrio_msg_t msg;
        return zxrio_handle_rpc(h, &msg, cb, cookie);
    }
}

void zxrio_txn_handoff(zx_handle_t srv, zx_handle_t reply, zxrio_msg_t* msg) {
    msg->txid = 0;
    msg->handle[0] = reply;
    msg->hcount = 1;

    zx_status_t r;
    uint32_t dsize = ZXRIO_HDR_SZ + msg->datalen;
    if ((r = zx_channel_write(srv, 0, msg, dsize, msg->handle, msg->hcount)) < 0) {
        // nothing to do but inform the caller that we failed
        struct {
            zx_status_t status;
            uint32_t type;
        } error = { r, 0 };
        zx_channel_write(reply, 0, &error, sizeof(error), NULL, 0);
        zx_handle_close(reply);
    }
}

// on success, msg->hcount indicates number of valid handles in msg->handle
// on error there are never any handles
static zx_status_t zxrio_txn(zxrio_t* rio, zxrio_msg_t* msg) {
    if (!is_message_valid(msg)) {
        return ZX_ERR_INVALID_ARGS;
    }

    msg->txid = atomic_fetch_add(&rio->txid, 1);
    xprintf("txn h=%x txid=%x op=%d len=%u\n", rio->h, msg->txid, msg->op, msg->datalen);

    zx_status_t r;
    zx_status_t rs = ZX_ERR_INTERNAL;
    uint32_t dsize;

    zx_channel_call_args_t args;
    args.wr_bytes = msg;
    args.wr_handles = msg->handle;
    args.rd_bytes = msg;
    args.rd_handles = msg->handle;
    args.wr_num_bytes = ZXRIO_HDR_SZ + msg->datalen;
    args.wr_num_handles = msg->hcount;
    args.rd_num_bytes = ZXRIO_HDR_SZ + FDIO_CHUNK_SIZE;
    args.rd_num_handles = FDIO_MAX_HANDLES;

    r = zx_channel_call(rio->h, 0, ZX_TIME_INFINITE, &args, &dsize, &msg->hcount, &rs);
    if (r < 0) {
        if (r == ZX_ERR_CALL_FAILED) {
            // read phase failed, true status is in rs
            msg->hcount = 0;
            return rs;
        } else {
            // write phase failed, we must discard the handles
            goto fail_discard_handles;
        }
    }

    // check for protocol errors
    if (!is_message_reply_valid(msg, dsize) ||
        (ZXRIO_OP(msg->op) != ZXRIO_STATUS)) {
        r = ZX_ERR_IO;
        goto fail_discard_handles;
    }
    // check for remote error
    if ((r = msg->arg) < 0) {
        goto fail_discard_handles;
    }
    return r;

fail_discard_handles:
    // We failed either writing at all (still have the handles)
    // or after reading (need to abandon any handles we received)
    discard_handles(msg->handle, msg->hcount);
    msg->hcount = 0;
    return r;
}

ssize_t zxrio_ioctl(fdio_t* io, uint32_t op, const void* in_buf,
                    size_t in_len, void* out_buf, size_t out_len) {
    zxrio_t* rio = (zxrio_t*)io;
    const uint8_t* data = in_buf;
    zx_status_t r = 0;
    zxrio_msg_t msg;

    if (in_len > FDIO_IOCTL_MAX_INPUT || out_len > FDIO_CHUNK_SIZE) {
        return ZX_ERR_INVALID_ARGS;
    }

    memset(&msg, 0, ZXRIO_HDR_SZ);
    msg.op = ZXRIO_IOCTL;
    msg.datalen = in_len;
    msg.arg = out_len;
    msg.arg2.op = op;

    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:
        msg.op = ZXRIO_IOCTL_1H;
        if (in_len < sizeof(zx_handle_t)) {
            return ZX_ERR_INVALID_ARGS;
        }
        msg.hcount = 1;
        msg.handle[0] = *((zx_handle_t*) in_buf);
        break;
    }

    memcpy(msg.data, data, in_len);

    if ((r = zxrio_txn(rio, &msg)) < 0) {
        return r;
    }

    size_t copy_len = msg.datalen;
    if (msg.datalen > out_len) {
        copy_len = out_len;
    }

    memcpy(out_buf, msg.data, copy_len);

    int handles = 0;
    switch (IOCTL_KIND(op)) {
        case IOCTL_KIND_GET_HANDLE:
            handles = (msg.hcount > 0 ? 1 : 0);
            if (handles) {
                memcpy(out_buf, msg.handle, sizeof(zx_handle_t));
            } else {
                memset(out_buf, 0, sizeof(zx_handle_t));
            }
            break;
        case IOCTL_KIND_GET_TWO_HANDLES:
            handles = (msg.hcount > 2 ? 2 : msg.hcount);
            if (handles) {
                memcpy(out_buf, msg.handle, handles * sizeof(zx_handle_t));
            }
            if (handles < 2) {
                memset(out_buf, 0, (2 - handles) * sizeof(zx_handle_t));
            }
            break;
        case IOCTL_KIND_GET_THREE_HANDLES:
            handles = (msg.hcount > 3 ? 3 : msg.hcount);
            if (handles) {
                memcpy(out_buf, msg.handle, handles * sizeof(zx_handle_t));
            }
            if (handles < 3) {
                memset(out_buf, 0, (3 - handles) * sizeof(zx_handle_t));
            }
            break;
    }
    discard_handles(msg.handle + handles, msg.hcount - handles);

    return r;
}

static ssize_t write_common(uint32_t op, fdio_t* io, const void* _data, size_t len, off_t offset) {
    zxrio_t* rio = (zxrio_t*)io;
    const uint8_t* data = _data;
    ssize_t count = 0;
    zx_status_t r = 0;
    zxrio_msg_t msg;
    ssize_t xfer;

    while (len > 0) {
        xfer = (len > FDIO_CHUNK_SIZE) ? FDIO_CHUNK_SIZE : len;

        memset(&msg, 0, ZXRIO_HDR_SZ);
        msg.op = op;
        msg.datalen = xfer;
        if (op == ZXRIO_WRITE_AT)
            msg.arg2.off = offset;
        memcpy(msg.data, data, xfer);

        if ((r = zxrio_txn(rio, &msg)) < 0) {
            break;
        }
        discard_handles(msg.handle, msg.hcount);

        if (r > xfer) {
            r = ZX_ERR_IO;
            break;
        }
        count += r;
        data += r;
        len -= r;
        if (op == ZXRIO_WRITE_AT)
            offset += r;
        // stop at short read
        if (r < xfer) {
            break;
        }
    }
    return count ? count : r;
}

static ssize_t zxrio_write(fdio_t* io, const void* _data, size_t len) {
    return write_common(ZXRIO_WRITE, io, _data, len, 0);
}

static ssize_t zxrio_write_at(fdio_t* io, const void* _data, size_t len, off_t offset) {
    return write_common(ZXRIO_WRITE_AT, io, _data, len, offset);
}

static ssize_t read_common(uint32_t op, fdio_t* io, void* _data, size_t len, off_t offset) {
    zxrio_t* rio = (zxrio_t*)io;
    uint8_t* data = _data;
    ssize_t count = 0;
    zx_status_t r = 0;
    zxrio_msg_t msg;
    ssize_t xfer;

    while (len > 0) {
        xfer = (len > FDIO_CHUNK_SIZE) ? FDIO_CHUNK_SIZE : len;

        memset(&msg, 0, ZXRIO_HDR_SZ);
        msg.op = op;
        msg.arg = xfer;
        if (op == ZXRIO_READ_AT)
            msg.arg2.off = offset;

        if ((r = zxrio_txn(rio, &msg)) < 0) {
            break;
        }
        discard_handles(msg.handle, msg.hcount);

        if ((r > (int)msg.datalen) || (r > xfer)) {
            r = ZX_ERR_IO;
            break;
        }
        memcpy(data, msg.data, r);
        count += r;
        data += r;
        len -= r;
        if (op == ZXRIO_READ_AT)
            offset += r;

        // stop at short read
        if (r < xfer) {
            break;
        }
    }
    return count ? count : r;
}

static ssize_t zxrio_read(fdio_t* io, void* _data, size_t len) {
    return read_common(ZXRIO_READ, io, _data, len, 0);
}

static ssize_t zxrio_read_at(fdio_t* io, void* _data, size_t len, off_t offset) {
    return read_common(ZXRIO_READ_AT, io, _data, len, offset);
}

static off_t zxrio_seek(fdio_t* io, off_t offset, int whence) {
    zxrio_t* rio = (zxrio_t*)io;
    zxrio_msg_t msg;
    zx_status_t r;

    memset(&msg, 0, ZXRIO_HDR_SZ);
    msg.op = ZXRIO_SEEK;
    msg.arg2.off = offset;
    msg.arg = whence;

    if ((r = zxrio_txn(rio, &msg)) < 0) {
        return r;
    }

    discard_handles(msg.handle, msg.hcount);
    return msg.arg2.off;
}

zx_status_t zxrio_close(fdio_t* io) {
    zxrio_t* rio = (zxrio_t*)io;
    zxrio_msg_t msg;
    zx_status_t r;

    memset(&msg, 0, ZXRIO_HDR_SZ);
    msg.op = ZXRIO_CLOSE;

    if ((r = zxrio_txn(rio, &msg)) >= 0) {
        discard_handles(msg.handle, msg.hcount);
    }

    zx_handle_t h = rio->h;
    rio->h = 0;
    zx_handle_close(h);
    if (rio->h2 > 0) {
        h = rio->h2;
        rio->h2 = 0;
        zx_handle_close(h);
    }

    return r;
}

static zx_status_t zxrio_reply_channel_call(zx_handle_t rio_h, zxrio_msg_t* msg,
                                            zxrio_object_t* info) {
    zx_status_t r;
    zx_handle_t h;
    if ((r = zx_channel_create(0, &h, &msg->handle[0])) < 0) {
        return r;
    }
    msg->hcount = 1;

    // Write the (one-way) request message
    if ((r = zx_channel_write(rio_h, 0, msg, ZXRIO_HDR_SZ + msg->datalen,
                              msg->handle, msg->hcount)) < 0) {
        zx_handle_close(msg->handle[0]);
        zx_handle_close(h);
        return r;
    }

    // Wait
    zx_object_wait_one(h, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ZX_TIME_INFINITE, NULL);

    // Attempt to read the callback response
    memset(info, 0xfe, sizeof(*info));
    uint32_t dsize = ZXRIO_OBJECT_MAXSIZE;
    info->hcount = FDIO_MAX_HANDLES;
    r = zx_channel_read(h, 0, info, &info->handle[1], dsize,
                        info->hcount, &dsize, &info->hcount);
    if (r < 0) {
        zx_handle_close(h);
        return r;
    }
    info->handle[0] = h;
    info->hcount++;
    if (dsize < ZXRIO_OBJECT_MINSIZE) {
        r = ZX_ERR_IO;
    } else {
        info->esize = dsize - ZXRIO_OBJECT_MINSIZE;
        r = info->status;
    }
    if (r < 0) {
        discard_handles(info->handle, info->hcount);
    }
    return r;
}

// This function always consumes the cnxn handle
// The svc handle is only used to send a message
static zx_status_t zxrio_connect(zx_handle_t svc, zx_handle_t cnxn,
                                 uint32_t op, int32_t flags, uint32_t mode,
                                 const char* name) {
    size_t len = strlen(name);
    if (len >= PATH_MAX) {
        zx_handle_close(cnxn);
        return ZX_ERR_BAD_PATH;
    }

    zxrio_msg_t msg;
    memset(&msg, 0, ZXRIO_HDR_SZ);
    msg.op = op;
    msg.datalen = len;
    msg.arg = O_PIPELINE | flags;
    msg.arg2.mode = mode;
    msg.hcount = 1;
    msg.handle[0] = cnxn;
    memcpy(msg.data, name, len);

    zx_status_t r;
    if ((r = zx_channel_write(svc, 0, &msg, ZXRIO_HDR_SZ + msg.datalen, msg.handle, 1)) < 0) {
        zx_handle_close(cnxn);
        return r;
    }

    return ZX_OK;
}

zx_status_t fdio_service_connect(const char* svcpath, zx_handle_t h) {
    if (svcpath == NULL) {
        zx_handle_close(h);
        return ZX_ERR_INVALID_ARGS;
    }
    // Otherwise attempt to connect through the root namespace
    if (fdio_root_ns != NULL) {
        return fdio_ns_connect(fdio_root_ns, svcpath, h);
    }
    // Otherwise we fail
    zx_handle_close(h);
    return ZX_ERR_NOT_FOUND;
}

zx_status_t fdio_service_connect_at(zx_handle_t dir, const char* path, zx_handle_t h) {
    if (path == NULL) {
        zx_handle_close(h);
        return ZX_ERR_INVALID_ARGS;
    }
    if (dir == ZX_HANDLE_INVALID) {
        zx_handle_close(h);
        return ZX_ERR_UNAVAILABLE;
    }
    return zxrio_connect(dir, h, ZXRIO_OPEN, O_RDWR, 0755, path);
}

zx_handle_t fdio_service_clone(zx_handle_t svc) {
    zx_handle_t cli, srv;
    zx_status_t r;
    if (svc == ZX_HANDLE_INVALID) {
        return ZX_HANDLE_INVALID;
    }
    if ((r = zx_channel_create(0, &cli, &srv)) < 0) {
        return ZX_HANDLE_INVALID;
    }
    if ((r = zxrio_connect(svc, srv, ZXRIO_CLONE, O_RDWR, 0755, "")) < 0) {
        zx_handle_close(cli);
        return ZX_HANDLE_INVALID;
    }
    return cli;
}

zx_status_t zxrio_misc(fdio_t* io, uint32_t op, int64_t off,
                       uint32_t maxreply, void* ptr, size_t len) {
    zxrio_t* rio = (zxrio_t*)io;
    zxrio_msg_t msg;
    zx_status_t r;

    if ((len > FDIO_CHUNK_SIZE) || (maxreply > FDIO_CHUNK_SIZE)) {
        return ZX_ERR_INVALID_ARGS;
    }

    memset(&msg, 0, ZXRIO_HDR_SZ);
    msg.op = op;
    msg.arg = maxreply;
    msg.arg2.off = off;
    msg.datalen = len;
    if (ptr && len > 0) {
        memcpy(msg.data, ptr, len);
    }
    switch (op) {
    case ZXRIO_RENAME:
    case ZXRIO_LINK:
        // As a hack, 'Rename' and 'Link' take token handles through
        // the offset argument.
        msg.handle[0] = (zx_handle_t) off;
        msg.hcount = 1;
    }

    if ((r = zxrio_txn(rio, &msg)) < 0) {
        return r;
    }

    switch (op) {
    case ZXRIO_MMAP: {
        // Ops which receive single handles:
        if ((msg.hcount != 1) || (msg.datalen > maxreply)) {
            discard_handles(msg.handle, msg.hcount);
            return ZX_ERR_IO;
        }
        r = msg.handle[0];
        memcpy(ptr, msg.data, msg.datalen);
        break;
    }
    case ZXRIO_FCNTL:
        // This is a bit of a hack, but for this case, we
        // return 'msg.arg2.mode' in the data field to simplify
        // this call for the client.
        discard_handles(msg.handle, msg.hcount);
        if (ptr) {
            memcpy(ptr, &msg.arg2.mode, sizeof(msg.arg2.mode));
        }
        break;
    default:
        // Ops which don't receive handles:
        discard_handles(msg.handle, msg.hcount);
        if (msg.datalen > maxreply) {
            return ZX_ERR_IO;
        }
        if (ptr && msg.datalen > 0) {
            memcpy(ptr, msg.data, msg.datalen);
        }
    }
    return r;
}

zx_status_t fdio_create_fd(zx_handle_t* handles, uint32_t* types, size_t hcount,
                           int* fd_out) {
    fdio_t* io;
    zx_status_t r;
    int fd;
    uint32_t type;

    switch (PA_HND_TYPE(types[0])) {
    case PA_FDIO_REMOTE:
        type = FDIO_PROTOCOL_REMOTE;
        break;
    case PA_FDIO_PIPE:
        type = FDIO_PROTOCOL_PIPE;
        break;
    case PA_FDIO_SOCKET:
        type = FDIO_PROTOCOL_SOCKET_CONNECTED;
        break;
    default:
        r = ZX_ERR_IO;
        goto fail;
    }

    if ((r = fdio_from_handles(type, handles, hcount, NULL, 0, &io)) != ZX_OK) {
        goto fail;
    }

    fd = fdio_bind_to_fd(io, -1, 0);
    if (fd < 0) {
        fdio_close(io);
        fdio_release(io);
        return ZX_ERR_BAD_STATE;
    }

    *fd_out = fd;
    return ZX_OK;
fail:
    for (size_t i = 0; i < hcount; i++) {
        zx_handle_close(handles[i]);
    }
    return r;
}

zx_status_t fdio_from_handles(uint32_t type, zx_handle_t* handles, int hcount,
                              void* extra, uint32_t esize, fdio_t** out) {
    // All failure cases which require discard_handles set r and break
    // to the end. All other cases in which handle ownership is moved
    // on return locally.
    zx_status_t r;
    fdio_t* io;
    switch (type) {
    case FDIO_PROTOCOL_REMOTE:
        if (hcount == 1) {
            io = fdio_remote_create(handles[0], 0);
            xprintf("rio (%x,%x) -> %p\n", handles[0], 0, io);
        } else if (hcount == 2) {
            io = fdio_remote_create(handles[0], handles[1]);
            xprintf("rio (%x,%x) -> %p\n", handles[0], handles[1], io);
        } else {
            r = ZX_ERR_INVALID_ARGS;
            break;
        }
        if (io == NULL) {
            return ZX_ERR_NO_RESOURCES;
        } else {
            *out = io;
            return ZX_OK;
        }
        break;
    case FDIO_PROTOCOL_SERVICE:
        if (hcount != 1) {
            r = ZX_ERR_INVALID_ARGS;
            break;
        } else if ((*out = fdio_service_create(handles[0])) == NULL) {
            return ZX_ERR_NO_RESOURCES;
        } else {
            return ZX_OK;
        }
        break;
    case FDIO_PROTOCOL_PIPE:
        if (hcount != 1) {
            r = ZX_ERR_INVALID_ARGS;
            break;
        } else if ((*out = fdio_pipe_create(handles[0])) == NULL) {
            return ZX_ERR_NO_RESOURCES;
        } else {
            return ZX_OK;
        }
    case FDIO_PROTOCOL_VMOFILE: {
        zx_off_t* args = extra;
        if ((hcount != 2) || (esize != (sizeof(zx_off_t) * 2))) {
            r = ZX_ERR_INVALID_ARGS;
            break;
        }
        // Currently, VMO Files don't use a client-side control channel.
        zx_handle_close(handles[0]);
        if ((*out = fdio_vmofile_create(handles[1], args[0], args[1])) == NULL) {
            return ZX_ERR_NO_RESOURCES;
        } else {
            return ZX_OK;
        }
    }
    case FDIO_PROTOCOL_SOCKET_CONNECTED:
    case FDIO_PROTOCOL_SOCKET: {
        int flags = (type == FDIO_PROTOCOL_SOCKET_CONNECTED) ? FDIO_FLAG_SOCKET_CONNECTED : 0;
        if (hcount == 1) {
            io = fdio_socket_create(handles[0], ZX_HANDLE_INVALID, flags);
        } else if (hcount == 2) {
            io = fdio_socket_create(handles[0], handles[1], flags);
        } else {
            r = ZX_ERR_INVALID_ARGS;
            break;
        }
        if (io == NULL) {
            return ZX_ERR_NO_RESOURCES;
        } else {
            *out = io;
            return ZX_OK;
        }
    }
    default:
        r = ZX_ERR_NOT_SUPPORTED;
        break;
    }
    discard_handles(handles, hcount);
    return r;
}

zx_status_t zxrio_getobject(zx_handle_t rio_h, uint32_t op, const char* name,
                            int32_t flags, uint32_t mode,
                            zxrio_object_t* info) {
    if (name == NULL) {
        return ZX_ERR_INVALID_ARGS;
    }

    size_t len = strlen(name);
    if (len >= PATH_MAX) {
        return ZX_ERR_BAD_PATH;
    }

    if (flags & O_PIPELINE) {
        zx_handle_t h0, h1;
        zx_status_t r;
        if ((r = zx_channel_create(0, &h0, &h1)) < 0) {
            return r;
        }
        if ((r = zxrio_connect(rio_h, h1, ZXRIO_OPEN, flags, mode, name)) < 0) {
            zx_handle_close(h0);
            return r;
        }
        // fake up a reply message since pipelined opens don't generate one
        info->status = ZX_OK;
        info->type = FDIO_PROTOCOL_REMOTE;
        info->esize = 0;
        info->hcount = 1;
        info->handle[0] = h0;
        return ZX_OK;
    } else {
        zxrio_msg_t msg;
        memset(&msg, 0, ZXRIO_HDR_SZ);
        msg.op = op;
        msg.datalen = len;
        msg.arg = flags;
        msg.arg2.mode = mode;
        memcpy(msg.data, name, len);

        return zxrio_reply_channel_call(rio_h, &msg, info);
    }
}

zx_status_t zxrio_open_handle(zx_handle_t h, const char* path, int32_t flags,
                              uint32_t mode, fdio_t** out) {
    zxrio_object_t info;
    zx_status_t r = zxrio_getobject(h, ZXRIO_OPEN, path, flags, mode, &info);
    if (r < 0) {
        return r;
    }
    return fdio_from_handles(info.type, info.handle, info.hcount, info.extra, info.esize, out);
}

zx_status_t zxrio_open_handle_raw(zx_handle_t h, const char* path, int32_t flags,
                                  uint32_t mode, zx_handle_t *out) {
    zxrio_object_t info;
    zx_status_t r = zxrio_getobject(h, ZXRIO_OPEN, path, flags, mode, &info);
    if (r < 0) {
        return r;
    }
    if ((info.type == FDIO_PROTOCOL_REMOTE) && (info.hcount > 0)) {
        for (unsigned n = 1; n < info.hcount; n++) {
            zx_handle_close(info.handle[n]);
        }
        *out = info.handle[0];
        return ZX_OK;
    }
    for (unsigned n = 0; n < info.hcount; n++) {
        zx_handle_close(info.handle[n]);
    }
    return ZX_ERR_WRONG_TYPE;
}

zx_status_t zxrio_open(fdio_t* io, const char* path, int32_t flags, uint32_t mode, fdio_t** out) {
    zxrio_t* rio = (void*)io;
    zxrio_object_t info;
    zx_status_t r = zxrio_getobject(rio->h, ZXRIO_OPEN, path, flags, mode, &info);
    if (r < 0) {
        return r;
    }
    return fdio_from_handles(info.type, info.handle, info.hcount, info.extra, info.esize, out);
}

static zx_status_t zxrio_clone(fdio_t* io, zx_handle_t* handles, uint32_t* types) {
    zxrio_t* rio = (void*)io;
    zxrio_object_t info;
    zx_status_t r = zxrio_getobject(rio->h, ZXRIO_CLONE, "", 0, 0, &info);
    if (r < 0) {
        return r;
    }
    for (unsigned i = 0; i < info.hcount; i++) {
        types[i] = PA_FDIO_REMOTE;
    }
    memcpy(handles, info.handle, info.hcount * sizeof(zx_handle_t));
    return info.hcount;
}

zx_status_t __zxrio_clone(zx_handle_t h, zx_handle_t* handles, uint32_t* types) {
    zxrio_t rio;
    rio.h = h;
    return zxrio_clone(&rio.io, handles, types);
}

static zx_status_t zxrio_unwrap(fdio_t* io, zx_handle_t* handles, uint32_t* types) {
    zxrio_t* rio = (void*)io;
    zx_status_t r;
    handles[0] = rio->h;
    types[0] = PA_FDIO_REMOTE;
    if (rio->h2 != 0) {
        handles[1] = rio->h2;
        types[1] = PA_FDIO_REMOTE;
        r = 2;
    } else {
        r = 1;
    }
    free(io);
    return r;
}

static void zxrio_wait_begin(fdio_t* io, uint32_t events, zx_handle_t* handle, zx_signals_t* _signals) {
    zxrio_t* rio = (void*)io;
    *handle = rio->h2;

    zx_signals_t signals = 0;
    // Manually add signals that don't fit within POLL_MASK
    if (events & POLLRDHUP) {
        signals |= ZX_CHANNEL_PEER_CLOSED;
    }

    // POLLERR is always detected
    *_signals = (((POLLERR | events) & POLL_MASK) << POLL_SHIFT) | signals;
}

static void zxrio_wait_end(fdio_t* io, zx_signals_t signals, uint32_t* _events) {
    // Manually add events that don't fit within POLL_MASK
    uint32_t events = 0;
    if (signals & ZX_CHANNEL_PEER_CLOSED) {
        events |= POLLRDHUP;
    }
    *_events = ((signals >> POLL_SHIFT) & POLL_MASK) | events;
}

static fdio_ops_t zx_remote_ops = {
    .read = zxrio_read,
    .read_at = zxrio_read_at,
    .write = zxrio_write,
    .write_at = zxrio_write_at,
    .recvfrom = fdio_default_recvfrom,
    .sendto = fdio_default_sendto,
    .recvmsg = fdio_default_recvmsg,
    .sendmsg = fdio_default_sendmsg,
    .misc = zxrio_misc,
    .seek = zxrio_seek,
    .close = zxrio_close,
    .open = zxrio_open,
    .clone = zxrio_clone,
    .ioctl = zxrio_ioctl,
    .wait_begin = zxrio_wait_begin,
    .wait_end = zxrio_wait_end,
    .unwrap = zxrio_unwrap,
    .shutdown = fdio_default_shutdown,
    .posix_ioctl = fdio_default_posix_ioctl,
    .get_vmo = fdio_default_get_vmo,
};

fdio_t* fdio_remote_create(zx_handle_t h, zx_handle_t e) {
    zxrio_t* rio = calloc(1, sizeof(*rio));
    if (rio == NULL) {
        zx_handle_close(h);
        zx_handle_close(e);
        return NULL;
    }
    rio->io.ops = &zx_remote_ops;
    rio->io.magic = FDIO_MAGIC;
    atomic_init(&rio->io.refcount, 1);
    rio->h = h;
    rio->h2 = e;
    return &rio->io;
}
