diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-05-29 14:13:20 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-05-29 14:13:20 +0000 |
commit | 52e91e0f721057d133b2020c10a3abe390fc1732 (patch) | |
tree | 7a0af9325b035ff384c9c82a16bcb53d8125aedc | |
parent | 6f39cf2d1e9677e29fefc76bc22b167b1e987624 (diff) | |
download | ruby-52e91e0f721057d133b2020c10a3abe390fc1732.tar.gz |
* io.c (pipe_open): Close pipes when rb_execarg_fixup() raises
an exception.
(rb_execarg_fixup_v): New function.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46232 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | io.c | 18 | ||||
-rw-r--r-- | test/ruby/test_process.rb | 55 |
3 files changed, 56 insertions, 23 deletions
@@ -1,3 +1,9 @@ +Thu May 29 23:11:20 2014 Tanaka Akira <akr@fsij.org> + + * io.c (pipe_open): Close pipes when rb_execarg_fixup() raises + an exception. + (rb_execarg_fixup_v): New function. + Thu May 29 22:18:57 2014 Tanaka Akira <akr@fsij.org> * test/lib/minitest/unit.rb (capture_subprocess_io): Close fds. @@ -5870,6 +5870,13 @@ popen_exec(void *pp, char *errmsg, size_t errmsg_len) #endif static VALUE +rb_execarg_fixup_v(VALUE execarg_obj) +{ + rb_execarg_fixup(execarg_obj); + return Qnil; +} + +static VALUE pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig) { struct rb_execarg *eargp = NIL_P(execarg_obj) ? NULL : rb_execarg_get(execarg_obj); @@ -5884,6 +5891,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc char errmsg[80] = { '\0' }; #endif #if defined(HAVE_FORK) || defined(HAVE_SPAWNV) + int state; struct popen_arg arg; int e = 0; #endif @@ -5964,7 +5972,15 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc rb_sys_fail_str(prog); } if (!NIL_P(execarg_obj)) { - rb_execarg_fixup(execarg_obj); + rb_protect(rb_execarg_fixup_v, execarg_obj, &state); + if (state) { + if (0 <= arg.write_pair[0]) close(arg.write_pair[0]); + if (0 <= arg.write_pair[1]) close(arg.write_pair[1]); + if (0 <= arg.pair[0]) close(arg.pair[0]); + if (0 <= arg.pair[1]) close(arg.pair[1]); + rb_jump_tag(state); + } + # if defined(HAVE_FORK) pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg)); # else diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 3764b72a58..75657ab894 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -733,11 +733,14 @@ class TestProcess < Test::Unit::TestCase } with_pipe {|r, w| io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('me')"]) - w.close - errmsg = io.read - assert_equal("", r.read) - assert_not_equal("", errmsg) - Process.wait + begin + w.close + errmsg = io.read + assert_equal("", r.read) + assert_not_equal("", errmsg) + ensure + io.close + end } with_pipe {|r, w| errmsg = `#{RUBY} -e "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts(123)"` @@ -785,29 +788,38 @@ class TestProcess < Test::Unit::TestCase } with_pipe {|r, w| io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('me')", :close_others=>true]) - w.close - errmsg = io.read - assert_equal("", r.read) - assert_not_equal("", errmsg) - Process.wait + begin + w.close + errmsg = io.read + assert_equal("", r.read) + assert_not_equal("", errmsg) + ensure + io.close + end } with_pipe {|r, w| w.close_on_exec = false io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>false]) - w.close - errmsg = io.read - assert_equal("mo\n", r.read) - assert_equal("", errmsg) - Process.wait + begin + w.close + errmsg = io.read + assert_equal("mo\n", r.read) + assert_equal("", errmsg) + ensure + io.close + end } with_pipe {|r, w| w.close_on_exec = false io = IO.popen([RUBY, "-e", "STDERR.reopen(STDOUT); IO.new(#{w.fileno}, 'w').puts('mo')", :close_others=>nil]) - w.close - errmsg = io.read - assert_equal("mo\n", r.read) - assert_equal("", errmsg) - Process.wait + begin + w.close + errmsg = io.read + assert_equal("mo\n", r.read) + assert_equal("", errmsg) + ensure + io.close + end } } @@ -1131,8 +1143,7 @@ class TestProcess < Test::Unit::TestCase Process.wait spawn([RUBY, "poiu"], "-e", "exit 4") assert_equal(4, $?.exitstatus) - assert_equal("1", IO.popen([[RUBY, "qwerty"], "-e", "print 1"]).read) - Process.wait + assert_equal("1", IO.popen([[RUBY, "qwerty"], "-e", "print 1"]) {|f| f.read }) write_file("s", <<-"End") exec([#{RUBY.dump}, "lkjh"], "-e", "exit 5") |