5 WRITES_PID = [:start, :restart]
7 attr_accessor :name, :uid, :gid, :log, :start, :stop, :restart
10 self.log = '/dev/null'
18 pid = File.read(self.pid_file).strip.to_i
19 System::Process.new(pid).exists?
26 # determine if we're tracking pid or not
31 # a start command must be specified
34 LOG.log(self, :error, "No start command was specified")
37 # self-daemonizing processes must specify a stop command
38 if !@tracking_pid && self.stop.nil?
40 LOG.log(self, :error, "No stop command was specified")
43 # uid must exist if specified
46 Etc.getpwnam(self.uid)
49 LOG.log(self, :error, "UID for '#{self.uid}' does not exist")
53 # gid must exist if specified
56 Etc.getgrnam(self.gid)
59 LOG.log(self, :error, "GID for '#{self.gid}' does not exist")
63 # pid dir must exist if specified
64 if self.pid_file && !File.exist?(File.dirname(self.pid_file))
66 LOG.log(self, :error, "PID file directory '#{File.dirname(self.pid_file)}' does not exist")
69 # log dir must exist if specified
70 if self.log && !File.exist?(File.dirname(self.log))
72 LOG.log(self, :error, "Log directory '#{File.dirname(self.log)}' does not exist")
78 # DON'T USE THIS INTERNALLY. Use the instance variable. -- Kev
79 # No really, trust me. Use the instance variable.
81 # if value is nil, do the right thing
92 @pid_file ||= default_pid_file
104 call_action(:restart)
110 ::Process::Sys.setgid(Etc.getgrnam(self.gid).gid) if self.gid
111 ::Process::Sys.setuid(Etc.getpwnam(self.uid).uid) if self.uid
114 STDIN.reopen "/dev/null"
115 STDOUT.reopen self.log, "a"
118 exec command unless command.empty?
122 def call_action(action)
123 command = send(action)
125 if action == :stop && command.nil?
126 pid = File.read(self.pid_file).strip.to_i
129 LOG.log(self, :info, "#{self.name} stop: default lambda killer")
131 ::Process.kill('HUP', pid) rescue nil
133 # Poll to see if it's dead
136 ::Process.kill(0, pid)
145 ::Process.kill('KILL', pid) rescue nil
149 if command.kind_of?(String)
153 # double fork god-daemonized processes
154 # we don't want to wait for them to finish
159 pid = self.spawn(command)
163 ::Process.waitpid(opid, 0)
167 # single fork self-daemonizing processes
168 # we want to wait for them to finish
169 pid = self.spawn(command)
170 ::Process.waitpid(pid, 0)
173 if @tracking_pid or (@pid_file.nil? and WRITES_PID.include?(action))
174 File.open(default_pid_file, 'w') do |f|
179 @pid_file = default_pid_file
181 elsif command.kind_of?(Proc)
185 raise NotImplementedError
190 File.join(God.pid_file_directory, "#{self.name}.pid")