module PhusionPassenger::Utils
Utility functions.
Constants
- FileSystemWatcher
Public Class Methods
included(klass)
click to toggle source
# 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
mktmpdir(prefix_suffix=nil, tmpdir=nil) { |path| ... }
click to toggle source
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
new(filenames, termination_pipe = nil)
click to toggle source
# 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
opens_files?()
click to toggle source
# File lib/phusion_passenger/utils/file_system_watcher.rb, line 69 def self.opens_files? return true end
Protected Class Methods
passenger_tmpdir(create = true)
click to toggle source
Returns the directory in which to store Phusion Passenger-specific
temporary files. If create
is true, then this method creates
the directory if it doesn't exist.
# File lib/phusion_passenger/utils/tmpdir.rb, line 37 def self.passenger_tmpdir(create = true) dir = @@passenger_tmpdir if dir.nil? || dir.empty? tmpdir = "/tmp" ["PASSENGER_TEMP_DIR", "PASSENGER_TMPDIR"].each do |name| if ENV.has_key?(name) && !ENV[name].empty? tmpdir = ENV[name] break end end dir = "#{tmpdir}/passenger.1.0.#{Process.pid}" dir.gsub!(%r{//+}, '/') @@passenger_tmpdir = dir end if create && !File.exist?(dir) # This is a very minimal implementation of the subdirectory # creation logic in ServerInstanceDir.h. This implementation # is only meant to make the unit tests pass. For production # systems one should pre-create the temp directory with # ServerInstanceDir.h. system("mkdir", "-p", "-m", "u=rwxs,g=rwx,o=rwx", dir) system("mkdir", "-p", "-m", "u=rwxs,g=rwx,o=rwx", "#{dir}/generation-0") system("mkdir", "-p", "-m", "u=rwxs,g=rwx,o=rwx", "#{dir}/backends") end return dir end
passenger_tmpdir=(dir)
click to toggle source
# File lib/phusion_passenger/utils/tmpdir.rb, line 64 def self.passenger_tmpdir=(dir) @@passenger_tmpdir = dir end
Public Instance Methods
connect_to_server(address)
click to toggle source
# File lib/phusion_passenger/utils.rb, line 102 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(%r{^tcp://}, '').split(':', 2) port = port.to_i return TCPSocket.new(host, port) else raise ArgumentError, "Unknown socket address type for '#{address}'." end end
generate_random_id(method)
click to toggle source
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
get_socket_address_type(address)
click to toggle source
# File lib/phusion_passenger/utils.rb, line 92 def get_socket_address_type(address) if address =~ %r{^unix:.} return :unix elsif address =~ %r{^tcp://.} return :tcp else return :unknown end end
global_backtrace_report()
click to toggle source
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 155 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
home_dir()
click to toggle source
# File lib/phusion_passenger/utils.rb, line 71 def home_dir Etc.getpwuid(Process.uid).dir end
install_options_as_ivars(object, options, *keys)
click to toggle source
# File lib/phusion_passenger/utils.rb, line 147 def install_options_as_ivars(object, options, *keys) keys.each do |key| object.instance_variable_set("@#{key}", options[key]) end end
local_socket_address?(address)
click to toggle source
# File lib/phusion_passenger/utils.rb, line 115 def local_socket_address?(address) case get_socket_address_type(address) when :unix return true when :tcp host, port = address.sub(%r{^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_exception(current_location, exception, destination = nil)
click to toggle source
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.
# File lib/phusion_passenger/utils.rb, line 79 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
process_is_alive?(pid)
click to toggle source
Checks whether the given process exists.
# File lib/phusion_passenger/utils.rb, line 128 def process_is_alive?(pid) begin Process.kill(0, pid) return true rescue Errno::ESRCH return false rescue SystemCallError => e return true end end
require_option(hash, key)
click to toggle source
# File lib/phusion_passenger/utils.rb, line 139 def require_option(hash, key) if hash.has_key?(key) return hash[key] else raise ArgumentError, "Option #{key.inspect} required" end end
retry_at_most(n, *exceptions) { || ... }
click to toggle source
# File lib/phusion_passenger/utils.rb, line 59 def retry_at_most(n, *exceptions) n.times do |i| begin return yield rescue *exceptions if i == n - 1 raise end end end end
Protected Instance Methods
passenger_tmpdir(create = true)
click to toggle source
# File lib/phusion_passenger/utils/tmpdir.rb, line 30 def passenger_tmpdir(create = true) PhusionPassenger::Utils.passenger_tmpdir(create) end