4: def popen3(*cmd)
5: pw = IO::pipe
6: pr = IO::pipe
7: pe = IO::pipe
8:
9: pid = fork{
10:
11: fork{
12:
13: pw[1].close
14: STDIN.reopen(pw[0])
15: pw[0].close
16:
17: pr[0].close
18: STDOUT.reopen(pr[1])
19: pr[1].close
20:
21: pe[0].close
22: STDERR.reopen(pe[1])
23: pe[1].close
24:
25: exec(*cmd)
26: }
27: exit!(0)
28: }
29:
30: pw[0].close
31: pr[1].close
32: pe[1].close
33: Process.waitpid(pid)
34: pi = [pw[1], pr[0], pe[0]]
35: pw[1].sync = true
36: if defined? yield
37: begin
38: return yield(*pi)
39: ensure
40: Process.detach(pid) if pid
41: pi.each { |p| p.close unless p.closed? }
42: end
43: end
44: pi
45: end