Add support for iOS platforms that does not support `fork`; fix
MODIFY
include/mruby/common.h
include/mruby/common.h
#ifndef MRUBY_COMMON_H
#define MRUBY_COMMON_H
+#ifdef __APPLE__
+ #ifndef __TARGETCONDITIONALS__
+ #include "TargetConditionals.h"
+ #endif
+#endif
#ifdef __cplusplus
#ifdef MRB_ENABLE_CXX_ABI

MODIFY
mrbgems/mruby-io/src/io.c
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

Add support for iOS platforms that does not support `fork`; fix #4113