1 // Copyright 2018 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/zx/channel.h>
6 #include <lib/zxio/inception.h>
7 #include <lib/zxio/ops.h>
8 #include <lib/zxio/zxio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <zircon/syscalls.h>
12 
13 // The private fields of a |zxio_t| object.
14 //
15 // In |ops.h|, the |zxio_t| struct is defined as opaque. Clients of the zxio
16 // library are forbidden from relying upon the structure of |zxio_t| objects.
17 // To avoid temptation, the details of the structure are defined only in this
18 // implementation file and are not visible in the header.
19 typedef struct zxio_internal {
20     const zxio_ops_t* ops;
21     uint64_t reserved[3];
22 } zxio_internal_t;
23 
24 static_assert(sizeof(zxio_t) == sizeof(zxio_internal_t),
25               "zxio_t should match zxio_internal_t");
26 
27 static_assert(ZXIO_READABLE == __ZX_OBJECT_READABLE,
28               "ZXIO signal bits should match ZX");
29 static_assert(ZXIO_WRITABLE == __ZX_OBJECT_WRITABLE,
30               "ZXIO signal bits should match ZX");
31 static_assert(ZXIO_READ_DISABLED == ZX_SOCKET_PEER_WRITE_DISABLED,
32               "ZXIO signal bits should match ZX");
33 static_assert(ZXIO_WRITE_DISABLED == ZX_SOCKET_WRITE_DISABLED,
34               "ZXIO signal bits should match ZX");
35 static_assert(ZXIO_READ_THRESHOLD == ZX_SOCKET_READ_THRESHOLD,
36               "ZXIO signal bits should match ZX");
37 static_assert(ZXIO_WRITE_THRESHOLD == ZX_SOCKET_WRITE_THRESHOLD,
38               "ZXIO signal bits should match ZX");
39 
zxio_init(zxio_t * io,const zxio_ops_t * ops)40 void zxio_init(zxio_t* io, const zxio_ops_t* ops) {
41     zxio_internal_t* zio = (zxio_internal_t*)io;
42     memset(zio, 0, sizeof(*zio));
43     zio->ops = ops;
44 }
45 
zxio_acquire_node(zx_handle_t node,zxio_t ** out_io)46 zx_status_t zxio_acquire_node(zx_handle_t node, zxio_t** out_io) {
47     zx_handle_close(node);
48     return ZX_ERR_NOT_SUPPORTED;
49 }
50 
zxio_acquire_socket(zx_handle_t socket,zxio_t ** out_io)51 zx_status_t zxio_acquire_socket(zx_handle_t socket, zxio_t** out_io) {
52     zx_handle_close(socket);
53     return ZX_ERR_NOT_SUPPORTED;
54 }
55 
zxio_release(zxio_t * io,zx_handle_t * out_io)56 zx_status_t zxio_release(zxio_t* io, zx_handle_t* out_io) {
57     zxio_internal_t* zio = (zxio_internal_t*)io;
58     return zio->ops->release(io, out_io);
59 }
60 
zxio_close(zxio_t * io)61 zx_status_t zxio_close(zxio_t* io) {
62     zxio_internal_t* zio = (zxio_internal_t*)io;
63     return zio->ops->close(io);
64 }
65 
zxio_wait_one(zxio_t * io,zxio_signals_t signals,zx_time_t deadline,zxio_signals_t * out_observed)66 zx_status_t zxio_wait_one(zxio_t* io, zxio_signals_t signals,
67                           zx_time_t deadline, zxio_signals_t* out_observed) {
68     zx_handle_t handle = ZX_HANDLE_INVALID;
69     zx_signals_t zx_signals = ZX_SIGNAL_NONE;
70     zxio_wait_begin(io, signals, &handle, &zx_signals);
71     if (handle == ZX_HANDLE_INVALID) {
72         return ZX_ERR_NOT_SUPPORTED;
73     }
74     zx_signals_t zx_observed = ZX_SIGNAL_NONE;
75     zx_status_t status = zx_object_wait_one(handle, zx_signals, deadline,
76                                             &zx_observed);
77     if (status != ZX_OK) {
78         return status;
79     }
80     zxio_wait_end(io, zx_signals, out_observed);
81     return ZX_OK;
82 }
83 
zxio_wait_begin(zxio_t * io,zxio_signals_t zxio_signals,zx_handle_t * out_handle,zx_signals_t * out_zx_signals)84 void zxio_wait_begin(zxio_t* io, zxio_signals_t zxio_signals,
85                      zx_handle_t* out_handle, zx_signals_t* out_zx_signals) {
86     zxio_internal_t* zio = (zxio_internal_t*)io;
87     return zio->ops->wait_begin(io, zxio_signals, out_handle, out_zx_signals);
88 }
89 
zxio_wait_end(zxio_t * io,zx_signals_t zx_signals,zxio_signals_t * out_zxio_signals)90 void zxio_wait_end(zxio_t* io, zx_signals_t zx_signals,
91                    zxio_signals_t* out_zxio_signals) {
92     zxio_internal_t* zio = (zxio_internal_t*)io;
93     return zio->ops->wait_end(io, zx_signals, out_zxio_signals);
94 }
95 
zxio_clone(zxio_t * io,uint32_t flags,zxio_t ** out_io)96 zx_status_t zxio_clone(zxio_t* io, uint32_t flags, zxio_t** out_io) {
97     zx::channel h1, h2;
98     zx_status_t status = zx::channel::create(0, &h1, &h2);
99     if (status != ZX_OK)
100         return status;
101     status = zxio_clone_async(io, flags, h1.release());
102     if (status != ZX_OK)
103         return status;
104     return zxio_acquire_node(h2.release(), out_io);
105 }
106 
zxio_clone_async(zxio_t * io,uint32_t flags,zx_handle_t request)107 zx_status_t zxio_clone_async(zxio_t* io, uint32_t flags,
108                              zx_handle_t request) {
109     zxio_internal_t* zio = (zxio_internal_t*)io;
110     return zio->ops->clone_async(io, flags, request);
111 }
112 
zxio_sync(zxio_t * io)113 zx_status_t zxio_sync(zxio_t* io) {
114     zxio_internal_t* zio = (zxio_internal_t*)io;
115     return zio->ops->sync(io);
116 }
117 
zxio_attr_get(zxio_t * io,zxio_node_attr_t * out_attr)118 zx_status_t zxio_attr_get(zxio_t* io, zxio_node_attr_t* out_attr) {
119     zxio_internal_t* zio = (zxio_internal_t*)io;
120     return zio->ops->attr_get(io, out_attr);
121 }
122 
zxio_attr_set(zxio_t * io,uint32_t flags,const zxio_node_attr_t * attr)123 zx_status_t zxio_attr_set(zxio_t* io, uint32_t flags,
124                           const zxio_node_attr_t* attr) {
125     zxio_internal_t* zio = (zxio_internal_t*)io;
126     return zio->ops->attr_set(io, flags, attr);
127 }
128 
zxio_read(zxio_t * io,void * buffer,size_t capacity,size_t * out_actual)129 zx_status_t zxio_read(zxio_t* io, void* buffer, size_t capacity,
130                       size_t* out_actual) {
131     zxio_internal_t* zio = (zxio_internal_t*)io;
132     return zio->ops->read(io, buffer, capacity, out_actual);
133 }
134 
zxio_read_at(zxio_t * io,size_t offset,void * buffer,size_t capacity,size_t * out_actual)135 zx_status_t zxio_read_at(zxio_t* io, size_t offset, void* buffer,
136                          size_t capacity, size_t* out_actual) {
137     zxio_internal_t* zio = (zxio_internal_t*)io;
138     return zio->ops->read_at(io, offset, buffer, capacity,
139                              out_actual);
140 }
141 
zxio_write(zxio_t * io,const void * buffer,size_t capacity,size_t * out_actual)142 zx_status_t zxio_write(zxio_t* io, const void* buffer, size_t capacity,
143                        size_t* out_actual) {
144     zxio_internal_t* zio = (zxio_internal_t*)io;
145     return zio->ops->write(io, buffer, capacity, out_actual);
146 }
147 
zxio_write_at(zxio_t * io,size_t offset,const void * buffer,size_t capacity,size_t * out_actual)148 zx_status_t zxio_write_at(zxio_t* io, size_t offset, const void* buffer,
149                           size_t capacity, size_t* out_actual) {
150     zxio_internal_t* zio = (zxio_internal_t*)io;
151     return zio->ops->write_at(io, offset, buffer, capacity,
152                               out_actual);
153 }
154 
zxio_seek(zxio_t * io,size_t offset,zxio_seek_origin_t start,size_t * out_offset)155 zx_status_t zxio_seek(zxio_t* io, size_t offset,
156                       zxio_seek_origin_t start, size_t* out_offset) {
157     zxio_internal_t* zio = (zxio_internal_t*)io;
158     return zio->ops->seek(io, offset, start, out_offset);
159 }
160 
zxio_truncate(zxio_t * io,size_t length)161 zx_status_t zxio_truncate(zxio_t* io, size_t length) {
162     zxio_internal_t* zio = (zxio_internal_t*)io;
163     return zio->ops->truncate(io, length);
164 }
165 
zxio_flags_get(zxio_t * io,uint32_t * out_flags)166 zx_status_t zxio_flags_get(zxio_t* io, uint32_t* out_flags) {
167     zxio_internal_t* zio = (zxio_internal_t*)io;
168     return zio->ops->flags_get(io, out_flags);
169 }
170 
zxio_flags_set(zxio_t * io,uint32_t flags)171 zx_status_t zxio_flags_set(zxio_t* io, uint32_t flags) {
172     zxio_internal_t* zio = (zxio_internal_t*)io;
173     return zio->ops->flags_set(io, flags);
174 }
175 
zxio_vmo_get_copy(zxio_t * io,zx_handle_t * out_vmo,size_t * out_size)176 zx_status_t zxio_vmo_get_copy(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
177     return ZX_ERR_NOT_SUPPORTED;
178 }
179 
zxio_vmo_get_clone(zxio_t * io,zx_handle_t * out_vmo,size_t * out_size)180 zx_status_t zxio_vmo_get_clone(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
181     return ZX_ERR_NOT_SUPPORTED;
182 }
183 
zxio_vmo_get_exact(zxio_t * io,zx_handle_t * out_vmo,size_t * out_size)184 zx_status_t zxio_vmo_get_exact(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
185     return ZX_ERR_NOT_SUPPORTED;
186 }
187 
zxio_open(zxio_t * directory,uint32_t flags,uint32_t mode,const char * path,zxio_t ** out_io)188 zx_status_t zxio_open(zxio_t* directory, uint32_t flags, uint32_t mode,
189                       const char* path, zxio_t** out_io) {
190     zxio_internal_t* zio = (zxio_internal_t*)directory;
191     return zio->ops->open(directory, flags, mode, path, out_io);
192 }
193 
zxio_open_async(zxio_t * directory,uint32_t flags,uint32_t mode,const char * path,zx_handle_t request)194 zx_status_t zxio_open_async(zxio_t* directory, uint32_t flags,
195                             uint32_t mode, const char* path,
196                             zx_handle_t request) {
197     zxio_internal_t* zio = (zxio_internal_t*)directory;
198     return zio->ops->open_async(directory, flags, mode, path, request);
199 }
200 
zxio_unlink(zxio_t * directory,const char * path)201 zx_status_t zxio_unlink(zxio_t* directory, const char* path) {
202     zxio_internal_t* zio = (zxio_internal_t*)directory;
203     return zio->ops->unlink(directory, path);
204 }
205 
zxio_rename(zxio_t * old_directory,const char * old_path,zxio_t * new_directory,const char * new_path)206 zx_status_t zxio_rename(zxio_t* old_directory, const char* old_path,
207                         zxio_t* new_directory, const char* new_path) {
208     return ZX_ERR_NOT_SUPPORTED;
209 }
210 
zxio_link(zxio_t * src_directory,const char * src_path,zxio_t * dst_directory,const char * dst_path)211 zx_status_t zxio_link(zxio_t* src_directory, const char* src_path,
212                       zxio_t* dst_directory, const char* dst_path) {
213     return ZX_ERR_NOT_SUPPORTED;
214 }
215 
zxio_dirent_iterator_init(zxio_dirent_iterator_t * iterator,zxio_t * directory,void * buffer,size_t capacity)216 zx_status_t zxio_dirent_iterator_init(zxio_dirent_iterator_t* iterator,
217                                       zxio_t* directory, void* buffer,
218                                       size_t capacity) {
219     return ZX_ERR_NOT_SUPPORTED;
220 }
221 
zxio_dirent_iterator_next(zxio_dirent_iterator_t * iterator,zxio_dirent_t ** out_entry)222 zx_status_t zxio_dirent_iterator_next(zxio_dirent_iterator_t* iterator,
223                                       zxio_dirent_t** out_entry) {
224     return ZX_ERR_NOT_SUPPORTED;
225 }
226