diff options
Diffstat (limited to 'lib/yahns/daemon.rb')
-rw-r--r-- | lib/yahns/daemon.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/yahns/daemon.rb b/lib/yahns/daemon.rb new file mode 100644 index 0000000..d12ff69 --- /dev/null +++ b/lib/yahns/daemon.rb @@ -0,0 +1,51 @@ +# -*- encoding: binary -*- +# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +module Yahns::Daemon # :nodoc: + # We don't do a lot of standard daemonization stuff: + # * umask is whatever was set by the parent process at startup + # and can be set in config.ru and config_file, so making it + # 0000 and potentially exposing sensitive log data can be bad + # policy. + # * don't bother to chdir("/") here since yahns is designed to + # run inside APP_ROOT. Yahns will also re-chdir() to + # the directory it was started in when being re-executed + # to pickup code changes if the original deployment directory + # is a symlink or otherwise got replaced. + def self.daemon(yahns_server) + $stdin.reopen("/dev/null") + + # We only start a new process group if we're not being reexecuted + # and inheriting file descriptors from our parent + unless ENV['YAHNS_FD'] + # grandparent - reads pipe, exits when master is ready + # \_ parent - exits immediately ASAP + # \_ yahns master - writes to pipe when ready + + # We cannot use Yahns::Sigevent (eventfd) here because we need + # to detect EOF on unexpected death, not just read/write + rd, wr = IO.pipe + grandparent = $$ + if fork + wr.close # grandparent does not write + else + rd.close # yahns master does not read + Process.setsid + exit if fork # parent dies now + end + + if grandparent == $$ + # this will block until Server#join runs (or it dies) + master_pid = (rd.readpartial(16) rescue nil).to_i + unless master_pid > 1 + warn "master failed to start, check stderr log for details" + exit!(1) + end + exit 0 + else # yahns master process + yahns_server.daemon_pipe = wr + end + end + # $stderr/$stderr can/will be redirected separately in the Yahns config + end +end |