summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorksss <[email protected]>2016-08-07 15:58:39 +0900
committerksss <[email protected]>2016-08-07 21:21:01 +0900
commitb462ef450665141a38978d5b31b5550a60db4e6b (patch)
treeaee07c67b90f27d02d40d1a61329664eb44bf188 /src
parent93d481d4b49829e37b1f501c7307663c6327dfab (diff)
downloadmruby-b462ef450665141a38978d5b31b5550a60db4e6b.tar.gz
mruby-b462ef450665141a38978d5b31b5550a60db4e6b.zip
Enable option :in, :out, :err
Diffstat (limited to 'src')
-rw-r--r--src/io.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/io.c b/src/io.c
index 42e9a93a8..f842ceb85 100644
--- a/src/io.c
+++ b/src/io.c
@@ -270,6 +270,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
mrb_value cmd, io, result;
mrb_value mode = mrb_str_new_cstr(mrb, "r");
mrb_value opt = mrb_hash_new(mrb);
+ mrb_value opt_in, opt_out, opt_err;
struct mrb_io *fptr;
const char *pname;
@@ -315,6 +316,18 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
result = mrb_nil_value();
switch (pid = fork()) {
case 0: /* child */
+ opt_in = mrb_funcall(mrb, opt, "[]", 1, mrb_symbol_value(mrb_intern_lit(mrb, "in")));
+ opt_out = mrb_funcall(mrb, opt, "[]", 1, mrb_symbol_value(mrb_intern_lit(mrb, "out")));
+ opt_err = mrb_funcall(mrb, opt, "[]", 1, mrb_symbol_value(mrb_intern_lit(mrb, "err")));
+ if (!mrb_nil_p(opt_in)) {
+ dup2(mrb_fixnum(mrb_io_fileno(mrb, opt_in)), 0);
+ }
+ if (!mrb_nil_p(opt_out)) {
+ dup2(mrb_fixnum(mrb_io_fileno(mrb, opt_out)), 1);
+ }
+ if (!mrb_nil_p(opt_err)) {
+ dup2(mrb_fixnum(mrb_io_fileno(mrb, opt_err)), 2);
+ }
if (flags & FMODE_READABLE) {
close(pr[0]);
if (pr[1] != 1) {