5 WRITES_PID = [:start, :restart]
7 attr_accessor :name, :uid, :gid, :log, :start, :stop, :restart
15 pid = File.read(self.pid_file).strip.to_i
16 System::Process.new(pid).exists?
20 # determine if we're tracking pid or not
25 # a name must be specified
28 LOG.log(self, :error, "No name was specified")
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 # self-daemonizing processes cannot specify log
44 if !@tracking_pid && self.log
46 LOG.log(self, :error, "Self-daemonizing processes cannot specify a log file")
49 # uid must exist if specified
52 Etc.getpwnam(self.uid)
55 LOG.log(self, :error, "UID for '#{self.uid}' does not exist")
59 # gid must exist if specified
62 Etc.getgrnam(self.gid)
65 LOG.log(self, :error, "GID for '#{self.gid}' does not exist")
72 # DON'T USE THIS INTERNALLY. Use the instance variable. -- Kev
73 # No really, trust me. Use the instance variable.
82 @pid_file = default_pid_file
99 def call_action(action)
100 command = send(action)
102 if action == :stop && command.nil?
103 pid = File.read(self.pid_file).strip.to_i
106 LOG.log(self, :info, "#{self.name} stop: default lambda killer")
108 ::Process.kill('HUP', pid) rescue nil
110 # Poll to see if it's dead
113 ::Process.kill(0, pid)
122 ::Process.kill('KILL', pid) rescue nil
126 if command.kind_of?(String)
128 # fork/exec to setuid/gid
135 ::Process::Sys.setgid(Etc.getgrnam(self.gid).gid) if self.gid
136 ::Process::Sys.setuid(Etc.getpwnam(self.uid).uid) if self.uid
139 STDIN.reopen "/dev/null"
141 STDOUT.reopen self.log, "a"
143 STDOUT.reopen "/dev/null", "a"
147 exec command unless command.empty?
152 ::Process.waitpid(opid, 0)
156 if @tracking_pid or (@pid_file.nil? and WRITES_PID.include?(action))
157 File.open(default_pid_file, 'w') do |f|
162 @pid_file = default_pid_file
165 elsif command.kind_of?(Proc)
169 raise NotImplementedError
174 File.join(God.pid_file_directory, "#{self.name}.pid")