Module: RightScale

Defined in:
lib/right_popen.rb,
lib/linux/right_popen.rb

Defined Under Namespace

Modules: StdErrHandler, StdOutHandler

Class Method Summary collapse

Class Method Details

.close_all_fd(keep = []) ⇒ Object

Closes all open I/O objects in the object space, keeping any provided as arguments.

Parameters

keep(Array)

array of I/O objects to keep.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/right_popen.rb', line 41

def self.close_all_fd(keep = [])
  keep = [keep] unless keep.is_a? Array
  keep += [$stdin, $stdout, $stderr]
  keep = keep.collect { |io| io.fileno }

  ObjectSpace.each_object(IO) do |io|
    unless io.closed? || keep.include?(io.fileno)
      begin
        io.close
      rescue Exception
      #do nothing
      end
    end
  end
end

.popen3(cmd, target, stdout_handler = nil, stderr_handler = nil, exit_handler = nil) ⇒ Object

Forks process to run given command asynchronously, hooking all three standard streams of the child process.

Streams the command’s stdout and stderr to the given handlers. Time- ordering of bytes sent to stdout and stderr is not preserved.

Calls given exit handler upon command process termination, passing in the resulting Process::Status.

All handlers must be methods exposed by the given target.

Parameters

cmd(String): command to execute, including any arguments.

target(Object): object defining handler methods to be called.

stdout_handler(String): token for stdout handler method name.

stderr_handler(String): token for stderr handler method name.

exit_handler(String): token for exit handler method name.



124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/linux/right_popen.rb', line 124

def self.popen3(cmd, target, stdout_handler = nil, stderr_handler = nil, exit_handler = nil)
  raise "EventMachine reactor must be started" unless EM.reactor_running?
  EM.next_tick do
    saved_stderr = $stderr.dup
    r, w = Socket::pair(Socket::AF_LOCAL, Socket::SOCK_STREAM, 0)#IO::pipe

    $stderr.reopen w
    c = EM.attach(r, StdErrHandler, target, stderr_handler) if stderr_handler
    EM.popen(cmd, StdOutHandler, target, stdout_handler, exit_handler, c, r, w)
    # Do not close 'w', strange things happen otherwise
    # (command protocol socket gets closed during decommission) 
    $stderr.reopen saved_stderr
  end
end