5 WRITES_PID = [:start, :restart]
7 attr_accessor :name, :uid, :gid, :log, :start, :stop, :restart
16 pid = File.read(self.pid_file).strip.to_i
17 System::Process.new(pid).exists?
24 # determine if we're tracking pid or not
29 # a name must be specified
32 LOG.log(self, :error, "No name was specified")
35 # a start command must be specified
38 LOG.log(self, :error, "No start command was specified")
41 # self-daemonizing processes must specify a stop command
42 if !@tracking_pid && self.stop.nil?
44 LOG.log(self, :error, "No stop command was specified")
47 # self-daemonizing processes cannot specify log
48 if !@tracking_pid && self.log
50 LOG.log(self, :error, "Self-daemonizing processes cannot specify a log file")
53 # uid must exist if specified
56 Etc.getpwnam(self.uid)
59 LOG.log(self, :error, "UID for '#{self.uid}' does not exist")
63 # gid must exist if specified
66 Etc.getgrnam(self.gid)
69 LOG.log(self, :error, "GID for '#{self.gid}' does not exist")
76 # DON'T USE THIS INTERNALLY. Use the instance variable. -- Kev
77 # No really, trust me. Use the instance variable.
86 @pid_file = default_pid_file
100 call_action(:restart)
103 def call_action(action)
104 command = send(action)
106 if action == :stop && command.nil?
107 pid = File.read(self.pid_file).strip.to_i
110 LOG.log(self, :info, "#{self.name} stop: default lambda killer")
112 ::Process.kill('HUP', pid) rescue nil
114 # Poll to see if it's dead
117 ::Process.kill(0, pid)
126 ::Process.kill('KILL', pid) rescue nil
130 if command.kind_of?(String)
132 # fork/exec to setuid/gid
139 ::Process::Sys.setgid(Etc.getgrnam(self.gid).gid) if self.gid
140 ::Process::Sys.setuid(Etc.getpwnam(self.uid).uid) if self.uid
143 STDIN.reopen "/dev/null"
145 STDOUT.reopen self.log, "a"
147 STDOUT.reopen "/dev/null", "a"
151 exec command unless command.empty?
156 ::Process.waitpid(opid, 0)
160 if @tracking_pid or (@pid_file.nil? and WRITES_PID.include?(action))
161 File.open(default_pid_file, 'w') do |f|
166 @pid_file = default_pid_file
169 elsif command.kind_of?(Proc)
173 raise NotImplementedError
178 File.join(God.pid_file_directory, "#{self.name}.pid")