Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Okay, so it almost works!

  • Loading branch information...
commit 040a1ab4063e50ed29ed7c6b74062b7c3a87d6f8 1 parent 9d41c6b
tailor authored
View
77 bin/lc-unix-socket
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby
+
+# This is the client for the unix-socket version of LiveConsole. It just talks
+# to the Unix socket, and there may already be a tool for this. I don't know,
+# I just work here.
+
+require 'socket'
+
+socket_path = ARGV.first
+if socket_path.nil?
+ $stderr.puts "You must supply a path to the socket you want to connect to."
+ exit 1
+end
+
+client = UNIXSocket.new socket_path
+
+$stdin.sync = $stdout.sync = client.sync = true
+
+read_thread =
+ Thread.new {
+ loop {
+ begin
+ Thread.pass
+ $stdout.write client.read_nonblock(1)
+ rescue Errno::EAGAIN, Errno::EINTR => e
+ IO.select [client], [], [], 1
+ rescue Errno::EOFError, Errno::EPIPE => e
+ $stderr.puts e.inspect
+ rescue Exception => e
+ $stderr.puts e.inspect
+ end
+ }
+ }
+
+st = Thread.new {
+ loop {
+ puts [
+ client.closed_read?,
+ client.closed_write?,
+ ].inspect
+ sleep 0.1
+ }
+}
+
+<<-EOSHIT
+while(l = $stdin.gets)
+ begin
+ client.print l if IO.select [], [client], [], 1
+ rescue Errno::EPIPE => e
+ puts "Other end closed."
+ break
+ end
+end
+EOSHIT
+
+Thread.new {
+ loop {
+ begin
+ l = $stdin.read_nonblock(1)
+ rescue Errno::EAGAIN
+ retry
+ end
+
+ begin
+ client.print l if IO.select [], [client], [], 1
+ rescue Errno::EPIPE => e
+ puts "Other end closed."
+ break
+ end
+ }
+}
+
+loop {
+ sleep 1
+}
+
+(Thread.list - [Thread.current]).map { |t| t.kill ; t.join }
View
38 doc/lc_unix_example.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+
+#require 'rubygems'
+require 'live_console'
+
+print <<-EOF
+This is a demo program for LiveConsole. It starts a LiveConsole on the
+specified port, and you can connect to it by using netcat or telnet to connect
+to the specified port.
+ Usage:
+ #{$0} [path_to_socket [value_for_$x]]
+The default port is 3333, and $x is set by default to nil. Run this program,
+and then in a different terminal, connect to it via netcat or telnet. You can
+check that the value of $x is exactly what you set it to, and that you're
+working inside this process, but there's not much to do inside the example
+script. :)
+
+EOF
+
+path = ARGV.first
+path = path.nil? ? "/tmp/lc_example_#{Process.uid}" : path
+$x = ARGV[1]
+
+lc = LiveConsole.new :unix_socket, :path => path
+lc.run
+
+puts "My PID is #{Process.pid}, " \
+ "I'm running on #{path}, and $x = #{$x.inspect}"
+
+oldx = $x
+loop {
+ if $x != oldx
+ puts "The time is now #{Time.now.strftime('%R:%S')}.",
+ "The value of $x changed from #{oldx.inspect} to #{$x.inspect}."
+ oldx = $x
+ end
+ sleep 1
+}
View
23 lib/live_console.rb
@@ -5,6 +5,7 @@
require 'irb'
require 'socket'
+require 'live_console_config'
# 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
@@ -16,14 +17,17 @@ class LiveConsole
include Socket::Constants
autoload :IOMethods, 'live_console/io_methods'
- attr_accessor :io_method, :io, :lc_thread
- private :io_method=, :io=, :lc_thread=
+ attr_accessor :io_method, :io, :thread
+ private :io_method=, :io=, :thread=
# call-seq:
# # Bind a LiveConsole to localhost:3030:
# LiveConsole.new :socket, :port => 3030
# # Accept connections from anywhere on port 3030. Ridiculously insecure:
- # LiveConsole.new(:socket, :port => 3030, :host => 'Your.IP.address')
+ # LiveConsole.new(:socket, :port => 3030, :host => '0.0.0.0')
+ # # More secure:
+ # LiveConsole.new(:unix_socket, :path => '/tmp/my_liveconsole.sock',
+ # :mode => 0600)
#
# Creates a new LiveConsole. You must next call LiveConsole#run when you
# want to spawn the thread to accept connections and run the console.
@@ -33,7 +37,6 @@ def initialize(io_method, opts = {})
raise ArgumentError, "Unknown IO method: #{io_method}"
end
- self.io_method
init_io opts
end
@@ -41,8 +44,8 @@ def initialize(io_method, opts = {})
# console to new connections. If a thread is already running, this method
# simply returns false; otherwise, it returns the new thread.
def run
- return false if lc_thread
- self.lc_thread = Thread.new {
+ return false if thread
+ self.thread = Thread.new {
loop {
Thread.pass
if io.start
@@ -55,15 +58,15 @@ def run
end
}
}
- lc_thread
+ thread
end
# Ends the running thread, if it exists. Returns true if a thread was
# running, false otherwise.
def stop
- if lc_thread
- lc_thread.exit
- self.lc_thread = nil
+ if thread
+ thread.exit
+ self.thread = nil
true
else
false
View
7 lib/live_console/io_methods.rb
@@ -42,5 +42,12 @@ def self.included(other)
}
}
end
+
+ def select
+ IO.select [server], [], [], 1 if server
+ end
+
+ private
+ attr_accessor :server
end
end
View
6 lib/live_console/io_methods/socket_io.rb
@@ -24,10 +24,4 @@ def stop
raw_input.close rescue nil
end
- def select
- IO.select [server], [], [], 1 if server
- end
-
- private
- attr_accessor :server
end
View
8 lib/live_console/io_methods/unix_socket_io.rb
@@ -11,10 +11,11 @@ class LiveConsole::IOMethods::UnixSocketIO
include LiveConsole::IOMethods::IOMethod
def start
- @server ||= UnixServer.new
+ @server ||= UNIXServer.new path
begin
self.raw_input = self.raw_output = server.accept_nonblock
+ raw_input.sync = true
return true
rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO,
Errno::EINTR => e
@@ -22,4 +23,9 @@ def start
retry
end
end
+
+ def stop
+ select
+ raw_input.close
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.