Utility functions.
# File lib/phusion_passenger/utils.rb, line 30 def self.included(klass) # When included into another class, make sure that Utils # methods are made private. public_instance_methods(false).each do |method_name| klass.send(:private, method_name) end end
Like Dir.mktmpdir, but creates shorter filenames.
# File lib/phusion_passenger/utils/tmpio.rb, line 45 def self.mktmpdir(prefix_suffix=nil, tmpdir=nil) case prefix_suffix when nil prefix = "d" suffix = "" when String prefix = prefix_suffix suffix = "" when Array prefix = prefix_suffix[0] suffix = prefix_suffix[1] else raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}" end tmpdir ||= Dir.tmpdir begin path = "#{tmpdir}/#{prefix}#{rand(0x100000000).to_s(36)}" path << suffix Dir.mkdir(path, 0700) rescue Errno::EEXIST retry end if block_given? begin yield path ensure FileUtils.remove_entry_secure path end else path end end
# File lib/phusion_passenger/utils/file_system_watcher.rb, line 60 def self.new(filenames, termination_pipe = nil) # Default parameter values, type conversion and exception # handling in C is too much of a pain. filenames = filenames.map do |filename| filename.to_s end return _new(filenames, termination_pipe) end
# File lib/phusion_passenger/utils.rb, line 130 def connect_to_server(address) case get_socket_address_type(address) when :unix return UNIXSocket.new(address.sub(/^unix:/, '')) when :tcp host, port = address.sub(%{^tcp://}, '').split(':', 2) port = port.to_i return TCPSocket.new(host, port) else raise ArgumentError, "Unknown socket address type for '#{address}'." end end
A wrapper around Thread.new that installs a default exception handler. If an uncaught exception is encountered, it will immediately log the exception and abort the entire program.
Thread#abort_on_exception is also supposed to do that, but the problem is that it is implemented by forwarding the uncaught exception to the main thread, which may not expect that particular exception and may not handle it properly. The exception could be forwarded to the main thread during any point of the main thread's execution.
This method requires 'thread' and 'ruby_core_enhancements'. If 'debug_logging' is loaded and included in the current module, it will use that for logging.
# File lib/phusion_passenger/utils.rb, line 106 def create_thread_and_abort_on_exception(*args) Thread.new do Thread.current.abort_on_exception = true begin yield(*args) rescue SystemExit raise rescue Exception => e print_exception(nil, e) exit(1) end end end
Generate a long, cryptographically secure random ID string, which is also a valid filename.
# File lib/phusion_passenger/utils.rb, line 40 def generate_random_id(method) data = File.open("/dev/urandom", "rb") do |f| f.read(64) end case method when :base64 data = [data].pack('m') data.gsub!("\n", '') data.gsub!("+", '') data.gsub!("/", '') data.gsub!(/==$/, '') return data when :hex return data.unpack('H*')[0] else raise ArgumentError, "Invalid method #{method.inspect}" end end
# File lib/phusion_passenger/utils.rb, line 120 def get_socket_address_type(address) if address =~ %{^unix:.} return :unix elsif address =~ %{^tcp://.} return :tcp else return :unknown end end
Returns a string which reports the backtraces for all threads, or if that's not supported the backtrace for the current thread.
# File lib/phusion_passenger/utils.rb, line 183 def global_backtrace_report if Kernel.respond_to?(:caller_for_all_threads) all_thread_stacks = caller_for_all_threads elsif Thread.respond_to?(:list) && Thread.public_method_defined?(:backtrace) all_thread_stacks = {} Thread.list.each do |thread| all_thread_stacks[thread] = thread.backtrace end end output = "========== Process #{Process.pid}: backtrace dump ==========\n" if all_thread_stacks all_thread_stacks.each_pair do |thread, stack| if thread_name = thread[:name] thread_name = "(#{thread_name})" end stack ||= ["(empty)"] output << ("-" * 60) << "\n" output << "# Thread: #{thread.inspect}#{thread_name}, " if thread == Thread.main output << "[main thread], " end if thread == Thread.current output << "[current thread], " end output << "alive = #{thread.alive?}\n" output << ("-" * 60) << "\n" output << " " << stack.join("\n ") output << "\n\n" end else output << ("-" * 60) << "\n" output << "# Current thread: #{Thread.current.inspect}\n" output << ("-" * 60) << "\n" output << " " << caller.join("\n ") end return output end
# File lib/phusion_passenger/utils.rb, line 175 def install_options_as_ivars(object, options, *keys) keys.each do |key| object.instance_variable_set("@#{key}", options[key]) end end
# File lib/phusion_passenger/utils.rb, line 143 def local_socket_address?(address) case get_socket_address_type(address) when :unix return true when :tcp host, port = address.sub(%{^tcp://}, '').split(':', 2) return host == "127.0.0.1" || host == "::1" || host == "localhost" else raise ArgumentError, "Unknown socket address type for '#{address}'." end end
Print the given exception, including the stack trace, to STDERR.
current_location is a string which describes where the code is currently at. Usually the current class name will be enough. It may be nil.
This method requires 'ruby_core_enhancements'. If 'debug_logging' is loaded and included in the current module, it will use that for logging.
# File lib/phusion_passenger/utils.rb, line 80 def print_exception(current_location, exception, destination = nil) if !exception.is_a?(SystemExit) data = exception.backtrace_string(current_location) if defined?(DebugLogging) && self.is_a?(DebugLogging) error(data) else destination ||= STDERR destination.puts(data) destination.flush if destination.respond_to?(:flush) end end end
Checks whether the given process exists.
# File lib/phusion_passenger/utils.rb, line 156 def process_is_alive?(pid) begin Process.kill(0, pid) return true rescue Errno::ESRCH return false rescue SystemCallError => e return true end end
Generated with the Darkfish Rdoc Generator 2.