$NetBSD: patch-eu,v 1.1 2010/09/10 03:29:01 taca Exp $ * r26783: (Open3#popen3): use Thread.detach instead of double-fork, so that the exit status can be obtained. * r26784: (Open3#popen3): ignore trap and at_exit also when exec failed. [ruby-dev:30181] --- lib/open3.rb.orig 2009-12-14 04:28:06.000000000 +0000 +++ lib/open3.rb @@ -56,39 +56,40 @@ module Open3 pid = fork{ # child - fork{ - # grandchild - pw[1].close - STDIN.reopen(pw[0]) - pw[0].close - - pr[0].close - STDOUT.reopen(pr[1]) - pr[1].close - - pe[0].close - STDERR.reopen(pe[1]) - pe[1].close - - exec(*cmd) - } - exit!(0) + pw[1].close + STDIN.reopen(pw[0]) + pw[0].close + + pr[0].close + STDOUT.reopen(pr[1]) + pr[1].close + + pe[0].close + STDERR.reopen(pe[1]) + pe[1].close + + trap("EXIT", "DEFAULT") + at_exit {exit!(false)} + at_exit {raise($!)} + exec(*cmd) } pw[0].close pr[1].close pe[1].close - Process.waitpid(pid) + waiter = Process.detach(pid) pi = [pw[1], pr[0], pe[0]] + result = pi + [waiter] pw[1].sync = true if defined? yield begin - return yield(*pi) + return yield(*result) ensure pi.each{|p| p.close unless p.closed?} + waiter.join end end - pi + result end module_function :popen3 end