lib/spring.rb in spring-0.0.3 vs lib/spring.rb in spring-0.0.4

- old
+ new

@@ -1,9 +1,8 @@ require "rbconfig" require "socket" require "pty" -require "io/console" require "spring/version" require "spring/sid" require "spring/env" require "spring/commands" @@ -14,10 +13,12 @@ "-r", "bundler/setup", "-r", "spring/server", "-e", "Spring::Server.boot" ] + FORWARDED_SIGNALS = %w(INT QUIT USR1 USR2 INFO) + def self.run(args) exit new.run(args) end attr_reader :env @@ -56,17 +57,10 @@ server = UNIXSocket.open(env.socket_name) server.send_io client server.puts rails_env_for(args.first) - status = server.read(1) - - server.close - client.close - - return false unless status == "0" - application.send_io STDOUT application.send_io STDERR application.send_io stdin_slave application.puts args.length @@ -74,17 +68,29 @@ args.each do |arg| application.puts arg.length application.write arg end - # FIXME: receive exit status from server - application.read - true + pid = server.gets.chomp + + # We must not close the client socket until we are sure that the application has + # received the FD. Otherwise the FD can end up getting closed while it's in the server + # socket buffer on OS X. This doesn't happen on Linux. + client.close + + if pid.empty? + false + else + forward_signals(pid.to_i) + application.read # FIXME: receive exit status from server + true + end rescue Errno::ECONNRESET false ensure application.close if application + server.close if server end private def rails_env_for(command_name) @@ -95,23 +101,26 @@ else ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' end end - # FIXME: need to make special chars (e.g. arrow keys) work def stdin_slave master, slave = PTY.open - master.raw! - Thread.new { - until STDIN.closed? - # This makes special chars work, but has some weird side-effects that - # I need to figure out. - # master.write STDIN.getch + # Sadly I cannot find a way to achieve this without shelling out to stty, or + # using a C extension library. [Ruby does not have direct support for calling + # tcsetattr().] We don't want to use a C extension library so + # that spring can be used by Rails in the future. + system "stty -icanon -echo" + at_exit { system "stty sane" } - master.write STDIN.read(1) - end - } + Thread.new { master.write STDIN.read(1) until STDIN.closed? } slave + end + + def forward_signals(pid) + (FORWARDED_SIGNALS & Signal.list.keys).each do |sig| + trap(sig) { Process.kill(sig, pid) } + end end end