diff --git a/expected/wasm32-wasip3/defined-symbols.txt b/expected/wasm32-wasip3/defined-symbols.txt index 02a9aafa9..850cfee4a 100644 --- a/expected/wasm32-wasip3/defined-symbols.txt +++ b/expected/wasm32-wasip3/defined-symbols.txt @@ -331,7 +331,7 @@ __wasilibc_parse_port __wasilibc_populate_preopens __wasilibc_pthread_self __wasilibc_random -__wasilibc_read_stream3 +__wasilibc_read __wasilibc_rename_newat __wasilibc_rename_oldat __wasilibc_reset_preopens @@ -345,7 +345,7 @@ __wasilibc_unspecified_addr __wasilibc_utimens __wasilibc_wasi_family_to_libc __wasilibc_wasi_to_sockaddr -__wasilibc_write_stream3 +__wasilibc_write __wasm_call_dtors __wcscoll_l __wcsftime_l diff --git a/libc-bottom-half/CMakeLists.txt b/libc-bottom-half/CMakeLists.txt index 65012cb03..4bdce3ff8 100644 --- a/libc-bottom-half/CMakeLists.txt +++ b/libc-bottom-half/CMakeLists.txt @@ -139,6 +139,7 @@ else() sources/descriptor_table.c sources/getsockpeername.c sources/listen.c + sources/file_utils.c sources/recv.c sources/send.c sources/shutdown.c @@ -155,7 +156,6 @@ if(WASI STREQUAL "p2") sources/netdb.c sources/wasip2.c sources/wasip2_file.c - sources/wasip2_file_utils.c sources/wasip2_stdio.c ) endif() @@ -165,7 +165,6 @@ if (WASI STREQUAL "p3") sources/wasip3.c sources/wasip3_block_on.c sources/wasip3_file.c - sources/wasip3_file_utils.c sources/wasip3_stdio.c ) endif() diff --git a/libc-bottom-half/cloudlibc/src/libc/poll/poll.c b/libc-bottom-half/cloudlibc/src/libc/poll/poll.c index 95ec03561..796f97c4b 100644 --- a/libc-bottom-half/cloudlibc/src/libc/poll/poll.c +++ b/libc-bottom-half/cloudlibc/src/libc/poll/poll.c @@ -216,7 +216,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) { if (pollfd->events & POLLRDNORM) { if (entry->vtable->get_read_stream) { - wasip2_read_t read; + wasi_read_t read; if (entry->vtable->get_read_stream(entry->data, &read) < 0) return -1; if (__wasilibc_poll_add_input_stream(&state, read.input, read.pollable) < 0) @@ -229,7 +229,7 @@ static int poll_impl(struct pollfd *fds, size_t nfds, int timeout) { if (pollfd->events & POLLWRNORM) { if (entry->vtable->get_write_stream) { - wasip2_write_t write; + wasi_write_t write; if (entry->vtable->get_write_stream(entry->data, &write) < 0) return -1; if (__wasilibc_poll_add_output_stream(&state, write.output, write.pollable) < 0) diff --git a/libc-bottom-half/cloudlibc/src/libc/unistd/read.c b/libc-bottom-half/cloudlibc/src/libc/unistd/read.c index 12db46717..36f2241ce 100644 --- a/libc-bottom-half/cloudlibc/src/libc/unistd/read.c +++ b/libc-bottom-half/cloudlibc/src/libc/unistd/read.c @@ -27,12 +27,12 @@ ssize_t read(int fildes, void *buf, size_t nbyte) { return -1; } return bytes_read; -#elif defined(__wasip2__) +#else descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes); if (!entry) return -1; if (entry->vtable->get_read_stream) { - wasip2_read_t read; + wasi_read_t read; if (entry->vtable->get_read_stream(entry->data, &read) < 0) return -1; return __wasilibc_read(&read, buf, nbyte); @@ -41,30 +41,5 @@ ssize_t read(int fildes, void *buf, size_t nbyte) { return entry->vtable->recvfrom(entry->data, buf, nbyte, 0, NULL, NULL); errno = EOPNOTSUPP; return -1; -#elif defined(__wasip3__) - filesystem_tuple2_stream_u8_future_result_void_error_code_t *stream; - off_t *off; - if (__wasilibc_read_stream3(fildes, &stream, &off)<0) - return -1; - wasip3_waitable_status_t status = - filesystem_stream_u8_read(stream->f0, buf, nbyte); - size_t amount = wasip3_waitable_block_on(status, stream->f0); - if (amount > 0 || nbyte == 0) { - if (off) - *off += amount; - return amount; - } else { - filesystem_result_void_error_code_t error; - status = filesystem_future_result_void_error_code_read(stream->f1, &error); - amount = wasip3_waitable_block_on(status, stream->f1); - if (amount > 0 && error.is_err) { - translate_error(error.val.err); - return -1; - } - // EOF - return 0; - } -#else -# error "Unsupported WASI version" #endif } diff --git a/libc-bottom-half/cloudlibc/src/libc/unistd/write.c b/libc-bottom-half/cloudlibc/src/libc/unistd/write.c index 8c2dead6d..ca191910b 100644 --- a/libc-bottom-half/cloudlibc/src/libc/unistd/write.c +++ b/libc-bottom-half/cloudlibc/src/libc/unistd/write.c @@ -28,12 +28,12 @@ ssize_t write(int fildes, const void *buf, size_t nbyte) { return -1; } return bytes_written; -#elif defined(__wasip2__) +#else descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes); if (!entry) return -1; if (entry->vtable->get_write_stream) { - wasip2_write_t write; + wasi_write_t write; if (entry->vtable->get_write_stream(entry->data, &write) < 0) return -1; return __wasilibc_write(&write, buf, nbyte); @@ -42,33 +42,5 @@ ssize_t write(int fildes, const void *buf, size_t nbyte) { return entry->vtable->sendto(entry->data, buf, nbyte, 0, NULL, 0); errno = EOPNOTSUPP; return -1; -#elif defined(__wasip3__) - wasip3_write_t *write_end; - off_t *off; - if (__wasilibc_write_stream3(fildes, &write_end, &off) < 0) - return -1; - if (WASIP3_SUBTASK_STATE(write_end->subtask) == WASIP3_SUBTASK_STARTING || - WASIP3_SUBTASK_STATE(write_end->subtask) == WASIP3_SUBTASK_STARTED) { - // the stream is still active - wasip3_waitable_status_t status = - filesystem_stream_u8_write(write_end->output, buf, nbyte); - size_t amount = wasip3_waitable_block_on(status, write_end->output); - if (amount > 0 || nbyte == 0) { - if (off) - *off += amount; - return amount; - } - // error or eof - wasip3_subtask_block_on(write_end->subtask); - write_end->subtask = WASIP3_SUBTASK_RETURNED; - } - if (write_end->pending_result.is_err) { - translate_error(write_end->pending_result.val.err); - return -1; - } - // EOF - return 0; -#else -# error "Unknown WASI version" #endif } diff --git a/libc-bottom-half/headers/private/wasi/descriptor_table.h b/libc-bottom-half/headers/private/wasi/descriptor_table.h index 254372fcd..e7841aeb5 100644 --- a/libc-bottom-half/headers/private/wasi/descriptor_table.h +++ b/libc-bottom-half/headers/private/wasi/descriptor_table.h @@ -8,48 +8,54 @@ #include #include -#ifdef __wasip2__ // Metadata for WASI reads which is used to delegate to `__wasilibc_read(...)` // to perform the actual read of a stream. -typedef struct wasip2_read_t { - // The `wasi:io/streams.input-stream` that this is reading from. - streams_borrow_input_stream_t input; +typedef struct wasi_read_t { // An optional pointer to the internal offset of this stream, updated on // successful reads. off_t *offset; - // A required pointer to an owned pollable for `input`. This is lazily - // initialized as-necessary. - poll_own_pollable_t *pollable; // Whether or not this read will use blocking I/O. bool blocking; // The timeout, in nanoseconds, for this operation. monotonic_clock_duration_t timeout; -} wasip2_read_t; +#ifdef __wasip2__ + // The `wasi:io/streams.input-stream` that this is reading from. + streams_borrow_input_stream_t input; + // A required pointer to an owned pollable for `input`. This is lazily + // initialized as-necessary. + poll_own_pollable_t *pollable; +#else + // The `stream` that's being read. + filesystem_stream_u8_t stream; + + // A callback/ptr pair to invoke when EOF is reached to set errno and return + // an error code. + int (*eof)(void*); + void *eof_data; +#endif +} wasi_read_t; -// Same as `wasip2_read_t`, but for writes. -typedef struct wasip2_write_t { - streams_borrow_output_stream_t output; +// Same as `wasip_read_t`, but for writes. +typedef struct wasi_write_t { off_t *offset; - poll_own_pollable_t *pollable; bool blocking; monotonic_clock_duration_t timeout; -} wasip2_write_t; -#endif - -#ifdef __wasip3__ -// create an alias to distinguish the handle type in the API -typedef uint32_t waitable_t; -/** - * This data structure represents the write end of a file - */ -typedef struct wasip3_write_t { +#ifdef __wasip2__ + streams_borrow_output_stream_t output; + poll_own_pollable_t *pollable; +#else filesystem_stream_u8_writer_t output; // contents will be filled by host (once write has an error) filesystem_result_void_error_code_t pending_result; // this task gets ready on error or eof - wasip3_subtask_t subtask; -} wasip3_write_t; + wasip3_subtask_t *subtask; +#endif +} wasi_write_t; + +#ifdef __wasip3__ +// create an alias to distinguish the handle type in the API +typedef uint32_t waitable_t; #endif /** @@ -71,18 +77,12 @@ typedef struct descriptor_vtable_t { // ===================================================================== // Generic I/O -#ifdef __wasip2__ /// Looks up metadata to perform a read operation for this stream. This is used /// to implement the `read` syscall, for example, and is also used with `poll` /// when waiting for readability. - int (*get_read_stream)(void*, wasip2_read_t*); + int (*get_read_stream)(void*, wasi_read_t*); /// Same as `get_read_stream`, but for output streams. - int (*get_write_stream)(void*, wasip2_write_t*); -#endif -#ifdef __wasip3__ - int (*get_read_stream3)(void*, filesystem_tuple2_stream_u8_future_result_void_error_code_t **out, off_t** off); - int (*get_write_stream3)(void*, wasip3_write_t **write_end, off_t**); -#endif + int (*get_write_stream)(void*, wasi_write_t*); /// Sets the nonblocking flag for this object to the specified value. int (*set_blocking)(void*, bool); diff --git a/libc-bottom-half/headers/private/wasi/file_utils.h b/libc-bottom-half/headers/private/wasi/file_utils.h index d929b83f2..11dc1e9eb 100644 --- a/libc-bottom-half/headers/private/wasi/file_utils.h +++ b/libc-bottom-half/headers/private/wasi/file_utils.h @@ -2,15 +2,14 @@ #define __wasi_file_utils_h #include - #if defined(__wasip2__) || defined(__wasip3__) + #include #include #include #include #include #include -#endif #ifdef __wasip2__ /// Handles a `wasi:io/streams.stream-error` for a `read`-style operation. @@ -50,7 +49,6 @@ static inline int wasip2_handle_write_error(streams_stream_error_t error) { int wasip2_string_from_c(const char *s, wasip2_string_t* out); #endif -#if defined(__wasip2__) || defined(__wasip3__) // Succeed only if fd is bound to a file handle in the descriptor table static inline int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* result) { descriptor_table_entry_t* entry = descriptor_table_get_ref(fd); @@ -62,25 +60,16 @@ static inline int fd_to_file_handle(int fd, filesystem_borrow_descriptor_t* resu } return entry->vtable->get_file(entry->data, result); } -#endif -#ifdef __wasip2__ // Reads from `read` into `buf`/`len` // // This perform the read configured by `read`, e.g. whether it's blocking or // not, and places the result in the specified buffer. Used to implement // `read` and `recvfrom`, for example. -ssize_t __wasilibc_read(wasip2_read_t *read, void *buf, size_t len); +ssize_t __wasilibc_read(wasi_read_t *read, void *buf, size_t len); // Same as `__wasilibc_read`, but for writes. -ssize_t __wasilibc_write(wasip2_write_t *write, const void *buf, size_t len); -#endif - -#ifdef __wasip3__ -int __wasilibc_write_stream3(int fildes, wasip3_write_t **write_end, off_t **off); -int __wasilibc_read_stream3(int fildes, filesystem_tuple2_stream_u8_future_result_void_error_code_t **stream, off_t **off); -#endif +ssize_t __wasilibc_write(wasi_write_t *write, const void *buf, size_t len); -#if defined(__wasip2__) || defined(__wasip3__) static inline unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty) { switch(ty) { case FILESYSTEM_DESCRIPTOR_TYPE_UNKNOWN: @@ -104,6 +93,6 @@ static inline unsigned dir_entry_type_to_d_type(filesystem_descriptor_type_t ty) } } -#endif +#endif // __wasip2__ || __wasip3__ -#endif +#endif // __wasi_file_utils_h diff --git a/libc-bottom-half/sources/wasip2_file_utils.c b/libc-bottom-half/sources/file_utils.c similarity index 83% rename from libc-bottom-half/sources/wasip2_file_utils.c rename to libc-bottom-half/sources/file_utils.c index abecd8263..9c2a50fbc 100644 --- a/libc-bottom-half/sources/wasip2_file_utils.c +++ b/libc-bottom-half/sources/file_utils.c @@ -4,9 +4,9 @@ #include #include #include +#include #ifdef __wasip2__ - /** * Validates that `ptr_signed` is a valid utf-8 string. * @@ -82,9 +82,11 @@ int wasip2_string_from_c(const char *s, wasip2_string_t *out) { out->len = len; return 0; } +#endif -ssize_t __wasilibc_write(wasip2_write_t *write, const void *buffer, +ssize_t __wasilibc_write(wasi_write_t *write, const void *buffer, size_t length) { +#if defined(__wasip2__) assert(write->output.__handle != 0); while (true) { streams_stream_error_t error; @@ -158,9 +160,36 @@ ssize_t __wasilibc_write(wasip2_write_t *write, const void *buffer, poll_method_pollable_block(pollable_borrow); } } +#elif defined(__wasip3__) + if (WASIP3_SUBTASK_STATE(*write->subtask) == WASIP3_SUBTASK_STARTING || + WASIP3_SUBTASK_STATE(*write->subtask) == WASIP3_SUBTASK_STARTED) { + // the stream is still active + wasip3_waitable_status_t status = + filesystem_stream_u8_write(write->output, buffer, length); + size_t amount = wasip3_waitable_block_on(status, write->output); + if (amount > 0 || length == 0) { + if (write->offset) + *write->offset += amount; + return amount; + } + // error or eof + wasip3_subtask_block_on(*write->subtask); + wasip3_subtask_drop(*write->subtask); + *write->subtask = WASIP3_SUBTASK_RETURNED; + } + if (write->pending_result.is_err) { + translate_error(write->pending_result.val.err); + return -1; + } + // EOF + return 0; +#else +#error "Unknown WASI version" +#endif } -ssize_t __wasilibc_read(wasip2_read_t *read, void *buffer, size_t length) { +ssize_t __wasilibc_read(wasi_read_t *read, void *buffer, size_t length) { +#if defined(__wasip2__) while (true) { wasip2_list_u8_t result; streams_stream_error_t error; @@ -223,6 +252,17 @@ ssize_t __wasilibc_read(wasip2_read_t *read, void *buffer, size_t length) { poll_method_pollable_block(pollable_borrow); } } +#elif defined(__wasip3__) + wasip3_waitable_status_t status = + filesystem_stream_u8_read(read->stream, buffer, length); + size_t amount = wasip3_waitable_block_on(status, read->stream); + if (amount > 0 || length == 0) { + if (read->offset) + *read->offset += amount; + return amount; + } + return read->eof(read->eof_data); +#else +#error "Unknown WASI version" +#endif } - -#endif // __wasip2__ diff --git a/libc-bottom-half/sources/tcp.c b/libc-bottom-half/sources/tcp.c index e32bf21e2..b9fe0be77 100644 --- a/libc-bottom-half/sources/tcp.c +++ b/libc-bottom-half/sources/tcp.c @@ -122,7 +122,7 @@ static void tcp_free(void *data) { } #ifdef __wasip2__ -static int tcp_get_read_stream(void *data, wasip2_read_t *read) { +static int tcp_get_read_stream(void *data, wasi_read_t *read) { tcp_socket_t *tcp = (tcp_socket_t *)data; if (tcp->state.tag != TCP_SOCKET_STATE_CONNECTED) { @@ -137,7 +137,7 @@ static int tcp_get_read_stream(void *data, wasip2_read_t *read) { return 0; } -static int tcp_get_write_stream(void *data, wasip2_write_t *write) { +static int tcp_get_write_stream(void *data, wasi_write_t *write) { tcp_socket_t *tcp = (tcp_socket_t *)data; if (tcp->state.tag != TCP_SOCKET_STATE_CONNECTED) { @@ -531,7 +531,7 @@ static ssize_t tcp_recvfrom(void *data, void *buffer, size_t length, int flags, return -1; } - wasip2_read_t read; + wasi_read_t read; if (tcp_get_read_stream(data, &read) < 0) return -1; @@ -555,7 +555,7 @@ static ssize_t tcp_sendto(void *data, const void *buffer, size_t length, return -1; } - wasip2_write_t write; + wasi_write_t write; if (tcp_get_write_stream(data, &write) < 0) return -1; diff --git a/libc-bottom-half/sources/wasip2_file.c b/libc-bottom-half/sources/wasip2_file.c index 116f6d4f3..7da5cb8a3 100644 --- a/libc-bottom-half/sources/wasip2_file.c +++ b/libc-bottom-half/sources/wasip2_file.c @@ -54,7 +54,7 @@ static void file_free(void *data) { free(file); } -static int file_get_read_stream(void *data, wasip2_read_t *read) { +static int file_get_read_stream(void *data, wasi_read_t *read) { file_t *file = (file_t *)data; if (file->read_stream.__handle == 0) { filesystem_error_code_t error_code; @@ -74,7 +74,7 @@ static int file_get_read_stream(void *data, wasip2_read_t *read) { return 0; } -static int file_get_write_stream(void *data, wasip2_write_t *write) { +static int file_get_write_stream(void *data, wasi_write_t *write) { file_t *file = (file_t *)data; if (file->write_stream.__handle == 0) { filesystem_error_code_t error_code; diff --git a/libc-bottom-half/sources/wasip2_stdio.c b/libc-bottom-half/sources/wasip2_stdio.c index c4681517d..47e9044c2 100644 --- a/libc-bottom-half/sources/wasip2_stdio.c +++ b/libc-bottom-half/sources/wasip2_stdio.c @@ -36,7 +36,7 @@ static void stdio_free(void *data) { free(stdio); } -static int stdio_get_read_stream(void *data, wasip2_read_t *read) { +static int stdio_get_read_stream(void *data, wasi_read_t *read) { stdio_t *stdio = (stdio_t *)data; if (stdio->fd != 0) { errno = EOPNOTSUPP; @@ -52,7 +52,7 @@ static int stdio_get_read_stream(void *data, wasip2_read_t *read) { return 0; } -static int stdio_get_write_stream(void *data, wasip2_write_t *write) { +static int stdio_get_write_stream(void *data, wasi_write_t *write) { stdio_t *stdio = (stdio_t *)data; if (stdio->output.__handle == 0) { if (stdio->fd == 1) { diff --git a/libc-bottom-half/sources/wasip3_file_utils.c b/libc-bottom-half/sources/wasip3_file_utils.c deleted file mode 100644 index e80b21ead..000000000 --- a/libc-bottom-half/sources/wasip3_file_utils.c +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#ifdef __wasip3__ -#include - -int __wasilibc_write_stream3(int fildes, wasip3_write_t **write_end, - off_t **off) { - descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes); - if (!entry) - return -1; - if (!entry->vtable->get_write_stream3) { - errno = EOPNOTSUPP; - return -1; - } - return (*entry->vtable->get_write_stream3)(entry->data, write_end, off); -} - -int __wasilibc_read_stream3( - int fildes, - filesystem_tuple2_stream_u8_future_result_void_error_code_t **stream, - off_t **off) { - descriptor_table_entry_t *entry = descriptor_table_get_ref(fildes); - if (!entry) - return -1; - if (!entry->vtable->get_read_stream3) { - errno = EOPNOTSUPP; - return -1; - } - return (*entry->vtable->get_read_stream3)(entry->data, stream, off); -} -#endif // __wasip3__ diff --git a/libc-bottom-half/sources/wasip3_stdio.c b/libc-bottom-half/sources/wasip3_stdio.c index 3f3091189..3104f2def 100644 --- a/libc-bottom-half/sources/wasip3_stdio.c +++ b/libc-bottom-half/sources/wasip3_stdio.c @@ -2,6 +2,7 @@ #include #ifdef __wasip3__ +#include #include #include #include @@ -20,7 +21,9 @@ typedef struct { typedef struct { // contains stream, result storage and result subtask - wasip3_write_t output; + wasip3_subtask_t subtask; + stdin_stream_u8_writer_t output; + stdin_result_void_error_code_t pending_result; // tristate: zero=unknown, valid handle=yes, -1=no terminal_output_own_terminal_output_t terminal_out; // stream creation function (delayed) @@ -45,38 +48,72 @@ static void stdout3_free(void *data) { stdout3_t *stdio = (stdout3_t *)data; if (stdio->terminal_out.__handle > 0) terminal_output_terminal_output_drop_own(stdio->terminal_out); - if (stdio->output.output) - stdin_stream_u8_drop_writable(stdio->output.output); - if (stdio->output.subtask) - wasip3_subtask_block_on(stdio->output.subtask); + if (stdio->output) + stdin_stream_u8_drop_writable(stdio->output); + if (stdio->subtask) + wasip3_subtask_block_on(stdio->subtask); free(stdio); } -static int stdout3_write(void *data, wasip3_write_t **out, off_t **offs) { +static int stdout3_write(void *data, wasi_write_t *out) { stdout3_t *stdio = (stdout3_t *)data; - if (!stdio->output.output) { - stdin_stream_u8_t read_side = stdin_stream_u8_new(&stdio->output.output); - stdio->output.subtask = (*stdio->stream_func)( - read_side, - (stdout_result_void_error_code_t *)&stdio->output.pending_result); + if (!stdio->output) { + assert(!stdio->subtask); + stdin_stream_u8_t read_side = stdin_stream_u8_new(&stdio->output); + stdio->subtask = (*stdio->stream_func)( + read_side, (stdout_result_void_error_code_t *)&stdio->pending_result); // subtask will be checked by write for error before writing } - *out = &stdio->output; - *offs = NULL; + out->offset = NULL; + out->blocking = true; + out->timeout = 0; + out->output = stdio->output; return 0; } -static int -stdin3_read(void *data, - filesystem_tuple2_stream_u8_future_result_void_error_code_t **out, - off_t **offs) { +static int stdin3_read_eof(void *data) { + stdin3_t *stdio = (stdin3_t *)data; + + stdin_result_void_error_code_t result; + wasip3_waitable_status_t status = + stdin_future_result_void_error_code_read(stdio->input.f1, &result); + size_t amt = wasip3_waitable_block_on(status, stdio->input.f1); + assert(amt == 1); + (void) amt; + stdin_future_result_void_error_code_drop_readable(stdio->input.f1); + stdio->input.f1 = 0; + if (result.is_err) { + switch (result.val.err) { + case WASI_CLI_TYPES_ERROR_CODE_IO: + errno = EIO; + break; + case WASI_CLI_TYPES_ERROR_CODE_ILLEGAL_BYTE_SEQUENCE: + errno = EILSEQ; + break; + case WASI_CLI_TYPES_ERROR_CODE_PIPE: + errno = EPIPE; + break; + default: + assert(0); + break; + } + return -1; + } + return 0; +} + +static int stdin3_read(void *data, wasi_read_t *read) { stdin3_t *stdio = (stdin3_t *)data; if (!stdio->input.f0) { + assert(!stdio->input.f1); stdin_read_via_stream(&stdio->input); } - *out = (filesystem_tuple2_stream_u8_future_result_void_error_code_t *)&stdio - ->input; - *offs = NULL; + read->stream = stdio->input.f0; + read->offset = NULL; + read->blocking = true; + read->timeout = 0; + read->eof_data = data; + read->eof = stdin3_read_eof; return 0; } @@ -116,7 +153,7 @@ static int stdout3_isatty(void *data) { static descriptor_vtable_t stdin3_vtable = { .free = stdin3_free, - .get_read_stream3 = stdin3_read, + .get_read_stream = stdin3_read, .fstat = stdio3_fstat, .fcntl_getfl = stdin3_fcntl_getfl, .isatty = stdin3_isatty, @@ -124,7 +161,7 @@ static descriptor_vtable_t stdin3_vtable = { static descriptor_vtable_t stdout3_vtable = { .free = stdout3_free, - .get_write_stream3 = stdout3_write, + .get_write_stream = stdout3_write, .fstat = stdio3_fstat, .fcntl_getfl = stdout3_fcntl_getfl, .isatty = stdout3_isatty,