1 # -*- encoding: binary -*-
3 $stdout.sync = $stderr.sync = true
10 module Unicorn::Launcher
12 # We don't do a lot of standard daemonization stuff:
13 # * umask is whatever was set by the parent process at startup
14 # and can be set in config.ru and config_file, so making it
15 # 0000 and potentially exposing sensitive log data can be bad
17 # * don't bother to chdir("/") here since unicorn is designed to
18 # run inside APP_ROOT. Unicorn will also re-chdir() to
19 # the directory it was started in when being re-executed
20 # to pickup code changes if the original deployment directory
21 # is a symlink or otherwise got replaced.
22 def self.daemonize!(options)
23 $stdin.reopen("/dev/null")
25 # We only start a new process group if we're not being reexecuted
26 # and inheriting file descriptors from our parent
27 unless ENV['UNICORN_FD']
28 # grandparent - reads pipe, exits when master is ready
29 # \_ parent - exits immediately ASAP
30 # \_ unicorn master - writes to pipe when ready
35 wr.close # grandparent does not write
37 rd.close # unicorn master does not read
39 exit if fork # parent dies now
43 # this will block until HttpServer#join runs (or it dies)
44 master_pid = (rd.readpartial(16) rescue nil).to_i
46 warn "master failed to start, check stderr log for details"
50 else # unicorn master process
51 options[:ready_pipe] = wr
54 # $stderr/$stderr can/will be redirected separately in the Unicorn config
55 Unicorn::Configurator::DEFAULTS[:stderr_path] ||= "/dev/null"
56 Unicorn::Configurator::DEFAULTS[:stdout_path] ||= "/dev/null"
57 Unicorn::Configurator::RACKUP[:daemonized] = true