Class: Snailgun::Server
- Inherits:
-
Object
- Object
- Snailgun::Server
- Defined in:
- lib/snailgun/server.rb
Instance Attribute Summary collapse
-
#sockname ⇒ Object
Returns the value of attribute sockname.
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(sockname = nil) {|_self| ... } ⇒ Server
constructor
A new instance of Server.
-
#interactive! ⇒ Object
Interactive mode (start a subshell with SNAILGUN_SOCK set up, and terminate the snailgun server when the subshell exits).
- #run ⇒ Object
-
#start_ruby(args) ⇒ Object
Process the received ruby command line.
Constructor Details
#initialize(sockname = nil) {|_self| ... } ⇒ Server
Returns a new instance of Server.
20 21 22 23 24 25 |
# File 'lib/snailgun/server.rb', line 20 def initialize(sockname = nil) @sockname = sockname || "/tmp/snailgun#{$$}" File.delete(@sockname) rescue nil @socket = UNIXServer.open(@sockname) yield self if block_given? end |
Instance Attribute Details
#sockname ⇒ Object
Returns the value of attribute sockname.
18 19 20 |
# File 'lib/snailgun/server.rb', line 18 def sockname @sockname end |
Class Method Details
.shell ⇒ Object
105 106 107 108 109 |
# File 'lib/snailgun/server.rb', line 105 def self.shell shell_opts = ENV['SNAILGUN_SHELL_OPTS'] args = shell_opts ? Shellwords.shellwords(shell_opts) : [] system(ENV['SHELL'] || 'bash', *args) end |
Instance Method Details
#interactive! ⇒ Object
Interactive mode (start a subshell with SNAILGUN_SOCK set up, and terminate the snailgun server when the subshell exits)
113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/snailgun/server.rb', line 113 def interactive! ENV['SNAILGUN_SOCK'] = @sockname pid = Process.fork { STDERR.puts "Snailgun starting on #{sockname} - 'exit' to end" run } self.class.shell Process.kill('TERM',pid) # TODO: wait a few secs for it to die, 'KILL' if required STDERR.puts "Snailgun ended" end |
#run ⇒ Object
27 28 29 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 61 62 63 64 65 66 67 68 69 |
# File 'lib/snailgun/server.rb', line 27 def run while client = @socket.accept pid = fork do rubylib = nil begin STDIN.reopen(client.recv_io) STDOUT.reopen(client.recv_io) STDERR.reopen(client.recv_io) nbytes = client.read(4).unpack("N").first args, env, cwd, pgid = Marshal.load(client.read(nbytes)) Dir.chdir(cwd) $LOAD_PATH.unshift rubylib if (rubylib = env['RUBYLIB']) begin Process.setpgid(0, pgid) rescue Errno::EPERM end exit_status = 0 $SNAILGUN_EXIT = lambda { begin client.write [exit_status].pack("C") rescue Errno::EPIPE end } #This doesn't work in 1.8.6: #Thread.new { client.read(1); Thread.main.raise Interrupt } Thread.new { client.read(1); exit 1 } start_ruby(args) rescue SystemExit => e exit_status = e.status raise # for the benefit of Test::Unit rescue Exception => e STDERR.puts "#{e}\n\t#{e.backtrace.join("\n\t")}" exit 1 ensure $LOAD_PATH.shift if rubylib end end Process.detach(pid) if pid && pid > 0 client.close end ensure File.delete(@sockname) rescue nil end |
#start_ruby(args) ⇒ Object
Process the received ruby command line. (TODO: implement more options)
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/snailgun/server.rb', line 72 def start_ruby(args) e = [] OptionParser.new do |opts| opts.on("-e EXPR") do |v| e << v end opts.on("-I DIR") do |v| $:.unshift v end opts.on("-r LIB") do |v| require v end # opts.on("-rcatch_exception") do |v| # end opts.on("-KU") do |v| $KCODE = 'u' if RUBY_VERSION < "1.9" end end.order!(args) ARGV.replace(args) if !e.empty? $0 = '-e' e.each { |expr| eval(expr, TOPLEVEL_BINDING) } elsif ARGV.empty? $0 = '-' eval(STDIN.read, TOPLEVEL_BINDING) else cmd = ARGV.shift $0 = cmd load(cmd) end end |