1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <lib/fdio/io.h>
6
7#include <stdatomic.h>
8#include <stdlib.h>
9#include <threads.h>
10
11#include <zircon/syscalls.h>
12
13#include "private.h"
14
15typedef struct fdio_out fdio_out_t;
16
17struct fdio_out {
18    fdio_t io;
19    ssize_t (*func)(void* cookie, const void* data, size_t len);
20    void* cookie;
21};
22
23static ssize_t log_write(fdio_t* io, const void* data, size_t len) {
24    fdio_out_t* out = (void*)io;
25    return out->func(out->cookie, data, len);
26}
27
28static zx_status_t log_close(fdio_t* io) {
29    return ZX_OK;
30}
31
32static fdio_ops_t out_io_ops = {
33    .read = fdio_default_read,
34    .read_at = fdio_default_read_at,
35    .write = log_write,
36    .write_at = fdio_default_write_at,
37    .seek = fdio_default_seek,
38    .misc = fdio_default_misc,
39    .close = fdio_default_close,
40    .open = fdio_default_open,
41    .clone = fdio_default_clone,
42    .ioctl = fdio_default_ioctl,
43    .wait_begin = fdio_default_wait_begin,
44    .wait_end = fdio_default_wait_end,
45    .unwrap = fdio_default_unwrap,
46    .posix_ioctl = fdio_default_posix_ioctl,
47    .get_vmo = fdio_default_get_vmo,
48    .get_token = fdio_default_get_token,
49    .get_attr = fdio_default_get_attr,
50    .set_attr = fdio_default_set_attr,
51    .sync = fdio_default_sync,
52    .readdir = fdio_default_readdir,
53    .rewind = fdio_default_rewind,
54    .unlink = fdio_default_unlink,
55    .truncate = fdio_default_truncate,
56    .rename = fdio_default_rename,
57    .link = fdio_default_link,
58    .get_flags = fdio_default_get_flags,
59    .set_flags = fdio_default_set_flags,
60    .recvfrom = fdio_default_recvfrom,
61    .sendto = fdio_default_sendto,
62    .recvmsg = fdio_default_recvmsg,
63    .sendmsg = fdio_default_sendmsg,
64    .shutdown = fdio_default_shutdown,
65};
66
67__EXPORT
68fdio_t* fdio_output_create(ssize_t (*func)(void* cookie, const void* data, size_t len),
69                           void* cookie) {
70    fdio_out_t* out = fdio_alloc(sizeof(fdio_out_t));
71    if (out == NULL) {
72        return NULL;
73    }
74    out->io.ops = &out_io_ops;
75    out->io.magic = FDIO_MAGIC;
76    atomic_init(&out->io.refcount, 1);
77    out->func = func;
78    out->cookie = cookie;
79    return &out->io;
80}
81