From 6ab27beeda3b0aaaa66f7cc4f734944a7aa84385 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 11 Aug 2011 12:59:09 -0700 Subject: future-proof against close-on-exec by default Setting the close-on-exec flag by default and closing non-standard descriptors is proposed for Ruby 1.9.4/2.0.0. Since Unicorn is one of the few apps to rely on FD inheritance across exec(), we need to workaround this by redirecting each listener FD to itself for Kernel#exec. Ruby supports a hash as the final argument to Kernel#exec since at least 1.9.1 (nobody cares for 1.9.0 anymore). This allows users to backport close-on-exec by default patches to older 1.9.x installs without breaking anything. ref: http://redmine.ruby-lang.org/issues/5041 --- lib/unicorn/http_server.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index 565f132..3d23d12 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -408,14 +408,14 @@ class Unicorn::HttpServer end self.reexec_pid = fork do - listener_fds = LISTENERS.map do |sock| + listener_fds = Hash[LISTENERS.map do |sock| # IO#close_on_exec= will be available on any future version of # Ruby that sets FD_CLOEXEC by default on new file descriptors # ref: http://redmine.ruby-lang.org/issues/5041 sock.close_on_exec = false if sock.respond_to?(:close_on_exec=) - sock.fileno - end - ENV['UNICORN_FD'] = listener_fds.join(',') + [ sock.fileno, sock.fileno ] + end] + ENV['UNICORN_FD'] = listener_fds.keys.join(',') Dir.chdir(START_CTX[:cwd]) cmd = [ START_CTX[0] ].concat(START_CTX[:argv]) @@ -428,6 +428,10 @@ class Unicorn::HttpServer IO_PURGATORY << io io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) end + + # exec(command, hash) works in at least 1.9.1+, but will only be + # required in 1.9.4/2.0.0 at earliest. + cmd << listener_fds if RUBY_VERSION >= "1.9.1" logger.info "executing #{cmd.inspect} (in #{Dir.pwd})" before_exec.call(self) exec(*cmd) -- cgit v1.2.3-24-ge0c7