Class: LiveConsole
- Inherits:
-
Object
- Object
- LiveConsole
- 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 or Unix Domain Socket path, 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.
Defined Under Namespace
Modules: IOMethods
Instance Attribute Summary collapse
-
#bind ⇒ Object
Returns the value of attribute bind.
-
#io ⇒ Object
readonly
Returns the value of attribute io.
-
#io_method ⇒ Object
readonly
Returns the value of attribute io_method.
-
#thread ⇒ Object
readonly
Returns the value of attribute thread.
Instance Method Summary collapse
-
#initialize(io_method, opts = {}) ⇒ LiveConsole
constructor
call-seq: # Bind a LiveConsole to localhost:3030 (only allow clients on this # machine to connect): LiveConsole.new :socket, :port => 3030 # Accept connections from anywhere on port 3030.
-
#restart ⇒ Object
Restarts.
-
#start ⇒ Object
LiveConsole#start spawns a thread to listen for, accept, and provide an IRB console to new connections.
-
#stop ⇒ Object
Ends the running thread, if it exists.
Constructor Details
#initialize(io_method, opts = {}) ⇒ LiveConsole
call-seq: # Bind a LiveConsole to localhost:3030 (only allow clients on this # machine to connect): LiveConsole.new :socket, :port => 3030 # Accept connections from anywhere on port 3030. Ridiculously insecure: LiveConsole.new(:socket, :port => 3030, :host => ‘0.0.0.0’) # Use a Unix Domain Socket (which is more secure) instead: LiveConsole.new(:unix_socket, :path => ‘/tmp/my_liveconsole.sock’,
:mode => 0600, :uid => Process.uid, :gid => Process.gid)
# By default, the mode is 0600, and the uid and gid are those of the # current process. These three options are for the file’s permissions. # You can also supply a binding for IRB’s toplevel: LiveConsole.new(:unix_socket, :path => “/tmp/live_console_#Process.pid.sock”, :bind => binding)
Creates a new LiveConsole. You must next call LiveConsole#start when you want to spawn the thread to accept connections and start the console.
41 42 43 44 45 46 47 48 49 |
# File 'lib/live_console.rb', line 41 def initialize(io_method, opts = {}) self.io_method = io_method.to_sym self.bind = opts.delete :bind unless IOMethods::List.include?(self.io_method) raise ArgumentError, "Unknown IO method: #{io_method}" end init_io opts end |
Instance Attribute Details
#bind ⇒ Object
Returns the value of attribute bind.
21 22 23 |
# File 'lib/live_console.rb', line 21 def bind @bind end |
#io ⇒ Object
Returns the value of attribute io.
21 22 23 |
# File 'lib/live_console.rb', line 21 def io @io end |
#io_method ⇒ Object
Returns the value of attribute io_method.
21 22 23 |
# File 'lib/live_console.rb', line 21 def io_method @io_method end |
#thread ⇒ Object
Returns the value of attribute thread.
21 22 23 |
# File 'lib/live_console.rb', line 21 def thread @thread end |
Instance Method Details
#restart ⇒ Object
Restarts. Useful for binding changes. Return value is the same as for LiveConsole#start.
102 103 104 105 106 107 108 109 |
# File 'lib/live_console.rb', line 102 def restart r = lambda { stop; start } if thread == Thread.current Thread.new &r # Leaks a thread, but works. else r.call end end |
#start ⇒ Object
LiveConsole#start 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.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/live_console.rb', line 54 def start if thread if thread.alive? return false else thread.join self.thread = nil end end self.thread = Thread.new { loop { Thread.pass if io.start irb_io = GenericIOMethod.new io.raw_input, io.raw_output begin IRB.start_with_io(irb_io, bind) rescue Errno::EPIPE => e io.stop end end } } thread end |
#stop ⇒ Object
Ends the running thread, if it exists. Returns true if a thread was running, false otherwise.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/live_console.rb', line 82 def stop if thread if thread == Thread.current self.thread = nil Thread.current.exit! end thread.exit if thread.join(0.1).nil? thread.exit! end self.thread = nil true else false end end |