Class: TTYProcessCtl

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/tty-process-ctl.rb

Defined Under Namespace

Classes: Listener

Constant Summary collapse

Timeout =
Class.new(Timeout::Error)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, options = {}) ⇒ TTYProcessCtl

Returns a new instance of TTYProcessCtl.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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

Instance Attribute Details

#exit_statusObject (readonly)

Returns the value of attribute exit_status.



63
64
65
# File 'lib/tty-process-ctl.rb', line 63

def exit_status
  @exit_status
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


65
66
67
# File 'lib/tty-process-ctl.rb', line 65

def alive?
	@thread.alive?
end

#each(options = {}, &block) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
# 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 = {}) ⇒ Object



97
98
99
100
101
102
103
104
# 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 = {}) ⇒ Object



106
107
108
109
110
111
112
113
# 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

#flushObject



137
138
139
140
# File 'lib/tty-process-ctl.rb', line 137

def flush
	true while process_message_no_block
	self
end

#on(regexp = nil, &callback) ⇒ Object



75
76
77
78
79
80
81
# 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 = {}) ⇒ Object



125
126
127
128
129
# File 'lib/tty-process-ctl.rb', line 125

def poll(options = {})
	timeout(options[:timeout]) do
		return process_message
	end
end

#poll!(options = {}) ⇒ Object



131
132
133
134
135
# File 'lib/tty-process-ctl.rb', line 131

def poll!(options = {})
	timeout(options[:timeout]) do
		true while process_message
	end
end

#send_command(command) ⇒ Object



69
70
71
72
73
# 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 = {}) ⇒ Object



119
120
121
122
123
# File 'lib/tty-process-ctl.rb', line 119

def wait_exit(options = {})
	poll!(options)
	@thread.join
	self
end

#wait_until(pattern, options = {}) ⇒ Object



115
116
117
# File 'lib/tty-process-ctl.rb', line 115

def wait_until(pattern, options = {})
	each_until(pattern, options){}
end