module Closure::Popen
def self.popen(cmd)
def self.popen(cmd) if WINDOWS error = nil Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thread| yield(stdin, stdout, stderr) if block_given? stdout.read unless stdout.closed? or stdout.eof? unless stderr.closed? stderr.rewind error = stderr.read end return wait_thread.value if wait_thread.is_a? Thread end else # pipe[0] for read, pipe[1] for write pw, pr, pe = IO.pipe, IO.pipe, IO.pipe pid = fork { 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) } pw[0].close pr[1].close pe[1].close pi = [pw[1], pr[0], pe[0]] pw[1].sync = true begin yield(*pi) if block_given? ensure pi.each{|p| p.close unless p.closed?} end Process.waitpid pid end $? end