port test/unit/test_ccc.rb to Perl 5
[unicorn.git] / lib / unicorn / launcher.rb
blobbd3324e95b7a13fdebe00e5fe4ab1d5660951f3e
1 # -*- encoding: binary -*-
2 # frozen_string_literal: false
4 # :enddoc:
5 $stdout.sync = $stderr.sync = true
6 $stdin.binmode
7 $stdout.binmode
8 $stderr.binmode
10 require 'unicorn'
12 module Unicorn::Launcher
14   # We don't do a lot of standard daemonization stuff:
15   #   * umask is whatever was set by the parent process at startup
16   #     and can be set in config.ru and config_file, so making it
17   #     0000 and potentially exposing sensitive log data can be bad
18   #     policy.
19   #   * don't bother to chdir("/") here since unicorn is designed to
20   #     run inside APP_ROOT.  Unicorn will also re-chdir() to
21   #     the directory it was started in when being re-executed
22   #     to pickup code changes if the original deployment directory
23   #     is a symlink or otherwise got replaced.
24   def self.daemonize!(options)
25     cfg = Unicorn::Configurator
26     $stdin.reopen("/dev/null")
28     # We only start a new process group if we're not being reexecuted
29     # and inheriting file descriptors from our parent
30     unless ENV['UNICORN_FD']
31       # grandparent - reads pipe, exits when master is ready
32       #  \_ parent  - exits immediately ASAP
33       #      \_ unicorn master - writes to pipe when ready
35       rd, wr = Unicorn.pipe
36       grandparent = $$
37       if fork
38         wr.close # grandparent does not write
39       else
40         rd.close # unicorn master does not read
41         Process.setsid
42         exit if fork # parent dies now
43       end
45       if grandparent == $$
46         # this will block until HttpServer#join runs (or it dies)
47         master_pid = (rd.readpartial(16) rescue nil).to_i
48         unless master_pid > 1
49           warn "master failed to start, check stderr log for details"
50           exit!(1)
51         end
52         exit 0
53       else # unicorn master process
54         options[:ready_pipe] = wr
55       end
56     end
57     # $stderr/$stderr can/will be redirected separately in the Unicorn config
58     cfg::DEFAULTS[:stderr_path] ||= "/dev/null"
59     cfg::DEFAULTS[:stdout_path] ||= "/dev/null"
60     cfg::RACKUP[:daemonized] = true
61   end
63 end