added __spawn_process for windows
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 2 Dec 2021 04:02:14 +0000 (22:02 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 2 Dec 2021 04:02:14 +0000 (22:02 -0600)
include/small_windows.h
src/wasm_runtime.c

index 2836ad7a3a6c9bbaaeee9959216296cc8966300a..9aa075f5a174d08647de3581a46f17e9b8f6989a 100644 (file)
@@ -256,6 +256,32 @@ typedef enum _GET_FILEEX_INFO_LEVELS {
     GetFileExInfoStandard,
     GetFileExMaxInfoLevel
 } GET_FILEEX_INFO_LEVELS;
+typedef struct _STARTUPINFOA {
+  DWORD  cb;
+  char * lpReserved;
+  char * lpDesktop;
+  char * lpTitle;
+  DWORD  dwX;
+  DWORD  dwY;
+  DWORD  dwXSize;
+  DWORD  dwYSize;
+  DWORD  dwXCountChars;
+  DWORD  dwYCountChars;
+  DWORD  dwFillAttribute;
+  DWORD  dwFlags;
+  WORD   wShowWindow;
+  WORD   cbReserved2;
+  char * lpReserved2;
+  HANDLE hStdInput;
+  HANDLE hStdOutput;
+  HANDLE hStdError;
+} STARTUPINFOA, *LPSTARTUPINFOA;
+typedef struct _PROCESS_INFORMATION {
+  HANDLE hProcess;
+  HANDLE hThread;
+  DWORD  dwProcessId;
+  DWORD  dwThreadId;
+} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
 
 #define INFINITE 0xffffffffl
 #define INVALID_HANDLE_VALUE ((void *)(intptr_t)(-1))
@@ -275,7 +301,11 @@ GB_DLL_IMPORT HANDLE  WINAPI CreateThread       (SECURITY_ATTRIBUTES *semaphore_
 GB_DLL_IMPORT DWORD   WINAPI GetThreadId        (HANDLE handle);
 GB_DLL_IMPORT void    WINAPI RaiseException     (DWORD, DWORD, DWORD, ULONG_PTR const *);
 GB_DLL_IMPORT BOOL    WINAPI TerminateThread    (HANDLE hThread, DWORD dwExitCode);
-
+GB_DLL_IMPORT BOOL    WINAPI CreateProcessA     (char const * lpApplicationName, char * lpCommandLine,
+                                                 SECURITY_ATTRIBUTES* lpProcessAttrs, SECURITY_ATTRIBUTES* lpThreadAttributes,
+                                                 BOOL bInheritHandles, DWORD dwCreationFlags, void* lpEnvironment,
+                                                 char const * lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo,
+                                                 LPPROCESS_INFORMATION lpProcessInformation);
 
 GB_DLL_IMPORT BOOL      WINAPI GetLogicalProcessorInformation(SYSTEM_LOGICAL_PROCESSOR_INFORMATION *buffer, DWORD *return_length);
 GB_DLL_IMPORT DWORD_PTR WINAPI SetThreadAffinityMask(HANDLE thread, DWORD_PTR check_mask);
index 3a0a8d5802a1443120aeaa858e9906ce088dc710..f01c93f008a593c68be43178dcceb5c44ae69755 100644 (file)
@@ -183,22 +183,24 @@ static wasm_trap_t* onyx_spawn_process_impl(const wasm_val_vec_t* params, wasm_v
     memcpy(process_path, process_str, process_len);
     process_path[process_len] = '\0';
 
-    char **process_args = bh_alloc_array(global_scratch_allocator, char *, args_len + 2);
-    byte_t* data = wasm_memory_data(wasm_memory);
-    byte_t* array_loc = data + args_ptr;
-    fori (i, 1, args_len + 1) {
-        char *arg_str = data + *(i32 *) (array_loc + (i - 1) * 8);
-        i32   arg_len = *(i32 *) (array_loc + (i - 1) * 8 + 4);
-
-        char *arg = bh_alloc_array(global_scratch_allocator, char, arg_len + 1);
-        memcpy(arg, arg_str, arg_len);
-        arg[arg_len] = '\0';
-        process_args[i] = arg;
-    }
-    process_args[0] = process_path;
-    process_args[args_len + 1] = NULL;
+    // CLEANUP: Make the return value from the Windows and Linux version mean the same thing!!!
 
     #ifdef _BH_LINUX
+        char **process_args = bh_alloc_array(global_scratch_allocator, char *, args_len + 2);
+        byte_t* data = wasm_memory_data(wasm_memory);
+        byte_t* array_loc = data + args_ptr;
+        fori (i, 0, args_len) {
+            char *arg_str = data + *(i32 *) (array_loc + i * 2 * POINTER_SIZE);
+            i32   arg_len = *(i32 *) (array_loc + i * 2 * POINTER_SIZE + 4);
+
+            char *arg = bh_alloc_array(global_scratch_allocator, char, arg_len + 1);
+            memcpy(arg, arg_str, arg_len);
+            arg[arg_len] = '\0';
+            process_args[i - 1] = arg;
+        }
+        process_args[0] = process_path;
+        process_args[args_len + 1] = NULL;
+
         if (fork() == 0) {
             execv(process_path, process_args);
         }
@@ -208,6 +210,32 @@ static wasm_trap_t* onyx_spawn_process_impl(const wasm_val_vec_t* params, wasm_v
         results->data[0] = WASM_I32_VAL(WEXITSTATUS(status));
     #endif
 
+    #ifdef _BH_WINDOWS
+        // CLEANUP CLEANUP CLEANUP: This is so freaking bad...
+        char cmdLine[2048];
+        memset(cmdLine, 0, 2048);
+        strncat(cmdLine, process_path, 2047);
+        
+        byte_t* data = wasm_memory_data(wasm_memory);
+        byte_t* array_loc = data + args_ptr;
+        fori (i, 0, args_len) {
+            char *arg_str = data + *(i32 *) (array_loc + i * 2 * POINTER_SIZE);
+            i32   arg_len = *(i32 *) (array_loc + i * 2 * POINTER_SIZE + 4);
+
+            strncat(cmdLine, " ", 2047);
+            strncat(cmdLine, arg_str, arg_len);
+        }
+
+        STARTUPINFOA startup;
+        memset(&startup, 0, sizeof startup);
+        startup.cb = sizeof(startup);
+
+        PROCESS_INFORMATION proc_info;
+        BOOL success = CreateProcessA(process_path, cmdLine, NULL, NULL, 1, 0, NULL, NULL, &startup, &proc_info);
+        DWORD result = WaitForSingleObject(proc_info.hProcess, INFINITE);
+        results->data[0] = WASM_I32_VAL(result);
+    #endif
+
     return NULL;
 }