diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-09-16 00:41:48 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2018-09-16 00:41:48 +0900 |
| commit | 2661ac70499601f28741be01e0ce82da0a4733bc (patch) | |
| tree | 398800c7471ab0cad5d37a6d46cb946a1bbc3f6e | |
| parent | f93734f6228e541ea4eee5f2dd208981ce6e38bd (diff) | |
| download | mruby-2661ac70499601f28741be01e0ce82da0a4733bc.tar.gz mruby-2661ac70499601f28741be01e0ce82da0a4733bc.zip | |
Add support for iOS platforms that does not support `fork`; fix #4113
| -rw-r--r-- | include/mruby/common.h | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 209 |
2 files changed, 113 insertions, 101 deletions
diff --git a/include/mruby/common.h b/include/mruby/common.h index d6ec78b0d..4c7d9384a 100644 --- a/include/mruby/common.h +++ b/include/mruby/common.h @@ -7,6 +7,11 @@ #ifndef MRUBY_COMMON_H #define MRUBY_COMMON_H +#ifdef __APPLE__ + #ifndef __TARGETCONDITIONALS__ + #include "TargetConditionals.h" + #endif +#endif #ifdef __cplusplus #ifdef MRB_ENABLE_CXX_ABI diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 67c57a08e..be5c4ba68 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -305,7 +305,112 @@ option_to_fd(mrb_state *mrb, mrb_value obj, const char *key) return -1; /* never reached */ } -#ifndef _WIN32 +#ifdef _WIN32 +mrb_value +mrb_io_s_popen(mrb_state *mrb, mrb_value klass) +{ + mrb_value cmd, io; + mrb_value mode = mrb_str_new_cstr(mrb, "r"); + mrb_value opt = mrb_hash_new(mrb); + + struct mrb_io *fptr; + const char *pname; + int pid = 0, flags; + STARTUPINFO si; + PROCESS_INFORMATION pi; + SECURITY_ATTRIBUTES saAttr; + + HANDLE ifd[2]; + HANDLE ofd[2]; + + int doexec; + int opt_in, opt_out, opt_err; + + ifd[0] = INVALID_HANDLE_VALUE; + ifd[1] = INVALID_HANDLE_VALUE; + ofd[0] = INVALID_HANDLE_VALUE; + ofd[1] = INVALID_HANDLE_VALUE; + + mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); + io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); + + pname = mrb_string_value_cstr(mrb, &cmd); + flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); + + doexec = (strcmp("-", pname) != 0); + opt_in = option_to_fd(mrb, opt, "in"); + opt_out = option_to_fd(mrb, opt, "out"); + opt_err = option_to_fd(mrb, opt, "err"); + + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + if (flags & FMODE_READABLE) { + if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) + || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) { + mrb_sys_fail(mrb, "pipe"); + } + } + + if (flags & FMODE_WRITABLE) { + if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) + || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) { + mrb_sys_fail(mrb, "pipe"); + } + } + + if (doexec) { + ZeroMemory(&pi, sizeof(pi)); + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags |= STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + si.dwFlags |= STARTF_USESTDHANDLES; + if (flags & FMODE_READABLE) { + si.hStdOutput = ofd[1]; + si.hStdError = ofd[1]; + } + if (flags & FMODE_WRITABLE) { + si.hStdInput = ifd[0]; + } + if (!CreateProcess( + NULL, (char*)pname, NULL, NULL, + TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { + CloseHandle(ifd[0]); + CloseHandle(ifd[1]); + CloseHandle(ofd[0]); + CloseHandle(ofd[1]); + mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); + } + CloseHandle(pi.hThread); + CloseHandle(ifd[0]); + CloseHandle(ofd[1]); + pid = pi.dwProcessId; + } + + mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); + + fptr = mrb_io_alloc(mrb); + fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0); + fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0); + fptr->pid = pid; + fptr->readable = ((flags & FMODE_READABLE) != 0); + fptr->writable = ((flags & FMODE_WRITABLE) != 0); + fptr->sync = 0; + + DATA_TYPE(io) = &mrb_io_type; + DATA_PTR(io) = fptr; + return io; +} +#elif TARGET_OS_IPHONE +mrb_value +mrb_io_s_popen(mrb_state *mrb, mrb_value klass) +{ + mrb_raise(mrb, E_NOTIMP_ERROR, "IO#popen is not supported on the platform"); + return mrb_false_value();w +} +#else mrb_value mrb_io_s_popen(mrb_state *mrb, mrb_value klass) { @@ -440,104 +545,6 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass) } return result; } -#else -mrb_value -mrb_io_s_popen(mrb_state *mrb, mrb_value klass) -{ - mrb_value cmd, io; - mrb_value mode = mrb_str_new_cstr(mrb, "r"); - mrb_value opt = mrb_hash_new(mrb); - - struct mrb_io *fptr; - const char *pname; - int pid = 0, flags; - STARTUPINFO si; - PROCESS_INFORMATION pi; - SECURITY_ATTRIBUTES saAttr; - - HANDLE ifd[2]; - HANDLE ofd[2]; - - int doexec; - int opt_in, opt_out, opt_err; - - ifd[0] = INVALID_HANDLE_VALUE; - ifd[1] = INVALID_HANDLE_VALUE; - ofd[0] = INVALID_HANDLE_VALUE; - ofd[1] = INVALID_HANDLE_VALUE; - - mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); - io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - - pname = mrb_string_value_cstr(mrb, &cmd); - flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); - - doexec = (strcmp("-", pname) != 0); - opt_in = option_to_fd(mrb, opt, "in"); - opt_out = option_to_fd(mrb, opt, "out"); - opt_err = option_to_fd(mrb, opt, "err"); - - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = NULL; - - if (flags & FMODE_READABLE) { - if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) - || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) { - mrb_sys_fail(mrb, "pipe"); - } - } - - if (flags & FMODE_WRITABLE) { - if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) - || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) { - mrb_sys_fail(mrb, "pipe"); - } - } - - if (doexec) { - ZeroMemory(&pi, sizeof(pi)); - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - si.dwFlags |= STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - si.dwFlags |= STARTF_USESTDHANDLES; - if (flags & FMODE_READABLE) { - si.hStdOutput = ofd[1]; - si.hStdError = ofd[1]; - } - if (flags & FMODE_WRITABLE) { - si.hStdInput = ifd[0]; - } - if (!CreateProcess( - NULL, (char*)pname, NULL, NULL, - TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { - CloseHandle(ifd[0]); - CloseHandle(ifd[1]); - CloseHandle(ofd[0]); - CloseHandle(ofd[1]); - mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); - } - CloseHandle(pi.hThread); - CloseHandle(ifd[0]); - CloseHandle(ofd[1]); - pid = pi.dwProcessId; - } - - mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); - - fptr = mrb_io_alloc(mrb); - fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0); - fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0); - fptr->pid = pid; - fptr->readable = ((flags & FMODE_READABLE) != 0); - fptr->writable = ((flags & FMODE_WRITABLE) != 0); - fptr->sync = 0; - - DATA_TYPE(io) = &mrb_io_type; - DATA_PTR(io) = fptr; - return io; -} #endif static int @@ -1004,7 +1011,7 @@ mrb_io_read_data_pending(mrb_state *mrb, mrb_value io) return 0; } -#ifndef _WIN32 +#if !defined(_WIN32) && !TARGET_OS_IPHONE static mrb_value mrb_io_s_pipe(mrb_state *mrb, mrb_value klass) { @@ -1306,7 +1313,7 @@ mrb_init_io(mrb_state *mrb) mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ANY()); mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY()); mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY()); -#ifndef _WIN32 +#if !defined(_WIN32) && !TARGET_OS_IPHONE mrb_define_class_method(mrb, io, "_pipe", mrb_io_s_pipe, MRB_ARGS_NONE()); #endif |
