Class: LiveConsole

Inherits:
Object
  • Object
show all
Includes:
Socket::Constants
Defined in:
lib/live_console.rb

Overview

LiveConsole provides a socket that can be connected to via netcat or telnet to use to connect to an IRB session inside a running process. It creates a thread that listens on the specified address/port, and presents connecting clients with an IRB shell. Using this, you can execute code on a running instance of a Ruby process to inspect the state or even patch code on the fly. There is currently no readline support.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(listen_port, listen_addr = '127.0.0.1') ⇒ LiveConsole

call-seq: # Bind a LiveConsole to localhost:3030: LiveConsole.new 3030 # Accept connections from anywhere on port 3030. Ridiculously insecure: LiveConsole.new(3030, ‘Your.IP.address’)

Creates a new LiveConsole. You must next call LiveConsole#run when you want to spawn the thread to accept connections and run the console.



29
30
31
# File 'lib/live_console.rb', line 29

def initialize(listen_port, listen_addr = '127.0.0.1')
	self.tcp_server = TCPServer.new listen_addr, listen_port
end

Instance Attribute Details

#lc_threadObject

Returns the value of attribute lc_thread.



18
19
20
# File 'lib/live_console.rb', line 18

def lc_thread
  @lc_thread
end

#tcp_serverObject

Returns the value of attribute tcp_server.



18
19
20
# File 'lib/live_console.rb', line 18

def tcp_server
  @tcp_server
end

Instance Method Details

#init_irbObject



70
71
72
73
74
# File 'lib/live_console.rb', line 70

def init_irb
	return if @@irb_inited_already
	IRB.setup nil
	@@irb_inited_already = true
end

#runObject

LiveConsole#run spawns a thread to listen for, accept, and provide an IRB console to new connections. If a thread is already running, this method simply returns false; otherwise, it returns the new thread.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/live_console.rb', line 36

def run
	return false if lc_thread
	self.lc_thread = Thread.new { 
		loop {
			socket = nil
			begin
				Thread.pass
				socket = tcp_server.accept_nonblock
				io = SocketIOMethod.new(socket)
				IRB.start_with_io(io)
			rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
				   Errno::EINTR
				socket.close rescue nil
				IO.select([tcp_server], [], [], 1)

				retry
			end
		}
	}
	lc_thread
end

#stopObject

Ends the running thread, if it exists. Returns true if a thread was running, false otherwise.



60
61
62
63
64
65
66
67
68
# File 'lib/live_console.rb', line 60

def stop
	if lc_thread
		lc_thread.exit
		self.lc_thread = nil
		true
	else
		false
	end
end