Просмотр исходного кода

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 <lifeng68@huawei.com>
LiFeng 4 лет назад
Родитель
Сommit
c6783ef258

+ 3 - 0
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;
     }

+ 30 - 5
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;

+ 9 - 0
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

+ 8 - 0
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,

+ 1 - 0
core/iwasm/interpreter/wasm.h

@@ -305,6 +305,7 @@ typedef struct WASIArguments {
     uint32 env_count;
     char **argv;
     uint32 argc;
+    int stdio[3];
 } WASIArguments;
 #endif
 

+ 3 - 0
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;
         }

+ 21 - 6
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);

+ 15 - 9
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;
 }