Skip to content

Instantly share code, notes, and snippets.

@enriclluelles
Created June 18, 2012 00:04
Show Gist options
  • Select an option

  • Save enriclluelles/2946108 to your computer and use it in GitHub Desktop.

Select an option

Save enriclluelles/2946108 to your computer and use it in GitHub Desktop.
Event machine terminal sharing
#!/usr/bin/env ruby
require 'eventmachine'
require 'pty'
class ShellServer
class HandlerWriter
def add_source(source)
@sources ||= []
@sources << source
end
def write(input)
input.gsub!(/\r\n/, "\n")
@sources.each{|h| h.send_data(input)} if @sources
end
def remove_source(source)
@sources.delete(source) if @sources
end
end
module ProcessHandler
def initialize(server)
@server = server
@data = ''
end
def notify_readable
data = @io.readpartial(1000)
@server.write(data)
STDOUT.write(data)
end
end
module ServerHandler
def initialize(server, shell)
@server = server
@shell = shell
@server.add_source(self)
end
def receive_data(data)
# data = data.gsub(%r{\r\n}, "\n")
@shell.write(data)
end
def unbind
@server.remove_source(self)
end
end
module InputHandler
def initialize(shell)
@shell = shell
end
def notify_readable
data = @io.readpartial(1000)
@shell.write(data)
end
end
def initialize(port = '3456', command = '/bin/sh')
@port = port
@command = command
@shell_writer = HandlerWriter.new
@server_writer = HandlerWriter.new
end
def start
@out, @in, @pid = PTY.spawn(@command)
EM.start_server('localhost', @port.to_i, ServerHandler, @server_writer, @in)
o = EM.watch(@out, ProcessHandler, @server_writer)
o.notify_readable = true
c = EM.watch(STDIN, InputHandler, @in)
c.notify_readable = true
end
def self.start
ShellServer.new.start
end
end
EM.run do
ShellServer.start
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment