From c6783ef258feb3339d401f14a784ebd599e63722 Mon Sep 17 00:00:00 2001 From: LiFeng Date: Tue, 22 Jun 2021 14:41:49 +0800 Subject: [PATCH] IO: support populate fds into WASM application (#655) Add new API wasm_runtime_set_wasi_args_ex to support populate stdio fds Signed-off-by: LiFeng --- core/iwasm/aot/aot_runtime.c | 3 ++ core/iwasm/common/wasm_runtime_common.c | 35 ++++++++++++++++--- core/iwasm/common/wasm_runtime_common.h | 9 +++++ core/iwasm/include/wasm_export.h | 8 +++++ core/iwasm/interpreter/wasm.h | 1 + core/iwasm/interpreter/wasm_runtime.c | 3 ++ .../linux-sgx/enclave-sample/App/App.cpp | 27 ++++++++++---- .../enclave-sample/Enclave/Enclave.cpp | 24 ++++++++----- 8 files changed, 90 insertions(+), 20 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index dd05c94c..484835df 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -1036,6 +1036,9 @@ aot_instantiate(AOTModule *module, bool is_sub_inst, module->wasi_args.env_count, module->wasi_args.argv, module->wasi_args.argc, + module->wasi_args.stdio[0], + module->wasi_args.stdio[1], + module->wasi_args.stdio[2], error_buf, error_buf_size)) goto fail; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 91ae8457..535e7fd0 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1793,12 +1793,14 @@ wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module, } #if WASM_ENABLE_LIBC_WASI != 0 + void -wasm_runtime_set_wasi_args(WASMModuleCommon *module, +wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[], uint32 dir_count, const char *map_dir_list[], uint32 map_dir_count, const char *env_list[], uint32 env_count, - char *argv[], int argc) + char *argv[], int argc, + int stdinfd, int stdoutfd, int stderrfd) { WASIArguments *wasi_args = NULL; @@ -1820,9 +1822,27 @@ wasm_runtime_set_wasi_args(WASMModuleCommon *module, wasi_args->env_count = env_count; wasi_args->argv = argv; wasi_args->argc = (uint32)argc; + wasi_args->stdio[0] = stdinfd; + wasi_args->stdio[1] = stdoutfd; + wasi_args->stdio[2] = stderrfd; } } +void +wasm_runtime_set_wasi_args(WASMModuleCommon *module, + const char *dir_list[], uint32 dir_count, + const char *map_dir_list[], uint32 map_dir_count, + const char *env_list[], uint32 env_count, + char *argv[], int argc) +{ + wasm_runtime_set_wasi_args_ex(module, + dir_list, dir_count, + map_dir_list, map_dir_count, + env_list, env_count, + argv, argc, + -1, -1, -1); +} + #if WASM_ENABLE_UVWASI == 0 bool wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, @@ -1830,6 +1850,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, const char *map_dir_list[], uint32 map_dir_count, const char *env[], uint32 env_count, char *argv[], uint32 argc, + int stdinfd, int stdoutfd, int stderrfd, char *error_buf, uint32 error_buf_size) { WASIContext *wasi_ctx; @@ -1951,9 +1972,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, argv_environ_inited = true; /* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */ - if (!fd_table_insert_existing(curfds, 0, 0) - || !fd_table_insert_existing(curfds, 1, 1) - || !fd_table_insert_existing(curfds, 2, 2)) { + if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0) + || !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1) + || !fd_table_insert_existing(curfds, 2, (stderrfd != -1) ? stderrfd : 2)) { set_error_buf(error_buf, error_buf_size, "Init wasi environment failed: init fd table failed"); goto fail; @@ -2065,6 +2086,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, const char *map_dir_list[], uint32 map_dir_count, const char *env[], uint32 env_count, char *argv[], uint32 argc, + int stdinfd, int stdoutfd, int stderrfd, char *error_buf, uint32 error_buf_size) { uvwasi_t *uvwasi = NULL; @@ -2084,6 +2106,9 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, init_options.allocator = &uvwasi_allocator; init_options.argc = argc; init_options.argv = (const char **)argv; + init_options.in = (stdinfd != -1) ? (uvwasi_fd_t)stdinfd : init_options.in; + init_options.out = (stdoutfd != -1) ? (uvwasi_fd_t)stdoutfd : init_options.out; + init_options.err = (stderrfd != -1) ? (uvwasi_fd_t)stderrfd : init_options.err; if (dir_count > 0) { init_options.preopenc = dir_count; diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 4ed88622..e8138bd2 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -630,6 +630,14 @@ wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, #endif #if WASM_ENABLE_LIBC_WASI != 0 +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, + const char *dir_list[], uint32 dir_count, + const char *map_dir_list[], uint32 map_dir_count, + const char *env_list[], uint32 env_count, + char *argv[], int argc, + int stdinfd, int stdoutfd, int stderrfd); + /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN void wasm_runtime_set_wasi_args(WASMModuleCommon *module, @@ -652,6 +660,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, const char *map_dir_list[], uint32 map_dir_count, const char *env[], uint32 env_count, char *argv[], uint32 argc, + int stdinfd, int stdoutfd, int stderrfd, char *error_buf, uint32 error_buf_size); void diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index a4394adb..0fe46d61 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -313,6 +313,14 @@ wasm_runtime_load_from_sections(wasm_section_list_t section_list, bool is_aot, WASM_RUNTIME_API_EXTERN void wasm_runtime_unload(wasm_module_t module); +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_wasi_args_ex(wasm_module_t module, + const char *dir_list[], uint32_t dir_count, + const char *map_dir_list[], uint32_t map_dir_count, + const char *env[], uint32_t env_count, + char *argv[], int argc, + int stdinfd, int stdoutfd, int stderrfd); + WASM_RUNTIME_API_EXTERN void wasm_runtime_set_wasi_args(wasm_module_t module, const char *dir_list[], uint32_t dir_count, diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index d99036e5..02b712e8 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -305,6 +305,7 @@ typedef struct WASIArguments { uint32 env_count; char **argv; uint32 argc; + int stdio[3]; } WASIArguments; #endif diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index d3874dfa..0b43f189 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1483,6 +1483,9 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, module->wasi_args.env_count, module->wasi_args.argv, module->wasi_args.argc, + module->wasi_args.stdio[0], + module->wasi_args.stdio[1], + module->wasi_args.stdio[2], error_buf, error_buf_size)) { goto fail; } diff --git a/product-mini/platforms/linux-sgx/enclave-sample/App/App.cpp b/product-mini/platforms/linux-sgx/enclave-sample/App/App.cpp index d15acbd3..14b8c415 100644 --- a/product-mini/platforms/linux-sgx/enclave-sample/App/App.cpp +++ b/product-mini/platforms/linux-sgx/enclave-sample/App/App.cpp @@ -550,20 +550,24 @@ static bool set_wasi_args(void *wasm_module, const char **dir_list, uint32_t dir_list_size, const char **env_list, uint32_t env_list_size, + int stdinfd, int stdoutfd, int stderrfd, char **argv, uint32_t argc) { - uint64_t ecall_args[7]; + uint64_t ecall_args[10]; ecall_args[0] = (uint64_t)(uintptr_t)wasm_module; ecall_args[1] = (uint64_t)(uintptr_t)dir_list; ecall_args[2] = dir_list_size; ecall_args[3] = (uint64_t)(uintptr_t)env_list; ecall_args[4] = env_list_size; - ecall_args[5] = (uint64_t)(uintptr_t)argv; - ecall_args[6] = argc; + ecall_args[5] = stdinfd; + ecall_args[6] = stdoutfd; + ecall_args[7] = stderrfd; + ecall_args[8] = (uint64_t)(uintptr_t)argv; + ecall_args[9] = argc; if (SGX_SUCCESS != ecall_handle_command(g_eid, CMD_SET_WASI_ARGS, (uint8_t *)ecall_args, - sizeof(uint64_t) * 7)) { + sizeof(uint64_t) * 10)) { printf("Call ecall_handle_command() failed.\n"); } @@ -702,7 +706,7 @@ main(int argc, char *argv[]) /* Set wasi arguments */ if (!set_wasi_args(wasm_module, dir_list, dir_list_size, - env_list, env_list_size, argv, argc)) { + env_list, env_list_size, 0, 1, 2, argv, argc)) { printf("%s\n", "set wasi arguments failed.\n"); goto fail3; } @@ -773,6 +777,9 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args) uint32_t max_thread_num = 4; char *wasm_files[16]; void *wasm_module_inst[16]; + int stdinfd = -1; + int stdoutfd = -1; + int stderrfd = -1; int argc = 2; char *argv[argc] = { (char*)"./iwasm", (char *)args->argv[0] }; @@ -796,6 +803,12 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args) wasm_files[i] = (char *)args->argv[i]; } + if (args->stdio != NULL) { + stdinfd = args->stdio->stdin_fd; + stdoutfd = args->stdio->stdout_fd; + stderrfd = args->stdio->stderr_fd; + } + /* Init runtime */ if (!init_runtime(alloc_with_pool, max_thread_num)) { printf("Failed to init runtime\n"); @@ -834,7 +847,9 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args) /* Set wasi arguments */ if (!set_wasi_args(wasm_module, dir_list, dir_list_size, - env_list, env_list_size, argv, argc)) { + env_list, env_list_size, + stdinfd, stdoutfd, stderrfd, + argv, argc)) { printf("%s\n", "set wasi arguments failed.\n"); unload_module(wasm_module); free(wasm_file_buf); diff --git a/product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp b/product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp index ed9ca418..15ce6c29 100644 --- a/product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp +++ b/product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp @@ -311,13 +311,16 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc) uint32 dir_list_size = *(uint32 *)args++; char **env_list = *(char ***)args++; uint32 env_list_size = *(uint32 *)args++; + int stdinfd = *(int *)args++; + int stdoutfd = *(int *)args++; + int stderrfd = *(int *)args++; char **wasi_argv = *(char ***)args++; char *p, *p1; uint32 wasi_argc = *(uint32 *)args++; uint64 total_size = 0; int32 i, str_len; - bh_assert(argc == 7); + bh_assert(argc == 10); total_size += sizeof(char *) * (uint64)dir_list_size + sizeof(char *) * (uint64)env_list_size @@ -382,14 +385,17 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc) p += sizeof(char *) * wasi_argc; } - wasm_runtime_set_wasi_args(enclave_module->module, - (const char **)enclave_module->wasi_dir_list, - dir_list_size, - NULL, 0, - (const char **)enclave_module->wasi_env_list, - env_list_size, - enclave_module->wasi_argv, - enclave_module->wasi_argc); + wasm_runtime_set_wasi_args_ex(enclave_module->module, + (const char **)enclave_module->wasi_dir_list, + dir_list_size, + NULL, 0, + (const char **)enclave_module->wasi_env_list, + env_list_size, + enclave_module->wasi_argv, + enclave_module->wasi_argc, + (stdinfd != -1) ? stdinfd : 0, + (stdoutfd != -1) ? stdoutfd : 1, + (stderrfd != -1) ? stderrfd : 2); *args_org = true; }