class RBDaemon::Daemon
Public Class Methods
new(options = {}, *args) { |self, *args| ... }
click to toggle source
# File lib/rbdaemon/daemon.rb, line 9 def initialize(options = {}, *args) exit!(0) if fork Process.setsid Signal.trap('HUP'){} exit!(0) if fork options[:no_change_umask] or File.umask(RBDaemon::UMASK) unless options[:no_close] ObjectSpace.each_object(IO) do |io| [STDIN, STDOUT, STDERR].include?(io) and next io.closed? or io.close rescue nil end STDIN.reopen(RBDaemon::STDIO_PATH) STDOUT.reopen(RBDaemon::STDIO_PATH, 'w') STDERR.reopen(RBDaemon::STDIO_PATH, 'w') end @pid_file = PidFile.new(options[:pid_file]) unless options[:no_trap_term] Signal.trap('TERM') do exit(0) end end ident = options[:pid_file] ? options[:pid_file] : $0 ident = File.basename(ident).split(/\./)[0] at_exit do Syslog::log(Syslog::LOG_INFO, "#{ident} exited") options[:change_root] or (@pid_file and @pid_file.delete) rescue nil end if options[:user] user = options[:user] options[:groups] ||= [user] uid = user.class == String ? Etc.getpwnam(user).uid : user end if options[:groups] groups = options[:groups].map do |group| case group when Fixnum group when String Etc.getgrnam(group).gid else raise ArgumentError, 'invalid group: ' + group end end if options[:user] groups.concat(Process.initgroups(options[:user], groups[0])) end if options[:user] and groups.include?(uid) gid = uid else gid = groups[0] end Process::groups = groups.uniq Process::GID::change_privilege(gid) end Syslog::open(ident, Syslog::LOG_NDELAY | Syslog::LOG_PID, Syslog::LOG_DAEMON) if options[:change_root] Dir.chdir(options[:change_root]) Dir.chroot('.') elsif not options[:no_change_dir] Dir.chdir(RBDaemon::WORK_DIR) end Process::UID::change_privilege(uid) if options[:user] Syslog::log(Syslog::LOG_INFO, "#{ident} started") yield self, *args exit(0) end