Class: Babushka::Open3

Inherits:
Object show all
Defined in:
lib/babushka/popen.rb

Class Method Summary (collapse)

Class Method Details

+ (Object) popen3(cmd, opts = {}, &block)



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/babushka/popen.rb', line 3

def self.popen3 cmd, opts = {}, &block
  pipes = { :in => IO::pipe, :out => IO::pipe, :err => IO::pipe }
  near = { :in => pipes[:in][1], :out => pipes[:out][0], :err => pipes[:err][0] }
  far = { :in => pipes[:in][0], :out => pipes[:out][1], :err => pipes[:err][1] }

  pid = fork {
    reopen_pipe_for :read, pipes[:in], STDIN
    reopen_pipe_for :write, pipes[:out], STDOUT
    reopen_pipe_for :write, pipes[:err], STDERR

    Dir.chdir opts[:chdir] if opts[:chdir]
    ENV.update opts[:env] if opts[:env]

    exec(*cmd)
  }

  far.values.each(&:close)
  near.values.each {|p| p.sync = true }

  begin
    yield near[:in], near[:out], near[:err]
    Process.waitpid2(pid).last.exitstatus
  ensure
    near.values.each {|p| p.close unless p.closed? }
  end
end