Change soft-fail to use the config, rather than env
[rbx.git] / stdlib / open3.rb
blobc4dacc9473a96afc0ae86e20d301c8c45c7b0d90
2 # = open3.rb: Popen, but with stderr, too
4 # Author:: Yukihiro Matsumoto
5 # Documentation:: Konrad Meyer
7 # Open3 gives you access to stdin, stdout, and stderr when running other
8 # programs.
12 # Open3 grants you access to stdin, stdout, and stderr when running another
13 # program. Example:
15 #   require "open3"
16 #   include Open3
17 #   
18 #   stdin, stdout, stderr = popen3('nroff -man')
20 # Open3.popen3 can also take a block which will receive stdin, stdout and
21 # stderr as parameters.  This ensures stdin, stdout and stderr are closed
22 # once the block exits. Example:
24 #   require "open3"
26 #   Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
29 module Open3
30   # 
31   # Open stdin, stdout, and stderr streams and start external executable.
32   # Non-block form:
33   #   
34   #   require 'open3'
35   #
36   #   [stdin, stdout, stderr] = Open3.popen3(cmd)
37   #
38   # Block form:
39   #
40   #   require 'open3'
41   #
42   #   Open3.popen3(cmd) { |stdin, stdout, stderr| ... }
43   #
44   # The parameter +cmd+ is passed directly to Kernel#exec.
45   #
46   def popen3(*cmd)
47     pw = IO::pipe   # pipe[0] for read, pipe[1] for write
48     pr = IO::pipe
49     pe = IO::pipe
51     pid = fork{
52       # child
53       fork{
54         # grandchild
55         pw[1].close
56         STDIN.reopen(pw[0])
57         pw[0].close
59         pr[0].close
60         STDOUT.reopen(pr[1])
61         pr[1].close
63         pe[0].close
64         STDERR.reopen(pe[1])
65         pe[1].close
67         exec(*cmd)
68       }
69       exit!(0)
70     }
72     pw[0].close
73     pr[1].close
74     pe[1].close
75     Process.waitpid(pid)
76     pi = [pw[1], pr[0], pe[0]]
77     pw[1].sync = true
78     if defined? yield
79       begin
80         return yield(*pi)
81       ensure
82         pi.each{|p| p.close unless p.closed?}
83       end
84     end
85     pi
86   end
87   module_function :popen3
88 end
90 if $0 == __FILE__
91   a = Open3.popen3("nroff -man")
92   Thread.start do
93     while line = gets
94       a[0].print line
95     end
96     a[0].close
97   end
98   while line = a[1].gets
99     print ":", line
100   end