stager/lib/vcap/stager/process_runner.rb
def run(cmd, opts = {})
    pipes = [IO.pipe, IO.pipe]

    child_pid = Process.spawn(cmd, :out => pipes[0][1], :err => pipes[1][1])

    # Only need the read side in parent
    pipes.each { |ios| ios[1].close }

    child_stdout, child_stderr = pipes[0][0], pipes[1][0]

    timeout = opts[:timeout] ? Float(opts[:timeout]) : nil

    # Holds data read thus far
    child_stdio_bufs = {
      child_stdout => "",
      child_stderr => "",
    }

    active = nil
    watched = child_stdio_bufs.keys
    start = Time.now

    while !watched.empty? &&
        (active = IO.select(watched, nil, watched, timeout))
      active.flatten.each do |io|
        begin
          child_stdio_bufs[io] << io.read_nonblock(MAX_READLEN)
        rescue IO::WaitReadable
          # Wait for more data
        rescue EOFError
          watched.delete(io)
        end
      end

      if timeout
        now = Time.now
        timeout -= now - start
        start = now
      end
    end

    ret = {
      :stdout    => child_stdio_bufs[child_stdout],
      :stderr    => child_stdio_bufs[child_stderr],
      :timed_out => active.nil?,
      :status    => nil,
    }

    Process.kill("KILL", child_pid) if ret[:timed_out]

    Process.waitpid(child_pid)

    ret[:status] = $?

    ret
  ensure
    pipes.each do |ios|
      ios.each { |io| io.close unless io.closed? }
    end
  end
# Runs a command and captures stdout/stderr/status
#
# @param [String] cmd  The command to run.
# @param [Hash]   opts
# @option opts [Integer] :timeout  How long the process is allowed to run for
#
# @return [Hash]  A hash with the following keys:
#                 :stdout    => String
#                 :stderr    => String
#                 :timed_out => Boolean
#                 :status    => Process::Status
Runs a command and captures stdout/stderr/status
Runs a command and captures stdout / stderr / status
def run(cmd, opts = {})
    pipes = [IO.pipe, IO.pipe]
    child_pid = Process.spawn(cmd, :out => pipes[0][1], :err => pipes[1][1])
    pipes.each { |ios| ios[1].close }
    child_stdout, child_stderr = pipes[0][0], pipes[1][0]
    timeout = opts[:timeout] ? Float(opts[:timeout]) : nil
    child_stdio_bufs = {
      child_stdout => "",
      child_stderr => "",
    }
    active = nil
    watched = child_stdio_bufs.keys
    start = Time.now
    while !watched.empty? &&
        (active = IO.select(watched, nil, watched, timeout))
      active.flatten.each do |io|
        begin
          child_stdio_bufs[io] << io.read_nonblock(MAX_READLEN)
        rescue IO::WaitReadable
        rescue EOFError
          watched.delete(io)
        end
      end
      if timeout
        now = Time.now
        timeout -= now - start
        start = now
      end
    end
    ret = {
      :stdout    => child_stdio_bufs[child_stdout],
      :stderr    => child_stdio_bufs[child_stderr],
      :timed_out => active.nil?,
      :status    => nil,
    }
    Process.kill("KILL", child_pid) if ret[:timed_out]
    Process.waitpid(child_pid)
    ret[:status] = $?
    ret
  ensure
    pipes.each do |ios|
      ios.each { |io| io.close unless io.closed? }
    end
  end
def run ( cmd , opts = { } ) pipes = [ IO . pipe , IO . pipe ] child_pid = Process . spawn ( cmd , :out => pipes [ 0 ] [ 1 ] , :err => pipes [ 1 ] [ 1 ] ) pipes . each { | ios | ios [ 1 ] . close } child_stdout , child_stderr = pipes [ 0 ] [ 0 ] , pipes [ 1 ] [ 0 ] timeout = opts [ :timeout ] ? Float ( opts [ :timeout ] ) : nil child_stdio_bufs = { child_stdout => "" , child_stderr => "" , } active = nil watched = child_stdio_bufs . keys start = Time . now while ! watched . empty? && ( active = IO . select ( watched , nil , watched , timeout ) ) active . flatten . each do | io | begin child_stdio_bufs [ io ] << io . read_nonblock ( MAX_READLEN ) rescue IO :: WaitReadable rescue EOFError watched . delete ( io ) end end if timeout now = Time . now timeout -= now - start start = now end end ret = { :stdout => child_stdio_bufs [ child_stdout ] , :stderr => child_stdio_bufs [ child_stderr ] , :timed_out => active . nil? , :status => nil , } Process . kill ( "KILL" , child_pid ) if ret [ :timed_out ] Process . waitpid ( child_pid ) ret [ :status ] = $? ret ensure pipes . each do | ios | ios . each { | io | io . close unless io . closed? } end end
Runs a command and captures stdout/stderr/status
Runs a command and captures stdout / stderr / status
# Only need the read side in parent # Holds data read thus far # Wait for more data
A hash with the following keys: :stdout => String :stderr => String :timed_out => Boolean :status => Process::Status
A hash with the following keys : : stdout = > String : stderr = > String : timed_out = > Boolean : status = > Process :: Status
Hash
cmd
opts
:timeout How long the process is allowed to run for
: timeout How long the process is allowed to run for
None