From cab34ec70691af61681519bccbe61106d9f62db0 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 13 Mar 2020 16:26:28 -0400 Subject: [PATCH 1/4] simplify uvwasi_fd_table_init() signature Simplify the signature of uvwasi_fd_table_init() to make it easier to configure stdio. --- include/fd_table.h | 4 ++-- src/fd_table.c | 11 ++++++----- src/uvwasi.c | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/include/fd_table.h b/include/fd_table.h index fa8a44e..f29b1ad 100644 --- a/include/fd_table.h +++ b/include/fd_table.h @@ -6,6 +6,7 @@ #include "wasi_types.h" struct uvwasi_s; +struct uvwasi_options_s; struct uvwasi_fd_wrap_t { uvwasi_fd_t id; @@ -27,8 +28,7 @@ struct uvwasi_fd_table_t { }; uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_s* uvwasi, - struct uvwasi_fd_table_t* table, - uint32_t init_size); + struct uvwasi_options_s* options); void uvwasi_fd_table_free(struct uvwasi_s* uvwasi, struct uvwasi_fd_table_t* table); uvwasi_errno_t uvwasi_fd_table_insert(struct uvwasi_s* uvwasi, diff --git a/src/fd_table.c b/src/fd_table.c index f77858a..e2bb879 100644 --- a/src/fd_table.c +++ b/src/fd_table.c @@ -117,8 +117,8 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, - struct uvwasi_fd_table_t* table, - uint32_t init_size) { + uvwasi_options_t* options) { + struct uvwasi_fd_table_t* table; struct uvwasi_fd_wrap_t* wrap; uvwasi_filetype_t type; uvwasi_rights_t base; @@ -128,14 +128,15 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, int r; /* Require an initial size of at least three to store the stdio FDs. */ - if (table == NULL || init_size < 3) + if (uvwasi == NULL || options == NULL || options->fd_table_size < 3) return UVWASI_EINVAL; + table = &uvwasi->fds; table->fds = NULL; table->used = 0; - table->size = init_size; + table->size = options->fd_table_size; table->fds = uvwasi__calloc(uvwasi, - init_size, + options->fd_table_size, sizeof(struct uvwasi_fd_wrap_t*)); if (table->fds == NULL) diff --git a/src/uvwasi.c b/src/uvwasi.c index d0f24a0..c80fc77 100644 --- a/src/uvwasi.c +++ b/src/uvwasi.c @@ -574,7 +574,7 @@ uvwasi_errno_t uvwasi_init(uvwasi_t* uvwasi, uvwasi_options_t* options) { } } - err = uvwasi_fd_table_init(uvwasi, &uvwasi->fds, options->fd_table_size); + err = uvwasi_fd_table_init(uvwasi, options); if (err != UVWASI_ESUCCESS) goto exit; From df4a051968224912713fe8d7b46e87212c13d91b Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 13 Mar 2020 17:07:17 -0400 Subject: [PATCH 2/4] refactor stdio setup logic This commit refactors the code that configures the stdio descriptors. Instead of setting them up in a loop, use a function. This will make it simpler to add the stdio as configurable options. --- src/fd_table.c | 85 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/fd_table.c b/src/fd_table.c index e2bb879..2d8c9f4 100644 --- a/src/fd_table.c +++ b/src/fd_table.c @@ -14,6 +14,46 @@ #include "uvwasi_alloc.h" +static uvwasi_errno_t uvwasi__insert_stdio(uvwasi_t* uvwasi, + struct uvwasi_fd_table_t* table, + const uv_file fd, + const uvwasi_fd_t expected, + const char* name) { + struct uvwasi_fd_wrap_t* wrap; + uvwasi_filetype_t type; + uvwasi_rights_t base; + uvwasi_rights_t inheriting; + uvwasi_errno_t err; + + err = uvwasi__get_filetype_by_fd(fd, &type); + if (err != UVWASI_ESUCCESS) + return err; + + err = uvwasi__get_rights(fd, UV_FS_O_RDWR, type, &base, &inheriting); + if (err != UVWASI_ESUCCESS) + return err; + + err = uvwasi_fd_table_insert(uvwasi, + table, + fd, + name, + name, + type, + base, + inheriting, + 0, + &wrap); + if (err != UVWASI_ESUCCESS) + return err; + + if (wrap->id != expected) + err = UVWASI_EBADF; + + uv_mutex_unlock(&wrap->mutex); + return err; +} + + uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table, uv_file fd, @@ -119,12 +159,7 @@ uvwasi_errno_t uvwasi_fd_table_insert(uvwasi_t* uvwasi, uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, uvwasi_options_t* options) { struct uvwasi_fd_table_t* table; - struct uvwasi_fd_wrap_t* wrap; - uvwasi_filetype_t type; - uvwasi_rights_t base; - uvwasi_rights_t inheriting; uvwasi_errno_t err; - int i; int r; /* Require an initial size of at least three to store the stdio FDs. */ @@ -155,35 +190,17 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, } /* Create the stdio FDs. */ - for (i = 0; i < 3; ++i) { - err = uvwasi__get_filetype_by_fd(i, &type); - if (err != UVWASI_ESUCCESS) - goto error_exit; - - err = uvwasi__get_rights(i, UV_FS_O_RDWR, type, &base, &inheriting); - if (err != UVWASI_ESUCCESS) - goto error_exit; - - err = uvwasi_fd_table_insert(uvwasi, - table, - i, - "", - "", - type, - base, - inheriting, - 0, - &wrap); - if (err != UVWASI_ESUCCESS) - goto error_exit; - - r = (int) wrap->id != i || wrap->id != (uvwasi_fd_t) wrap->fd; - uv_mutex_unlock(&wrap->mutex); - if (r) { - err = UVWASI_EBADF; - goto error_exit; - } - } + err = uvwasi__insert_stdio(uvwasi, table, 0, 0, ""); + if (err != UVWASI_ESUCCESS) + goto error_exit; + + err = uvwasi__insert_stdio(uvwasi, table, 1, 1, ""); + if (err != UVWASI_ESUCCESS) + goto error_exit; + + err = uvwasi__insert_stdio(uvwasi, table, 2, 2, ""); + if (err != UVWASI_ESUCCESS) + goto error_exit; return UVWASI_ESUCCESS; error_exit: From 4d5fd1feeddb6c890713db7fd7137de878b6024f Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 13 Mar 2020 17:28:32 -0400 Subject: [PATCH 3/4] support passing stdio descriptors This commit requires the stdio file descriptors to be explicitly defined. This allows embedders to run multiple WASI applications in the same process (assuming they also monkey patch the uvwasi_proc_exit() functionality to not force the process to exit). --- README.md | 8 ++++++++ include/uvwasi.h | 3 +++ src/fd_table.c | 8 ++++---- test/test-args-get.c | 3 +++ test/test-basic-file-io.c | 3 +++ test/test-ebadf-input-validation.c | 3 +++ test/test-environ-get.c | 3 +++ test/test-fd-prestat-dir-name.c | 3 +++ test/test-multiple-wasi-destroys.c | 3 +++ test/test-path-create-remove-directory.c | 3 +++ test/test-random-get.c | 3 +++ 11 files changed, 39 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b6d1546..7e049c8 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ int main(void) { uvwasi_errno_t err; /* Setup the initialization options. */ + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 3; init_options.argv = calloc(3, sizeof(char*)); @@ -38,6 +41,7 @@ int main(void) { init_options.preopens = calloc(1, sizeof(uvwasi_preopen_t)); init_options.preopens[0].mapped_path = "/var"; init_options.preopens[0].real_path = "."; + init_options.allocator = NULL; /* Initialize the sandbox. */ err = uvwasi_init(&uvwasi, &init_options); @@ -146,6 +150,10 @@ typedef struct uvwasi_options_s { size_t argc; char** argv; char** envp; + uvwasi_fd_t stdin; + uvwasi_fd_t stdout; + uvwasi_fd_t stderr; + const uvwasi_mem_t* allocator; } uvwasi_options_t; ``` diff --git a/include/uvwasi.h b/include/uvwasi.h index 9ca3045..44de573 100644 --- a/include/uvwasi.h +++ b/include/uvwasi.h @@ -60,6 +60,9 @@ typedef struct uvwasi_options_s { size_t argc; char** argv; char** envp; + uvwasi_fd_t stdin; + uvwasi_fd_t stdout; + uvwasi_fd_t stderr; const uvwasi_mem_t* allocator; } uvwasi_options_t; diff --git a/src/fd_table.c b/src/fd_table.c index 2d8c9f4..1b636e4 100644 --- a/src/fd_table.c +++ b/src/fd_table.c @@ -16,7 +16,7 @@ static uvwasi_errno_t uvwasi__insert_stdio(uvwasi_t* uvwasi, struct uvwasi_fd_table_t* table, - const uv_file fd, + const uvwasi_fd_t fd, const uvwasi_fd_t expected, const char* name) { struct uvwasi_fd_wrap_t* wrap; @@ -190,15 +190,15 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, } /* Create the stdio FDs. */ - err = uvwasi__insert_stdio(uvwasi, table, 0, 0, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->stdin, 0, ""); if (err != UVWASI_ESUCCESS) goto error_exit; - err = uvwasi__insert_stdio(uvwasi, table, 1, 1, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->stdout, 1, ""); if (err != UVWASI_ESUCCESS) goto error_exit; - err = uvwasi__insert_stdio(uvwasi, table, 2, 2, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->stderr, 2, ""); if (err != UVWASI_ESUCCESS) goto error_exit; diff --git a/test/test-args-get.c b/test/test-args-get.c index 79ec30b..715ac95 100644 --- a/test/test-args-get.c +++ b/test/test-args-get.c @@ -12,6 +12,9 @@ int main(void) { char** args_get_argv; char* buf; + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 3; init_options.argv = calloc(3, sizeof(char*)); diff --git a/test/test-basic-file-io.c b/test/test-basic-file-io.c index 45c3b17..67be3f4 100644 --- a/test/test-basic-file-io.c +++ b/test/test-basic-file-io.c @@ -29,6 +29,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_EEXIST); + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-ebadf-input-validation.c b/test/test-ebadf-input-validation.c index 46f7d0a..2c7f316 100644 --- a/test/test-ebadf-input-validation.c +++ b/test/test-ebadf-input-validation.c @@ -22,6 +22,9 @@ int main(void) { test_void = (void*) &test_fdstat; + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-environ-get.c b/test/test-environ-get.c index b235226..3af684e 100644 --- a/test/test-environ-get.c +++ b/test/test-environ-get.c @@ -20,6 +20,9 @@ int main(void) { char* buf; size_t i; + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-fd-prestat-dir-name.c b/test/test-fd-prestat-dir-name.c index 783484d..3e99a97 100644 --- a/test/test-fd-prestat-dir-name.c +++ b/test/test-fd-prestat-dir-name.c @@ -19,6 +19,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_EEXIST); + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-multiple-wasi-destroys.c b/test/test-multiple-wasi-destroys.c index b762f90..6d37a48 100644 --- a/test/test-multiple-wasi-destroys.c +++ b/test/test-multiple-wasi-destroys.c @@ -8,6 +8,9 @@ int main(void) { uvwasi_options_t init_options; uvwasi_errno_t err; + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-path-create-remove-directory.c b/test/test-path-create-remove-directory.c index 83a731d..eca154d 100644 --- a/test/test-path-create-remove-directory.c +++ b/test/test-path-create-remove-directory.c @@ -21,6 +21,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_ENOENT); + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-random-get.c b/test/test-random-get.c index 13cc6e8..7ee7347 100644 --- a/test/test-random-get.c +++ b/test/test-random-get.c @@ -13,6 +13,9 @@ int main(void) { int success; int i; + init_options.stdin = 0; + init_options.stdout = 1; + init_options.stderr = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; From cdd8c082d3451624cc6a49d9b61d9b77e7fde64a Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 13 Mar 2020 17:48:45 -0400 Subject: [PATCH 4/4] rename std* for Windows Windows doesn't seem to like the use of stdin, stdout, or stderr as struct members. --- README.md | 12 ++++++------ include/uvwasi.h | 6 +++--- src/fd_table.c | 6 +++--- test/test-args-get.c | 6 +++--- test/test-basic-file-io.c | 6 +++--- test/test-ebadf-input-validation.c | 6 +++--- test/test-environ-get.c | 6 +++--- test/test-fd-prestat-dir-name.c | 6 +++--- test/test-multiple-wasi-destroys.c | 6 +++--- test/test-path-create-remove-directory.c | 6 +++--- test/test-random-get.c | 6 +++--- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 7e049c8..bb53afa 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,9 @@ int main(void) { uvwasi_errno_t err; /* Setup the initialization options. */ - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 3; init_options.argv = calloc(3, sizeof(char*)); @@ -150,9 +150,9 @@ typedef struct uvwasi_options_s { size_t argc; char** argv; char** envp; - uvwasi_fd_t stdin; - uvwasi_fd_t stdout; - uvwasi_fd_t stderr; + uvwasi_fd_t in; + uvwasi_fd_t out; + uvwasi_fd_t err; const uvwasi_mem_t* allocator; } uvwasi_options_t; ``` diff --git a/include/uvwasi.h b/include/uvwasi.h index 44de573..4aa15e7 100644 --- a/include/uvwasi.h +++ b/include/uvwasi.h @@ -60,9 +60,9 @@ typedef struct uvwasi_options_s { size_t argc; char** argv; char** envp; - uvwasi_fd_t stdin; - uvwasi_fd_t stdout; - uvwasi_fd_t stderr; + uvwasi_fd_t in; + uvwasi_fd_t out; + uvwasi_fd_t err; const uvwasi_mem_t* allocator; } uvwasi_options_t; diff --git a/src/fd_table.c b/src/fd_table.c index 1b636e4..f6e530d 100644 --- a/src/fd_table.c +++ b/src/fd_table.c @@ -190,15 +190,15 @@ uvwasi_errno_t uvwasi_fd_table_init(uvwasi_t* uvwasi, } /* Create the stdio FDs. */ - err = uvwasi__insert_stdio(uvwasi, table, options->stdin, 0, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->in, 0, ""); if (err != UVWASI_ESUCCESS) goto error_exit; - err = uvwasi__insert_stdio(uvwasi, table, options->stdout, 1, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->out, 1, ""); if (err != UVWASI_ESUCCESS) goto error_exit; - err = uvwasi__insert_stdio(uvwasi, table, options->stderr, 2, ""); + err = uvwasi__insert_stdio(uvwasi, table, options->err, 2, ""); if (err != UVWASI_ESUCCESS) goto error_exit; diff --git a/test/test-args-get.c b/test/test-args-get.c index 715ac95..6973975 100644 --- a/test/test-args-get.c +++ b/test/test-args-get.c @@ -12,9 +12,9 @@ int main(void) { char** args_get_argv; char* buf; - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 3; init_options.argv = calloc(3, sizeof(char*)); diff --git a/test/test-basic-file-io.c b/test/test-basic-file-io.c index 67be3f4..492408c 100644 --- a/test/test-basic-file-io.c +++ b/test/test-basic-file-io.c @@ -29,9 +29,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_EEXIST); - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-ebadf-input-validation.c b/test/test-ebadf-input-validation.c index 2c7f316..31662da 100644 --- a/test/test-ebadf-input-validation.c +++ b/test/test-ebadf-input-validation.c @@ -22,9 +22,9 @@ int main(void) { test_void = (void*) &test_fdstat; - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-environ-get.c b/test/test-environ-get.c index 3af684e..aa7cc23 100644 --- a/test/test-environ-get.c +++ b/test/test-environ-get.c @@ -20,9 +20,9 @@ int main(void) { char* buf; size_t i; - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-fd-prestat-dir-name.c b/test/test-fd-prestat-dir-name.c index 3e99a97..800f4a8 100644 --- a/test/test-fd-prestat-dir-name.c +++ b/test/test-fd-prestat-dir-name.c @@ -19,9 +19,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_EEXIST); - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-multiple-wasi-destroys.c b/test/test-multiple-wasi-destroys.c index 6d37a48..b1ad17b 100644 --- a/test/test-multiple-wasi-destroys.c +++ b/test/test-multiple-wasi-destroys.c @@ -8,9 +8,9 @@ int main(void) { uvwasi_options_t init_options; uvwasi_errno_t err; - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-path-create-remove-directory.c b/test/test-path-create-remove-directory.c index eca154d..b59114a 100644 --- a/test/test-path-create-remove-directory.c +++ b/test/test-path-create-remove-directory.c @@ -21,9 +21,9 @@ int main(void) { uv_fs_req_cleanup(&req); assert(r == 0 || r == UV_ENOENT); - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL; diff --git a/test/test-random-get.c b/test/test-random-get.c index 7ee7347..5bfd14f 100644 --- a/test/test-random-get.c +++ b/test/test-random-get.c @@ -13,9 +13,9 @@ int main(void) { int success; int i; - init_options.stdin = 0; - init_options.stdout = 1; - init_options.stderr = 2; + init_options.in = 0; + init_options.out = 1; + init_options.err = 2; init_options.fd_table_size = 3; init_options.argc = 0; init_options.argv = NULL;