diff options
| author | ksss <[email protected]> | 2016-08-07 15:58:39 +0900 |
|---|---|---|
| committer | ksss <[email protected]> | 2016-08-07 21:21:01 +0900 |
| commit | b462ef450665141a38978d5b31b5550a60db4e6b (patch) | |
| tree | aee07c67b90f27d02d40d1a61329664eb44bf188 | |
| parent | 93d481d4b49829e37b1f501c7307663c6327dfab (diff) | |
| download | mruby-b462ef450665141a38978d5b31b5550a60db4e6b.tar.gz mruby-b462ef450665141a38978d5b31b5550a60db4e6b.zip | |
Enable option :in, :out, :err
| -rw-r--r-- | mrblib/io.rb | 4 | ||||
| -rw-r--r-- | src/io.c | 13 | ||||
| -rw-r--r-- | test/io.rb | 37 |
3 files changed, 52 insertions, 2 deletions
diff --git a/mrblib/io.rb b/mrblib/io.rb index 9644c2396..7e6ed9b1d 100644 --- a/mrblib/io.rb +++ b/mrblib/io.rb @@ -26,11 +26,11 @@ class IO end end - def self.popen(command, mode = 'r', &block) + def self.popen(command, mode = 'r', opts={}, &block) if !self.respond_to?(:_popen) raise NotImplementedError, "popen is not supported on this platform" end - io = self._popen(command, mode) + io = self._popen(command, mode, opts) return io unless block begin @@ -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) { diff --git a/test/io.rb b/test/io.rb index f0f30e3ce..6e1bcb247 100644 --- a/test/io.rb +++ b/test/io.rb @@ -393,6 +393,43 @@ assert('IO.popen') do end end +assert('IO.popen with in option') do + begin + IO.pipe do |r, w| + w.write 'hello' + w.close + assert_equal "hello", IO.popen("cat", "r", in: r) { |i| i.read } + assert_equal "", r.read + end + rescue NotImplementedError => e + skip e.message + end +end + +assert('IO.popen with out option') do + begin + IO.pipe do |r, w| + IO.popen("echo 'hello'", "w", out: w) {} + w.close + assert_equal "hello\n", r.read + end + rescue NotImplementedError => e + skip e.message + end +end + +assert('IO.popen with err option') do + begin + IO.pipe do |r, w| + assert_equal "", IO.popen("echo 'hello' 1>&2", "r", err: w) { |i| i.read } + w.close + assert_equal "hello\n", r.read + end + rescue NotImplementedError => e + skip e.message + end +end + assert('IO.read') do # empty file fd = IO.sysopen $mrbtest_io_wfname, "w" |
