module PhusionPassenger::Utils

def self.included(klass)

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

def self.mktmpdir(prefix_suffix=nil, tmpdir=nil)

Like Dir.mktmpdir, but creates shorter filenames.
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

def self.new(filenames, termination_pipe = nil)

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

def self.opens_files?

def self.opens_files?
	return true
end

def self.passenger_tmpdir(create = true)

directory if it doesn't exist.
temporary files. If +create+ is true, then this method creates the
Returns the directory in which to store Phusion Passenger-specific
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")
		system("mkdir", "-p", "-m", "u=rwxs,g=rwx,o=rwx", "#{dir}/spawn-server")
	end
	return dir
end

def self.passenger_tmpdir=(dir)

def self.passenger_tmpdir=(dir)
	@@passenger_tmpdir = dir
end

def connect_to_server(address)

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

def generate_random_id(method)

is also a valid filename.
Generate a long, cryptographically secure random ID string, which
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

def get_socket_address_type(address)

def get_socket_address_type(address)
	if address =~ %r{^unix:.}
		return :unix
	elsif address =~ %r{^tcp://.}
		return :tcp
	else
		return :unknown
	end
end

def global_backtrace_report

or if that's not supported the backtrace for the current thread.
Returns a string which reports the backtraces for all threads,
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
			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

def install_options_as_ivars(object, options, *keys)

def install_options_as_ivars(object, options, *keys)
	keys.each do |key|
		object.instance_variable_set("@#{key}", options[key])
	end
end

def local_socket_address?(address)

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

def passenger_tmpdir(create = true)

def passenger_tmpdir(create = true)
	PhusionPassenger::Utils.passenger_tmpdir(create)
end

def print_exception(current_location, exception, destination = nil)

currently at. Usually the current class name will be enough.
+current_location+ is a string which describes where the code is

Print the given exception, including the stack trace, to STDERR.
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

def process_is_alive?(pid)

Checks whether the given process exists.
def process_is_alive?(pid)
	begin
		Process.kill(0, pid)
		return true
	rescue Errno::ESRCH
		return false
	rescue SystemCallError => e
		return true
	end
end

def require_option(hash, key)

def require_option(hash, key)
	if hash.has_key?(key)
		return hash[key]
	else
		raise ArgumentError, "Option #{key.inspect} required"
	end
end

def split_by_null_into_hash(data)

string using the null character as the delimitor.
Split the given string into an hash. Keys and values are obtained by splitting the
def split_by_null_into_hash(data)
	return PhusionPassenger::NativeSupport.split_by_null_into_hash(data)
end

def split_by_null_into_hash(data)

def split_by_null_into_hash(data)
	args = data.split(NULL, -1)
	args.pop
	return Hash[*args]
end