Skip to content

Commit

Permalink
feat: start adding socket tests (#214)
Browse files Browse the repository at this point in the history
* feat: add tests and complete sock function implementation

Signed-off-by: Michael Dawson <[email protected]>
  • Loading branch information
mhdawson authored Jul 28, 2023
1 parent c8d36d4 commit 0ffea5a
Show file tree
Hide file tree
Showing 31 changed files with 856 additions and 110 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ set(uvwasi_sources
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
Expand Down
2 changes: 2 additions & 0 deletions include/uvwasi.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
extern "C" {
#endif

#include "uv.h"
#include "wasi_serdes.h"
#include "wasi_types.h"

Expand Down Expand Up @@ -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 {
Expand Down
45 changes: 28 additions & 17 deletions src/fd_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,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);
Expand Down
95 changes: 95 additions & 0 deletions src/sync_helpers.c
Original file line number Diff line number Diff line change
@@ -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;
}
27 changes: 27 additions & 0 deletions src/sync_helpers.h
Original file line number Diff line number Diff line change
@@ -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__ */
Loading

0 comments on commit 0ffea5a

Please sign in to comment.