class Servolux::Child
def alive?
Returns +true+ if the child process is alive.
def alive? return if @io.nil? Process.kill(0, @pid) true rescue Errno::ESRCH, Errno::ENOENT false end
def initialize( command, opts = {} )
def initialize( command, opts = {} ) @command = command @timeout = opts.getopt :timeout @signals = opts.getopt :signals, %w[TERM QUIT KILL] @suspend = opts.getopt :suspend, 4 @io = @pid = @thread = @timed_out = nil end
def kill
def kill return if @io.nil? existed = false @signals.each do |sig| begin Process.kill sig, @pid existed = true rescue Errno::ESRCH, Errno::ENOENT return(existed ? nil : true) end return true unless alive? sleep @suspend return true unless alive? end return !alive? end
def start( mode = 'r', &block )
def start( mode = 'r', &block ) start_timeout_thread if @timeout @io = IO::popen @command, mode @pid = @io.pid return block.call(@io) unless block.nil? self end
def start_timeout_thread
def start_timeout_thread @timed_out = false @thread = Thread.new(self) { |child| sleep @timeout unless Thread.current[:stop] if child.alive? child.instance_variable_set(:@timed_out, true) child.__send__(:kill) end end } end
def stop
def stop unless @thread.nil? t, @thread = @thread, nil t[:stop] = true t.wakeup.join if t.status end kill if alive? @io.close rescue nil @io = @pid = nil self end
def timed_out?
Returns +true+ if the child process was killed by the timeout thread.
def timed_out? @timed_out end
def wait( flags = 0 )
information on the child process.
global variable $? is set to a Process::Status object containing
Waits for the child process to exit and returns its exit status. The
def wait( flags = 0 ) return if @io.nil? Process.wait(@pid, flags) $?.exitstatus end