Class: Babushka::Open3

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

Class Method Summary collapse

Class Method Details

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


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
29
30
31
32
33
34
# File 'lib/babushka/popen.rb', line 3

def self.popen3 cmd, opts = {}, &block
  pipe_in, pipe_out, pipe_err = IO::pipe, IO::pipe, IO::pipe

  # To write to the process' STDIN, and read from its STDOUT/ERR.
  near = [pipe_in[1], pipe_out[0], pipe_err[0]]
  # The other ends, connected to the process.
  far  = [pipe_in[0], pipe_out[1], pipe_err[1]]

  pid = fork {
    reopen_pipe_for :read, pipe_in, STDIN
    reopen_pipe_for :write, pipe_out, STDOUT
    reopen_pipe_for :write, pipe_err, STDERR

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

    if opts[:chdir]
      Dir.chdir(opts[:chdir]) { exec(*cmd) }
    else
      exec(*cmd)
    end
  }

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

  begin
    yield(*near)
    Process.waitpid2(pid).last.exitstatus
  ensure
    near.each {|p| p.close unless p.closed? }
  end
end