2011-12-06 16:28:54 -05:00
|
|
|
require 'ffi'
|
|
|
|
|
|
|
|
module Puma
|
|
|
|
module JRubyRestart
|
|
|
|
extend FFI::Library
|
|
|
|
ffi_lib 'c'
|
|
|
|
|
|
|
|
attach_function :execlp, [:string, :varargs], :int
|
|
|
|
attach_function :chdir, [:string], :int
|
2013-06-19 19:16:15 -04:00
|
|
|
attach_function :fork, [], :int
|
|
|
|
attach_function :exit, [:int], :void
|
|
|
|
attach_function :setsid, [], :int
|
2011-12-06 16:28:54 -05:00
|
|
|
|
2013-03-19 01:06:16 -04:00
|
|
|
def self.chdir_exec(dir, argv)
|
2011-12-06 16:28:54 -05:00
|
|
|
chdir(dir)
|
2013-03-19 01:06:16 -04:00
|
|
|
cmd = argv.first
|
2011-12-06 16:28:54 -05:00
|
|
|
argv = ([:string] * argv.size).zip(argv).flatten
|
2013-03-19 01:06:16 -04:00
|
|
|
argv << :string
|
|
|
|
argv << nil
|
2011-12-06 16:28:54 -05:00
|
|
|
execlp(cmd, *argv)
|
|
|
|
raise SystemCallError.new(FFI.errno)
|
|
|
|
end
|
2013-06-19 19:16:15 -04:00
|
|
|
|
2013-08-13 19:05:51 -04:00
|
|
|
PermKey = 'PUMA_DAEMON_PERM'
|
|
|
|
RestartKey = 'PUMA_DAEMON_RESTART'
|
|
|
|
|
|
|
|
# Called to tell things "Your now always in daemon mode,
|
|
|
|
# don't try to reenter it."
|
|
|
|
#
|
|
|
|
def self.perm_daemonize
|
|
|
|
ENV[PermKey] = "1"
|
|
|
|
end
|
|
|
|
|
2013-06-19 19:16:15 -04:00
|
|
|
def self.daemon?
|
2013-08-13 19:05:51 -04:00
|
|
|
ENV.key?(PermKey) || ENV.key?(RestartKey)
|
2013-06-19 19:16:15 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.daemon_init
|
2013-08-13 19:05:51 -04:00
|
|
|
return true if ENV.key?(PermKey)
|
|
|
|
|
|
|
|
return false unless ENV.key? RestartKey
|
|
|
|
|
|
|
|
master = ENV[RestartKey]
|
|
|
|
|
|
|
|
# In case the master disappears early
|
|
|
|
begin
|
|
|
|
Process.kill "SIGUSR2", master.to_i
|
|
|
|
rescue SystemCallError => e
|
|
|
|
end
|
2013-06-19 19:16:15 -04:00
|
|
|
|
2013-08-13 19:05:51 -04:00
|
|
|
ENV[RestartKey] = ""
|
2013-06-19 19:16:15 -04:00
|
|
|
|
|
|
|
setsid
|
|
|
|
|
|
|
|
null = File.open "/dev/null", "w+"
|
|
|
|
STDIN.reopen null
|
|
|
|
STDOUT.reopen null
|
|
|
|
STDERR.reopen null
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.daemon_start(dir, argv)
|
|
|
|
ENV['PUMA_DAEMON_RESTART'] = Process.pid.to_s
|
|
|
|
|
2013-07-22 17:22:43 -04:00
|
|
|
if k = ENV['PUMA_JRUBY_DAEMON_OPTS']
|
|
|
|
ENV['JRUBY_OPTS'] = k
|
|
|
|
end
|
|
|
|
|
2013-06-19 19:16:15 -04:00
|
|
|
cmd = argv.first
|
|
|
|
argv = ([:string] * argv.size).zip(argv).flatten
|
|
|
|
argv << :string
|
|
|
|
argv << nil
|
|
|
|
|
|
|
|
chdir(dir)
|
|
|
|
ret = fork
|
|
|
|
return ret if ret != 0
|
|
|
|
execlp(cmd, *argv)
|
|
|
|
raise SystemCallError.new(FFI.errno)
|
|
|
|
end
|
2011-12-06 16:28:54 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|