class TTYProcessCtl

Constants

Timeout

Attributes

exit_status[R]

Public Class Methods

new(command, options = {}) click to toggle source
# File lib/tty-process-ctl.rb, line 38
def initialize(command, options = {})
        @backlog_size = options[:backlog_size] || 4000
        @command = command

        @listeners = []
        @out_queue = Queue.new

        @r, @w, @pid = PTY.spawn(@command)
        @w.echo = false # disable echoing of commands
        @thread = Thread.start do
                begin
                        abort_on_exception = true
                        @r.each_line do |line|
                                enqueue_message line.chop
                        end
                rescue Errno::EIO
                ensure
                        @exit_status = PTY.check(@pid)
                        @r.close
                        @w.close
                        enqueue_end
                end
        end
end

Public Instance Methods

alive?() click to toggle source
# File lib/tty-process-ctl.rb, line 65
def alive?
        @thread.alive?
end
each(options = {}, &block) click to toggle source
# File lib/tty-process-ctl.rb, line 83
def each(options = {}, &block)
        return enum_for(:each, options) unless block
        listener = listener(&block)
        begin
                timeout(options[:timeout]) do
                        true while not listener.closed? and poll
                end
                self
        ensure
                # make sure we close the listener when each exits
                listener.close
        end
end
each_until(pattern, options = {}) { |message| ... } click to toggle source
# File lib/tty-process-ctl.rb, line 97
def each_until(pattern, options = {})
        return enum_for(:each_until, pattern, options) unless block_given?
        each(options) do |message|
                yield message
                break if message =~ pattern
        end
        self
end
each_until_exclude(pattern, options = {}) { |message| ... } click to toggle source
# File lib/tty-process-ctl.rb, line 106
def each_until_exclude(pattern, options = {})
        return enum_for(:each_until_exclude, pattern, options) unless block_given?
        each(options) do |message|
                break if message =~ pattern
                yield message
        end
        self
end
flush() click to toggle source
# File lib/tty-process-ctl.rb, line 137
def flush
        true while process_message_no_block
        self
end
on(regexp = nil, &callback) click to toggle source
# File lib/tty-process-ctl.rb, line 75
def on(regexp = nil, &callback)
        # return listender to user so he can close it after use
        listener do |message|
                next if regexp and message !~ regexp
                callback.call(message)
        end
end
poll(options = {}) click to toggle source
# File lib/tty-process-ctl.rb, line 125
def poll(options = {})
        timeout(options[:timeout]) do
                return process_message
        end
end
poll!(options = {}) click to toggle source
# File lib/tty-process-ctl.rb, line 131
def poll!(options = {})
        timeout(options[:timeout]) do
                true while process_message
        end
end
send_command(command) click to toggle source
# File lib/tty-process-ctl.rb, line 69
def send_command(command)
        @w.puts command
rescue Errno::EIO
        raise IOError.new("process '#{@command}' (pid: #{@pid}) not accepting input")
end
wait_exit(options = {}) click to toggle source
# File lib/tty-process-ctl.rb, line 119
def wait_exit(options = {})
        poll!(options)
        @thread.join
        self
end
wait_until(pattern, options = {}) click to toggle source
# File lib/tty-process-ctl.rb, line 115
def wait_until(pattern, options = {})
        each_until(pattern, options){}
end

Private Instance Methods

enqueue_end() click to toggle source
# File lib/tty-process-ctl.rb, line 182
def enqueue_end
        @out_queue << nil
end
enqueue_message(message) click to toggle source
# File lib/tty-process-ctl.rb, line 177
def enqueue_message(message)
        @out_queue << message
        @out_queue.pop while @out_queue.length > @backlog_size
end
listener(&block) click to toggle source
# File lib/tty-process-ctl.rb, line 152
def listener(&block)
        listener = Listener.new(&block).on_close do |listener|
                @listeners.delete(listener)
        end
        @listeners << listener
        listener
end
process_message(no_block = false) click to toggle source
# File lib/tty-process-ctl.rb, line 166
def process_message(no_block = false)
        return nil if not alive? and @out_queue.empty?
        message = @out_queue.pop(no_block)
        return nil unless message
        message.freeze
        @listeners.each do |listener|
                listener.call(message)
        end
        message
end
process_message_no_block() click to toggle source
# File lib/tty-process-ctl.rb, line 160
def process_message_no_block
        process_message(true)
rescue ThreadError
        nil
end
timeout(t) { || ... } click to toggle source
# File lib/tty-process-ctl.rb, line 144
def timeout(t)
        yield unless t

        ::Timeout::timeout(t, Timeout) do
                yield
        end
end