diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/win32/win32.c b/win32/win32.c index 8165812b25..9e319b3d1d 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1298,6 +1298,47 @@ is_batch(const char *cmd) #define utf8_to_wstr(str, plen) mbstr_to_wstr(CP_UTF8, str, -1, plen) #define wstr_to_utf8(str, plen) wstr_to_mbstr(CP_UTF8, str, -1, plen) +/* License: Ruby's */ +MJIT_FUNC_EXPORTED HANDLE +rb_w32_start_process(const char *abspath, char *const *argv, int out_fd) +{ + /* NOTE: This function is used by MJIT worker, i.e. it must not touch Ruby VM. + This function is not using ALLOCV that may trigger GC. So this can't be + replaced with some families in this file. */ + struct ChildRecord *child; + char *cmd; + size_t len; + WCHAR *wcmd = NULL, *wprog = NULL; + HANDLE outHandle = NULL; + + if (out_fd) { + outHandle = (HANDLE)rb_w32_get_osfhandle(out_fd); + } + + len = join_argv(NULL, argv, FALSE, filecp(), 1); + cmd = alloca(sizeof(char) * len); + join_argv(cmd, argv, FALSE, filecp(), 1); + + if (!(wcmd = mbstr_to_wstr(filecp(), cmd, -1, NULL))) { + errno = E2BIG; + return 0; + } + if (!(wprog = mbstr_to_wstr(filecp(), abspath, -1, NULL))) { + errno = E2BIG; + return 0; + } + + child = CreateChild(wcmd, wprog, NULL, NULL, outHandle, outHandle, 0); + if (child == NULL) { + return 0; + } + child->pid = 0; /* release the slot */ + + free(wcmd); + free(wprog); + return child->hProcess; +} + /* License: Artistic or GPL */ static rb_pid_t w32_spawn(int mode, const char *cmd, const char *prog, UINT cp) @@ -2112,6 +2153,7 @@ rb_w32_wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen, long *plen) WCHAR * rb_w32_mbstr_to_wstr(UINT cp, const char *str, int clen, long *plen) { + /* This is used by MJIT worker. Do not trigger GC or call Ruby method here. */ WCHAR *ptr; int len = MultiByteToWideChar(cp, 0, str, clen, NULL, 0); if (!(ptr = malloc(sizeof(WCHAR) * len))) return 0; |