Class: MindControl::Server
- Inherits:
-
Object
- Object
- MindControl::Server
- Includes:
- Loggable
- Defined in:
- lib/mind_control/server.rb
Overview
Listens UNIX socket and starts REPL sessions.
Instance Attribute Summary collapse
-
#repl ⇒ Object
readonly
Returns the value of attribute repl.
-
#socket_path ⇒ Object
readonly
Returns the value of attribute socket_path.
Instance Method Summary collapse
-
#get_client_id(socket) ⇒ String
Return id string for connected client.
-
#handle_client_connection(socket, client_id) ⇒ Object
Starts REPL session in separate thread for connected client.
-
#initialize(socket_path, repl) ⇒ Server
constructor
A new instance of Server.
-
#running? ⇒ Boolean
Server is running?.
-
#start ⇒ Object
Start server.
-
#start_server_loop(socket_path, &block) ⇒ Object
Starts UNIX server, accepts clients and yields its sockets in loop.
-
#stop ⇒ Object
Stop server.
Constructor Details
#initialize(socket_path, repl) ⇒ Server
Returns a new instance of Server.
23 24 25 |
# File 'lib/mind_control/server.rb', line 23 def initialize( socket_path, repl ) @socket_path, @repl = socket_path, repl end |
Instance Attribute Details
#repl ⇒ Object (readonly)
Returns the value of attribute repl.
17 18 19 |
# File 'lib/mind_control/server.rb', line 17 def repl @repl end |
#socket_path ⇒ Object (readonly)
Returns the value of attribute socket_path.
16 17 18 |
# File 'lib/mind_control/server.rb', line 16 def socket_path @socket_path end |
Instance Method Details
#get_client_id(socket) ⇒ String
Return id string for connected client.
111 112 113 114 115 116 117 118 119 |
# File 'lib/mind_control/server.rb', line 111 def get_client_id( socket ) # UNIX socket return effective UID/GID for connected client euid, _ = socket.getpeereid # Find record in /etc/passwd user_info = Etc.getpwuid euid return "#{user_info.name} (#{user_info.gecos})" end |
#handle_client_connection(socket, client_id) ⇒ Object
Starts REPL session in separate thread for connected client.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/mind_control/server.rb', line 127 def handle_client_connection( socket, client_id ) info "Starting new MindControl session for user #{client_id} ..." # Client will send us his STDIN and STDOUT client_stdin, client_stdout = socket.recv_io, socket.recv_io # Start REPL repl.start client_stdin, client_stdout info "MindControl session for user #{client_id} has ended!" rescue Exception => e = "REPL exception: #{e.} (#{e.class.name})\n#{e.backtrace.join( "\n" )}" error # Send error to client client_stdout.puts if client_stdout end |
#running? ⇒ Boolean
Server is running?
79 80 81 |
# File 'lib/mind_control/server.rb', line 79 def running? @server_thread && @server_thread.alive? end |
#start ⇒ Object
Start server.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/mind_control/server.rb', line 30 def start return if running? info "Starting MindControl server on #{socket_path} ..." # Storage for client threads client_threads = ThreadGroup.new # Start acceptor thread @server_thread = Thread.new do begin start_server_loop( socket_path ) do |client_socket| # Process client in new thread client_threads.add Thread.new { begin handle_client_connection( client_socket, get_client_id( client_socket )) ensure # We MUST close the socket client_socket.close end } end ensure # Kill all client threads on server stop client_threads.list.each( &:kill ) end end # We should known if our server has failed @server_thread.abort_on_exception = true end |
#start_server_loop(socket_path, &block) ⇒ Object
Starts UNIX server, accepts clients and yields its sockets in loop.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/mind_control/server.rb', line 89 def start_server_loop( socket_path, &block ) # Remove old file FileUtils.rm_f socket_path FileUtils.mkdir_p File.dirname( socket_path ) UNIXServer.open( socket_path ) do |server| loop do # Wait for client block.call server.accept end end ensure # Cleanup FileUtils.rm socket_path end |
#stop ⇒ Object
Stop server.
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/mind_control/server.rb', line 65 def stop return unless running? info "Stopping MindControl server ..." # Kill acceptor thread @server_thread.kill @server_thread.join @server_thread = nil end |