summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-12 15:14:51 (GMT)
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-12 15:14:51 (GMT)
commitb712840c8a97c4c361f1136143448af8756279e2 (patch)
treeb2f1e42254a080737164ca9ed91bc1dd4a3a6952 /win32
parenta113da5b18cc4472844cd79db6dbc30989767412 (diff)
mjit_worker.c: suppress child process's output properly
Prior to this commit, some of parent process's output was unintentionally suppressed. We couldn't suppress only child process's output with spawnvp. Instead of that, this commit uses CreateProcess directly to redirect stdout and stderr only for child process. As it's dealing with HANDLE returned from CreateProcess, now waitpid macro needs to CloseHandle it. win32/win32.c: Introduce rb_w32_start_process which is designed for MJIT worker. Other similar functions can't be used since they are using ALLOCV that may trigger GC, which should be avoided on MJIT worker. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65033 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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 8165812..9e319b3 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;