[Bug #20995] Protect IO.popen block from exiting by exception

This commit is contained in:
Nobuyoshi Nakada 2025-01-02 15:50:20 +09:00
parent 6cf11ad76e
commit 8034e9c3d0
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
Notes: git 2025-01-02 08:06:34 +00:00
2 changed files with 23 additions and 9 deletions

2
io.c
View File

@ -8038,7 +8038,7 @@ popen_finish(VALUE port, VALUE klass)
if (NIL_P(port)) {
/* child */
if (rb_block_given_p()) {
rb_yield(Qnil);
rb_protect(rb_yield, Qnil, NULL);
rb_io_flush(rb_ractor_stdout());
rb_io_flush(rb_ractor_stderr());
_exit(0);

View File

@ -922,15 +922,29 @@ class TestProcess < Test::Unit::TestCase
}
end
def test_popen_fork
IO.popen("-") {|io|
if !io
puts "fooo"
else
assert_equal("fooo\n", io.read)
if Process.respond_to?(:fork)
def test_popen_fork
IO.popen("-") do |io|
if !io
puts "fooo"
else
assert_equal("fooo\n", io.read)
end
end
}
rescue NotImplementedError
end
def test_popen_fork_ensure
IO.popen("-") do |io|
if !io
STDERR.reopen(STDOUT)
raise "fooo"
else
assert_empty io.read
end
end
rescue RuntimeError
abort "[Bug #20995] should not reach here"
end
end
def test_fd_inheritance