diff --git a/io.c b/io.c index 92fe5322da..a78936488f 100644 --- a/io.c +++ b/io.c @@ -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); diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 7057e0b837..9c1836dffb 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -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