# File lib/phusion_passenger/abstract_server.rb, line 134 def start if started? raise ServerAlreadyStarted, "Server is already started" end a, b = UNIXSocket.pair File.unlink(@socket_filename) rescue nil server_socket = UNIXServer.new(@socket_filename) File.chmod(0700, @socket_filename) before_fork @pid = fork if @pid.nil? has_exception = false begin STDOUT.sync = true STDERR.sync = true a.close # During Passenger's early days, we used to close file descriptors based # on a white list of file descriptors. That proved to be way too fragile: # too many file descriptors are being left open even though they shouldn't # be. So now we close file descriptors based on a black list. # # Note that STDIN, STDOUT and STDERR may be temporarily set to # different file descriptors than 0, 1 and 2, e.g. in unit tests. # We don't want to close these either. file_descriptors_to_leave_open = [0, 1, 2, b.fileno, server_socket.fileno, fileno_of(STDIN), fileno_of(STDOUT), fileno_of(STDERR) ].compact.uniq NativeSupport.close_all_file_descriptors(file_descriptors_to_leave_open) # In addition to closing the file descriptors, one must also close # the associated IO objects. This is to prevent IO.close from # double-closing already closed file descriptors. close_all_io_objects_for_fds(file_descriptors_to_leave_open) # At this point, RubyGems might have open file handles for which # the associated file descriptors have just been closed. This can # result in mysterious 'EBADFD' errors. So we force RubyGems to # clear all open file handles. Gem.clear_paths # Reseed pseudo-random number generator for security reasons. srand start_synchronously(@socket_filename, @password, server_socket, b) rescue Interrupt # Do nothing. has_exception = true rescue Exception => e has_exception = true print_exception(self.class.to_s, e) ensure exit!(has_exception ? 1 : 0) end end server_socket.close b.close @owner_socket = a end