aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 14:13:20 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 14:13:20 +0000
commit52e91e0f721057d133b2020c10a3abe390fc1732 (patch)
tree7a0af9325b035ff384c9c82a16bcb53d8125aedc
parent6f39cf2d1e9677e29fefc76bc22b167b1e987624 (diff)
downloadruby-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--ChangeLog6
-rw-r--r--io.c18
-rw-r--r--test/ruby/test_process.rb55
3 files changed, 56 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 79699b72a6..0515a7f975 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/io.c b/io.c
index 20c093aa43..40ee3d435d 100644
--- a/io.c
+++ b/io.c
@@ -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")