From 7e93903439c79e4674763348b64d5f5b08a9e8b5 Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Wed, 27 Sep 2023 18:51:03 +0000 Subject: [PATCH 1/2] deps: update uvwasi to 0.0.19 --- deps/uvwasi/include/uvwasi.h | 11 +- deps/uvwasi/src/fd_table.c | 69 +++- deps/uvwasi/src/fd_table.h | 5 + deps/uvwasi/src/sync_helpers.c | 95 ++++++ deps/uvwasi/src/sync_helpers.h | 27 ++ deps/uvwasi/src/uvwasi.c | 320 ++++++++++++++++-- deps/uvwasi/src/wasi_rights.h | 5 +- .../maintaining/maintaining-dependencies.md | 6 +- 8 files changed, 491 insertions(+), 47 deletions(-) create mode 100644 deps/uvwasi/src/sync_helpers.c create mode 100644 deps/uvwasi/src/sync_helpers.h diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h index d475d3e67512bf..a458cfe17daaa3 100644 --- a/deps/uvwasi/include/uvwasi.h +++ b/deps/uvwasi/include/uvwasi.h @@ -5,12 +5,13 @@ extern "C" { #endif +#include "uv.h" #include "wasi_serdes.h" #include "wasi_types.h" #define UVWASI_VERSION_MAJOR 0 #define UVWASI_VERSION_MINOR 0 -#define UVWASI_VERSION_PATCH 18 +#define UVWASI_VERSION_PATCH 19 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \ (UVWASI_VERSION_MINOR << 8) | \ (UVWASI_VERSION_PATCH)) @@ -47,6 +48,7 @@ typedef struct uvwasi_s { char* env_buf; uvwasi_size_t env_buf_size; const uvwasi_mem_t* allocator; + uv_loop_t* loop; } uvwasi_t; typedef struct uvwasi_preopen_s { @@ -54,10 +56,17 @@ typedef struct uvwasi_preopen_s { const char* real_path; } uvwasi_preopen_t; +typedef struct uvwasi_preopen_socket_s { + const char* address; + int port; +} uvwasi_preopen_socket_t; + typedef struct uvwasi_options_s { uvwasi_size_t fd_table_size; uvwasi_size_t preopenc; uvwasi_preopen_t* preopens; + uvwasi_size_t preopen_socketc; + uvwasi_preopen_socket_t* preopen_sockets; uvwasi_size_t argc; const char** argv; const char** envp; diff --git a/deps/uvwasi/src/fd_table.c b/deps/uvwasi/src/fd_table.c index 7782f1ee43b420..881d192ff3a340 100644 --- a/deps/uvwasi/src/fd_table.c +++ b/deps/uvwasi/src/fd_table.c @@ -37,6 +37,7 @@ static uvwasi_errno_t uvwasi__insert_stdio(uvwasi_t* uvwasi, err = uvwasi_fd_table_insert(uvwasi, table, fd, + NULL, name, name, type, @@ -58,6 +59,7 @@ static uvwasi_errno_t uvwasi__insert_stdio(uvwasi_t* uvwasi, uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table, uv_file fd, + uv_tcp_t* sock, const char* mapped_path, const char* real_path, uvwasi_filetype_t type, @@ -78,29 +80,40 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, char* rp_copy; char* np_copy; - mp_len = strlen(mapped_path); - rp_len = strlen(real_path); + if (type != UVWASI_FILETYPE_SOCKET_STREAM) { + mp_len = strlen(mapped_path); + rp_len = strlen(real_path); + } else { + mp_len = 0; + rp_len = 0; + rp_copy = NULL; + mp_copy = NULL; + np_copy = NULL; + } + /* Reserve room for the mapped path, real path, and normalized mapped path. */ entry = (struct uvwasi_fd_wrap_t*) uvwasi__malloc(uvwasi, sizeof(*entry) + mp_len + mp_len + rp_len + 3); if (entry == NULL) return UVWASI_ENOMEM; - mp_copy = (char*)(entry + 1); - rp_copy = mp_copy + mp_len + 1; - np_copy = rp_copy + rp_len + 1; - memcpy(mp_copy, mapped_path, mp_len); - mp_copy[mp_len] = '\0'; - memcpy(rp_copy, real_path, rp_len); - rp_copy[rp_len] = '\0'; - - /* Calculate the normalized version of the mapped path, as it will be used for - any path calculations on this fd. Use the length of the mapped path as an - upper bound for the normalized path length. */ - err = uvwasi__normalize_path(mp_copy, mp_len, np_copy, mp_len); - if (err) { - uvwasi__free(uvwasi, entry); - goto exit; + if (type != UVWASI_FILETYPE_SOCKET_STREAM) { + mp_copy = (char*)(entry + 1); + rp_copy = mp_copy + mp_len + 1; + np_copy = rp_copy + rp_len + 1; + memcpy(mp_copy, mapped_path, mp_len); + mp_copy[mp_len] = '\0'; + memcpy(rp_copy, real_path, rp_len); + rp_copy[rp_len] = '\0'; + + /* Calculate the normalized version of the mapped path, as it will be used for + any path calculations on this fd. Use the length of the mapped path as an + upper bound for the normalized path length. */ + err = uvwasi__normalize_path(mp_copy, mp_len, np_copy, mp_len); + if (err) { + uvwasi__free(uvwasi, entry); + goto exit; + } } uv_rwlock_wrlock(&table->rwlock); @@ -150,6 +163,7 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, entry->id = index; entry->fd = fd; + entry->sock = sock; entry->path = mp_copy; entry->real_path = rp_copy; entry->normalized_path = np_copy; @@ -280,6 +294,7 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(uvwasi_t* uvwasi, return uvwasi_fd_table_insert(uvwasi, table, fd, + NULL, path, real_path, UVWASI_FILETYPE_DIRECTORY, @@ -290,6 +305,26 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(uvwasi_t* uvwasi, } +uvwasi_errno_t uvwasi_fd_table_insert_preopen_socket(uvwasi_t* uvwasi, + struct uvwasi_fd_table_t* table, + uv_tcp_t* sock) { + if (table == NULL || sock == NULL) + return UVWASI_EINVAL; + + return uvwasi_fd_table_insert(uvwasi, + table, + -1, + sock, + NULL, + NULL, + UVWASI_FILETYPE_SOCKET_STREAM, + UVWASI__RIGHTS_SOCKET_BASE, + UVWASI__RIGHTS_SOCKET_INHERITING, + 1, + NULL); +} + + uvwasi_errno_t uvwasi_fd_table_get(struct uvwasi_fd_table_t* table, const uvwasi_fd_t id, struct uvwasi_fd_wrap_t** wrap, diff --git a/deps/uvwasi/src/fd_table.h b/deps/uvwasi/src/fd_table.h index 0755c2d17fdec2..9a7a825bc85d4c 100644 --- a/deps/uvwasi/src/fd_table.h +++ b/deps/uvwasi/src/fd_table.h @@ -11,6 +11,7 @@ struct uvwasi_options_s; struct uvwasi_fd_wrap_t { uvwasi_fd_t id; uv_file fd; + uv_tcp_t* sock; char* path; char* real_path; char* normalized_path; @@ -35,6 +36,7 @@ void uvwasi_fd_table_free(struct uvwasi_s* uvwasi, uvwasi_errno_t uvwasi_fd_table_insert(struct uvwasi_s* uvwasi, struct uvwasi_fd_table_t* table, uv_file fd, + uv_tcp_t* sock, const char* mapped_path, const char* real_path, uvwasi_filetype_t type, @@ -47,6 +49,9 @@ uvwasi_errno_t uvwasi_fd_table_insert_preopen(struct uvwasi_s* uvwasi, const uv_file fd, const char* path, const char* real_path); +uvwasi_errno_t uvwasi_fd_table_insert_preopen_socket(struct uvwasi_s* uvwasi, + struct uvwasi_fd_table_t* table, + uv_tcp_t* sock); uvwasi_errno_t uvwasi_fd_table_get(struct uvwasi_fd_table_t* table, const uvwasi_fd_t id, struct uvwasi_fd_wrap_t** wrap, diff --git a/deps/uvwasi/src/sync_helpers.c b/deps/uvwasi/src/sync_helpers.c new file mode 100644 index 00000000000000..c63a62b83d75ed --- /dev/null +++ b/deps/uvwasi/src/sync_helpers.c @@ -0,0 +1,95 @@ +#include "uv.h" +#include "sync_helpers.h" +#include "uv_mapping.h" +#include "uvwasi_alloc.h" + +typedef struct free_handle_data_s { + uvwasi_t* uvwasi; + int done; +} free_handle_data_t; + +static void free_handle_cb(uv_handle_t* handle) { + free_handle_data_t* free_handle_data = uv_handle_get_data((uv_handle_t*) handle); + uvwasi__free(free_handle_data->uvwasi, handle); + free_handle_data->done = 1; +} + +int free_handle_sync(struct uvwasi_s* uvwasi, uv_handle_t* handle) { + free_handle_data_t free_handle_data = { uvwasi, 0 }; + uv_handle_set_data(handle, (void*) &free_handle_data); + uv_close(handle, free_handle_cb); + uv_loop_t* handle_loop = uv_handle_get_loop(handle); + while(!free_handle_data.done) { + if (uv_run(handle_loop, UV_RUN_ONCE) == 0) { + break; + } + } + return UVWASI_ESUCCESS; +} + +static void do_stream_shutdown(uv_shutdown_t* req, int status) { + shutdown_data_t* shutdown_data; + shutdown_data = uv_handle_get_data((uv_handle_t*) req->handle); + shutdown_data->status = status; + shutdown_data->done = 1; + } + +int shutdown_stream_sync(struct uvwasi_s* uvwasi, + uv_stream_t* stream, + shutdown_data_t* shutdown_data) { + uv_shutdown_t req; + uv_loop_t* stream_loop; + + shutdown_data->done = 0; + shutdown_data->status = 0; + stream_loop = uv_handle_get_loop((uv_handle_t*) stream); + + uv_handle_set_data((uv_handle_t*) stream, (void*) shutdown_data); + uv_shutdown(&req, stream, do_stream_shutdown); + while (!shutdown_data->done) { + if (uv_run(stream_loop, UV_RUN_ONCE) == 0) { + return UVWASI_ECANCELED; + } + } + return UVWASI_ESUCCESS; +} + +static void recv_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { + recv_data_t* recv_data; + recv_data = uv_handle_get_data(handle); + buf->base = recv_data->base; + buf->len = recv_data->len; +} + +void do_stream_recv(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + recv_data_t* recv_data; + recv_data = uv_handle_get_data((uv_handle_t*) stream); + uv_read_stop(stream); + recv_data->nread = nread; + recv_data->done = 1; +} + +int read_stream_sync(struct uvwasi_s* uvwasi, + uv_stream_t* stream, + recv_data_t* recv_data) { + uv_loop_t* recv_loop; + int r; + + recv_data->nread = 0; + recv_data->done = 0; + recv_loop = uv_handle_get_loop((uv_handle_t*) stream); + + uv_handle_set_data((uv_handle_t*) stream, (void*) recv_data); + r = uv_read_start(stream, recv_alloc_cb, do_stream_recv); + if (r != 0) { + return uvwasi__translate_uv_error(r); + } + + while (!recv_data->done) { + if (uv_run(recv_loop, UV_RUN_ONCE) == 0) { + return UVWASI_ECANCELED; + } + } + + return UVWASI_ESUCCESS; +} diff --git a/deps/uvwasi/src/sync_helpers.h b/deps/uvwasi/src/sync_helpers.h new file mode 100644 index 00000000000000..6ffe2cac133d6c --- /dev/null +++ b/deps/uvwasi/src/sync_helpers.h @@ -0,0 +1,27 @@ +#ifndef __UVWASI_SYNC_HELPERS_H__ +#define __UVWASI_SYNC_HELPERS_H__ + +struct uvwasi_s; + +typedef struct shutdown_data_s { + int status; + int done; +} shutdown_data_t; + +typedef struct recv_data_s { + char* base; + size_t len; + ssize_t nread; + int done; +} recv_data_t; + +int free_handle_sync(struct uvwasi_s* uvwasi, uv_handle_t* handle); + +int shutdown_stream_sync(struct uvwasi_s* uvwasi, + uv_stream_t* stream, + shutdown_data_t* shutdown_data); + +int read_stream_sync(struct uvwasi_s* uvwasi, + uv_stream_t* stream, + recv_data_t* recv_data); +#endif /* __UVWASI_SYNC_HELPERS_H__ */ diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c index 9e7fc7681664b8..e904b9f9293864 100644 --- a/deps/uvwasi/src/uvwasi.c +++ b/deps/uvwasi/src/uvwasi.c @@ -25,6 +25,7 @@ #include "clocks.h" #include "path_resolver.h" #include "poll_oneoff.h" +#include "sync_helpers.h" #include "wasi_rights.h" #include "wasi_serdes.h" #include "debug.h" @@ -231,6 +232,13 @@ static uvwasi_errno_t uvwasi__setup_ciovs(const uvwasi_t* uvwasi, return UVWASI_ESUCCESS; } +typedef struct new_connection_data_s { + int done; +} new_connection_data_t; + +void on_new_connection(uv_stream_t *server, int status) { + // just do nothing +} uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options) { uv_fs_t realpath_req; @@ -243,11 +251,16 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options) { uvwasi_size_t env_buf_size; uvwasi_size_t i; int r; + struct sockaddr_in addr; if (uvwasi == NULL || options == NULL || options->fd_table_size == 0) return UVWASI_EINVAL; + // loop is only needed if there were pre-open sockets + uvwasi->loop = NULL; + uvwasi->allocator = options->allocator; + if (uvwasi->allocator == NULL) uvwasi->allocator = &default_allocator; @@ -328,6 +341,14 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options) { } } + for (i = 0; i < options->preopen_socketc; ++i) { + if (options->preopen_sockets[i].address == NULL || + options->preopen_sockets[i].port > 65535) { + err = UVWASI_EINVAL; + goto exit; + } + } + err = uvwasi_fd_table_init(uvwasi, options); if (err != UVWASI_ESUCCESS) goto exit; @@ -363,6 +384,36 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, const uvwasi_options_t* options) { goto exit; } + if (options->preopen_socketc > 0) { + uvwasi->loop = uvwasi__malloc(uvwasi, sizeof(uv_loop_t)); + r = uv_loop_init(uvwasi->loop); + if (r != 0) { + err = uvwasi__translate_uv_error(r); + goto exit; + } + } + + for (i = 0; i < options->preopen_socketc; ++i) { + uv_tcp_t* socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(uvwasi->loop, socket); + + uv_ip4_addr(options->preopen_sockets[i].address, options->preopen_sockets[i].port, &addr); + + uv_tcp_bind(socket, (const struct sockaddr*)&addr, 0); + r = uv_listen((uv_stream_t*) socket, 128, on_new_connection); + if (r != 0) { + err = uvwasi__translate_uv_error(r); + goto exit; + } + + err = uvwasi_fd_table_insert_preopen_socket(uvwasi, + uvwasi->fds, + socket); + + if (err != UVWASI_ESUCCESS) + goto exit; + } + return UVWASI_ESUCCESS; exit: @@ -380,6 +431,12 @@ void uvwasi_destroy(uvwasi_t* uvwasi) { uvwasi__free(uvwasi, uvwasi->argv); uvwasi__free(uvwasi, uvwasi->env_buf); uvwasi__free(uvwasi, uvwasi->env); + if (uvwasi->loop != NULL) { + uv_stop(uvwasi->loop); + uv_loop_close(uvwasi->loop); + uvwasi__free(uvwasi, uvwasi->loop); + uvwasi->loop = NULL; + } uvwasi->fds = NULL; uvwasi->argv_buf = NULL; uvwasi->argv = NULL; @@ -401,6 +458,8 @@ void uvwasi_options_init(uvwasi_options_t* options) { options->envp = NULL; options->preopenc = 0; options->preopens = NULL; + options->preopen_socketc = 0; + options->preopen_sockets = NULL; options->allocator = NULL; } @@ -694,10 +753,9 @@ uvwasi_errno_t uvwasi_fd_allocate(uvwasi_t* uvwasi, return err; } - uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) { struct uvwasi_fd_wrap_t* wrap; - uvwasi_errno_t err; + uvwasi_errno_t err = 0; uv_fs_t req; int r; @@ -712,9 +770,18 @@ uvwasi_errno_t uvwasi_fd_close(uvwasi_t* uvwasi, uvwasi_fd_t fd) { if (err != UVWASI_ESUCCESS) goto exit; - r = uv_fs_close(NULL, &req, wrap->fd, NULL); - uv_mutex_unlock(&wrap->mutex); - uv_fs_req_cleanup(&req); + if (wrap->sock == NULL) { + r = uv_fs_close(NULL, &req, wrap->fd, NULL); + uv_mutex_unlock(&wrap->mutex); + uv_fs_req_cleanup(&req); + } else { + r = 0; + err = free_handle_sync(uvwasi, (uv_handle_t*) wrap->sock); + uv_mutex_unlock(&wrap->mutex); + if (err != UVWASI_ESUCCESS) { + goto exit; + } + } if (r != 0) { err = uvwasi__translate_uv_error(r); @@ -1997,6 +2064,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi, err = uvwasi_fd_table_insert(uvwasi, uvwasi->fds, r, + NULL, resolved_path, resolved_path, filetype, @@ -2520,7 +2588,6 @@ uvwasi_errno_t uvwasi_sched_yield(uvwasi_t* uvwasi) { return UVWASI_ESUCCESS; } - uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi, uvwasi_fd_t sock, const uvwasi_iovec_t* ri_data, @@ -2528,10 +2595,50 @@ uvwasi_errno_t uvwasi_sock_recv(uvwasi_t* uvwasi, uvwasi_riflags_t ri_flags, uvwasi_size_t* ro_datalen, uvwasi_roflags_t* ro_flags) { - /* TODO(cjihrig): Waiting to implement, pending - https://github.com/WebAssembly/WASI/issues/4 */ - UVWASI_DEBUG("uvwasi_sock_recv(uvwasi=%p, unimplemented)\n", uvwasi); - return UVWASI_ENOTSUP; + struct uvwasi_fd_wrap_t* wrap; + uvwasi_errno_t err = 0; + recv_data_t recv_data; + + UVWASI_DEBUG("uvwasi_sock_recv(uvwasi=%p, sock=%d, ri_data=%p, " + "ri_data_len=%d, ri_flags=%d, ro_datalen=%p, ro_flags=%p)\n", + uvwasi, + sock, + ri_data, + ri_data_len, + ri_flags, + ro_datalen, + ro_flags); + + if (uvwasi == NULL || ri_data == NULL || ro_datalen == NULL || ro_flags == NULL) + return UVWASI_EINVAL; + + if (ri_flags != 0) + return UVWASI_ENOTSUP; + + err = uvwasi_fd_table_get(uvwasi->fds, + sock, + &wrap, + UVWASI__RIGHTS_SOCKET_BASE, + 0); + if (err != UVWASI_ESUCCESS) + return err; + + recv_data.base = ri_data->buf; + recv_data.len = ri_data->buf_len; + err = read_stream_sync(uvwasi, (uv_stream_t*) wrap->sock, &recv_data); + uv_mutex_unlock(&wrap->mutex); + if (err != 0) { + return err; + } + + if (recv_data.nread == 0) { + return UVWASI_EAGAIN; + } else if (recv_data.nread < 0) { + return uvwasi__translate_uv_error(recv_data.nread); + } + + *ro_datalen = recv_data.nread; + return UVWASI_ESUCCESS; } @@ -2541,30 +2648,195 @@ uvwasi_errno_t uvwasi_sock_send(uvwasi_t* uvwasi, uvwasi_size_t si_data_len, uvwasi_siflags_t si_flags, uvwasi_size_t* so_datalen) { - /* TODO(cjihrig): Waiting to implement, pending - https://github.com/WebAssembly/WASI/issues/4 */ - UVWASI_DEBUG("uvwasi_sock_send(uvwasi=%p, unimplemented)\n", uvwasi); - return UVWASI_ENOTSUP; -} + struct uvwasi_fd_wrap_t* wrap; + uvwasi_errno_t err = 0; + uv_buf_t* bufs; + int r = 0; + + UVWASI_DEBUG("uvwasi_sock_send(uvwasi=%p, sock=%d, si_data=%p, " + "si_data_len=%d, si_flags=%d, so_datalen=%p)\n", + uvwasi, + sock, + si_data, + si_data_len, + si_flags, + so_datalen); + + if (uvwasi == NULL || si_data == NULL || so_datalen == NULL || + si_flags != 0) + return UVWASI_EINVAL; + + err = uvwasi_fd_table_get(uvwasi->fds, + sock, + &wrap, + UVWASI__RIGHTS_SOCKET_BASE, + 0); + if (err != UVWASI_ESUCCESS) + return err; + + err = uvwasi__setup_ciovs(uvwasi, &bufs, si_data, si_data_len); + if (err != UVWASI_ESUCCESS) { + uv_mutex_unlock(&wrap->mutex); + return err; + } + + r = uv_try_write((uv_stream_t*) wrap->sock, bufs, si_data_len); + uvwasi__free(uvwasi, bufs); + uv_mutex_unlock(&wrap->mutex); + if (r < 0) + return uvwasi__translate_uv_error(r); + + *so_datalen = (uvwasi_size_t) r; + return UVWASI_ESUCCESS; +} uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi, uvwasi_fd_t sock, uvwasi_sdflags_t how) { - /* TODO(cjihrig): Waiting to implement, pending - https://github.com/WebAssembly/WASI/issues/4 */ - UVWASI_DEBUG("uvwasi_sock_shutdown(uvwasi=%p, unimplemented)\n", uvwasi); - return UVWASI_ENOTSUP; + struct uvwasi_fd_wrap_t* wrap; + uvwasi_errno_t err = 0; + shutdown_data_t shutdown_data; + + if (how & ~UVWASI_SHUT_WR) + return UVWASI_ENOTSUP; + + UVWASI_DEBUG("uvwasi_sock_shutdown(uvwasi=%p, sock=%d, how=%d)\n", + uvwasi, + sock, + how); + + if (uvwasi == NULL) + return UVWASI_EINVAL; + + err = uvwasi_fd_table_get(uvwasi->fds, + sock, + &wrap, + UVWASI__RIGHTS_SOCKET_BASE, + 0); + if (err != UVWASI_ESUCCESS) + return err; + + if (how & UVWASI_SHUT_WR) { + err = shutdown_stream_sync(uvwasi, (uv_stream_t*) wrap->sock, &shutdown_data); + if (err != UVWASI_ESUCCESS) { + uv_mutex_unlock(&wrap->mutex); + return err; + } + } + + uv_mutex_unlock(&wrap->mutex); + + if (shutdown_data.status != 0) + return uvwasi__translate_uv_error(shutdown_data.status); + + return UVWASI_ESUCCESS; } uvwasi_errno_t uvwasi_sock_accept(uvwasi_t* uvwasi, uvwasi_fd_t sock, uvwasi_fdflags_t flags, - uvwasi_fd_t* fd) { - /* TODO(mhdawson): Needs implementation */ - UVWASI_DEBUG("uvwasi_sock_accept(uvwasi=%p, unimplemented)\n", uvwasi); - return UVWASI_ENOTSUP; -}; + uvwasi_fd_t* connect_sock) { + struct uvwasi_fd_wrap_t* wrap; + struct uvwasi_fd_wrap_t* connected_wrap; + uvwasi_errno_t err = 0; + uv_loop_t* sock_loop = NULL; + int r = 0; + + UVWASI_DEBUG("uvwasi_sock_accept(uvwasi=%p, sock=%d, flags=%d, " + "connect_sock=%p)\n", + uvwasi, + sock, + flags, + connect_sock); + + if (uvwasi == NULL || connect_sock == NULL) + return UVWASI_EINVAL; + + if (flags & ~UVWASI_FDFLAG_NONBLOCK) + return UVWASI_ENOTSUP; + + err = uvwasi_fd_table_get(uvwasi->fds, + sock, + &wrap, + UVWASI__RIGHTS_SOCKET_BASE, + 0); + if (err != UVWASI_ESUCCESS) + return err; + + sock_loop = uv_handle_get_loop((uv_handle_t*) wrap->sock); + uv_tcp_t* uv_connect_sock = (uv_tcp_t*) uvwasi__malloc(uvwasi, sizeof(uv_tcp_t)); + uv_tcp_init(sock_loop, uv_connect_sock); + + r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); + if (r != 0) { + if (r == UV_EAGAIN) { + // if not blocking then just return as we have to wait for a connection + if (flags & UVWASI_FDFLAG_NONBLOCK) { + err = free_handle_sync(uvwasi, (uv_handle_t*) uv_connect_sock); + uv_mutex_unlock(&wrap->mutex); + if (err != UVWASI_ESUCCESS) { + return err; + } + return UVWASI_EAGAIN; + } + } else { + err = uvwasi__translate_uv_error(r); + goto close_sock_and_error_exit; + } + + // request was blocking and we have no connection yet. run + // the loop until a connection comes in + while (1) { + err = 0; + if (uv_run(sock_loop, UV_RUN_ONCE) == 0) { + err = UVWASI_ECONNABORTED; + goto close_sock_and_error_exit; + } + + int r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); + if (r == UV_EAGAIN) { + // still no connection or error so run the loop again + continue; + } + + if (r != 0) { + // An error occurred accepting the connection. Break out of the loop and + // report an error. + err = uvwasi__translate_uv_error(r); + goto close_sock_and_error_exit; + } + + // if we get here a new connection was successfully accepted + break; + } + } + + err = uvwasi_fd_table_insert(uvwasi, + uvwasi->fds, + -1, + uv_connect_sock, + NULL, + NULL, + UVWASI_FILETYPE_SOCKET_STREAM, + UVWASI__RIGHTS_SOCKET_BASE, + UVWASI__RIGHTS_SOCKET_INHERITING, + 1, + &connected_wrap); + + if (err != UVWASI_ESUCCESS) + goto close_sock_and_error_exit; + + *connect_sock = connected_wrap->id; + uv_mutex_unlock(&wrap->mutex); + uv_mutex_unlock(&connected_wrap->mutex); + return UVWASI_ESUCCESS; + +close_sock_and_error_exit: + uvwasi__free(uvwasi, uv_connect_sock); + uv_mutex_unlock(&wrap->mutex); + return err; +} const char* uvwasi_embedder_err_code_to_string(uvwasi_errno_t code) { diff --git a/deps/uvwasi/src/wasi_rights.h b/deps/uvwasi/src/wasi_rights.h index 09009b39889cc0..54ac7d7072b7fe 100644 --- a/deps/uvwasi/src/wasi_rights.h +++ b/deps/uvwasi/src/wasi_rights.h @@ -84,8 +84,9 @@ UVWASI_RIGHT_FD_WRITE | \ UVWASI_RIGHT_FD_FILESTAT_GET | \ UVWASI_RIGHT_POLL_FD_READWRITE | \ - UVWASI_RIGHT_SOCK_SHUTDOWN) -#define UVWASI__RIGHTS_SOCKET_INHERITING UVWASI__RIGHTS_ALL; + UVWASI_RIGHT_SOCK_SHUTDOWN | \ + UVWASI_RIGHT_SOCK_ACCEPT) +#define UVWASI__RIGHTS_SOCKET_INHERITING UVWASI__RIGHTS_ALL #define UVWASI__RIGHTS_TTY_BASE (UVWASI_RIGHT_FD_READ | \ UVWASI_RIGHT_FD_FDSTAT_SET_FLAGS | \ diff --git a/doc/contributing/maintaining/maintaining-dependencies.md b/doc/contributing/maintaining/maintaining-dependencies.md index 6271f05ce36326..80827fe9eaadbd 100644 --- a/doc/contributing/maintaining/maintaining-dependencies.md +++ b/doc/contributing/maintaining/maintaining-dependencies.md @@ -29,7 +29,7 @@ This a list of all the dependencies: * [postject 1.0.0-alpha.6][] * [simdutf 3.2.17][] * [undici 5.25.2][] -* [uvwasi 0.0.16][] +* [uvwasi 0.0.19][] * [V8 11.3.244.8][] * [zlib 1.2.13.1-motley-f5fd0ad][] @@ -297,7 +297,7 @@ The [undici](https://github.com/nodejs/undici) dependency is an HTTP/1.1 client, written from scratch for Node.js.. See [maintaining-http][] for more informations. -### uvwasi 0.0.16 +### uvwasi 0.0.19 The [uvwasi](https://github.com/nodejs/uvwasi) dependency implements the WASI system call API, so that WebAssembly runtimes can easily @@ -347,6 +347,6 @@ performance improvements not currently available in standard zlib. [simdutf 3.2.17]: #simdutf-3217 [undici 5.25.2]: #undici-5252 [update-openssl-action]: ../../../.github/workflows/update-openssl.yml -[uvwasi 0.0.16]: #uvwasi-0016 +[uvwasi 0.0.19]: #uvwasi-0019 [v8 11.3.244.8]: #v8-1132448 [zlib 1.2.13.1-motley-f5fd0ad]: #zlib-12131-motley-f5fd0ad From 23eae88eef98f66ee733d3a99da4d7a1a034bb20 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Wed, 27 Sep 2023 20:06:12 +0000 Subject: [PATCH 2/2] wasi: updates required for latest uvwasi version Signed-off-by: Michael Dawson --- deps/uvwasi/uvwasi.gyp | 1 + test/wasi/c/sock.c | 4 ++-- test/wasi/wasm/sock.wasm | Bin 18999 -> 19026 bytes 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/deps/uvwasi/uvwasi.gyp b/deps/uvwasi/uvwasi.gyp index 229dc9f41f8de8..4dfe3c46d51818 100644 --- a/deps/uvwasi/uvwasi.gyp +++ b/deps/uvwasi/uvwasi.gyp @@ -5,6 +5,7 @@ 'src/fd_table.c', 'src/path_resolver.c', 'src/poll_oneoff.c', + 'src/sync_helpers.c', 'src/uv_mapping.c', 'src/uvwasi.c', 'src/wasi_rights.c', diff --git a/test/wasi/c/sock.c b/test/wasi/c/sock.c index de4a3ccc5f95a6..d11e86c805784d 100644 --- a/test/wasi/c/sock.c +++ b/test/wasi/c/sock.c @@ -9,9 +9,9 @@ int main(void) { int fd = 0 ; socklen_t addrlen = 0; int flags = 0; - int ret = accept(0, NULL, &addrlen); + int ret = accept(10, NULL, &addrlen); assert(ret == -1); - assert(errno == ENOTSUP); + assert(errno == EBADF); return 0; } diff --git a/test/wasi/wasm/sock.wasm b/test/wasi/wasm/sock.wasm index 78e7b8e430f91141c4d2305da27a6dbc367f5437..9fdba111a23ca2298b62a449a5f8bce92fcc1f80 100755 GIT binary patch delta 2181 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