summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c42
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;