module Daemonize
def call_as_daemon(block, logfile_name = nil, app_name = nil)
def call_as_daemon(block, logfile_name = nil, app_name = nil) rd, wr = IO.pipe if tmppid = safefork # parent wr.close pid = rd.read.to_i rd.close Process.waitpid(tmppid) return pid else # child rd.close # Detach from the controlling terminal unless sess_id = Process.setsid raise Daemons.RuntimeException.new('cannot detach from controlling terminal') end # Prevent the possibility of acquiring a controlling terminal #if oldmode.zero? trap 'SIGHUP', 'IGNORE' exit if pid = safefork #end wr.write Process.pid wr.close $0 = app_name if app_name Dir.chdir "/" # Release old working directory File.umask 0000 # Insure sensible umask # Make sure all file descriptors are closed ObjectSpace.each_object(IO) do |io| unless [STDIN, STDOUT, STDERR].include?(io) begin unless io.closed? io.close end rescue ::Exception end end end ios = Array.new(8192){|i| IO.for_fd(i) rescue nil}.compact ios.each do |io| next if io.fileno < 3 io.close end redirect_io(logfile_name) block.call exit end end
def daemonize(logfile_name = nil, app_name = nil)
def daemonize(logfile_name = nil, app_name = nil) srand # Split rand streams between spawning and daemonized process safefork and exit # Fork and exit from the parent # Detach from the controlling terminal unless sess_id = Process.setsid raise Daemons.RuntimeException.new('cannot detach from controlling terminal') end # Prevent the possibility of acquiring a controlling terminal #if oldmode.zero? trap 'SIGHUP', 'IGNORE' exit if pid = safefork #end $0 = app_name if app_name Dir.chdir "/" # Release old working directory File.umask 0000 # Insure sensible umask # Make sure all file descriptors are closed ObjectSpace.each_object(IO) do |io| unless [STDIN, STDOUT, STDERR].include?(io) begin unless io.closed? io.close end rescue ::Exception end end end redirect_io(logfile_name) #return oldmode ? sess_id : 0 # Return value is mostly irrelevant return sess_id end
def redirect_io(logfile_name)
point them somewhere sensible
Free file descriptors and
def redirect_io(logfile_name) begin; STDIN.reopen "/dev/null"; rescue ::Exception; end if logfile_name begin STDOUT.reopen logfile_name, "a" File.chmod(0644, logfile_name) STDOUT.sync = true rescue ::Exception begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end end else begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end end begin; STDERR.reopen STDOUT; rescue ::Exception; end STDERR.sync = true end
def safefork
Try to fork if at all possible retrying every 5 sec if the
def safefork tryagain = true while tryagain tryagain = false begin if pid = fork return pid end rescue Errno::EWOULDBLOCK sleep 5 tryagain = true end end end
def simulate(logfile_name = nil)
def simulate(logfile_name = nil) # NOTE: STDOUT and STDERR will not be redirected to the logfile, because in :ontop mode, we normally want to see the output Dir.chdir "/" # Release old working directory File.umask 0000 # Insure sensible umask # Make sure all file descriptors are closed ObjectSpace.each_object(IO) do |io| unless [STDIN, STDOUT, STDERR].include?(io) begin unless io.closed? io.close end rescue ::Exception end end end # Free file descriptors and # point them somewhere sensible # STDOUT/STDERR should go to a logfile begin; STDIN.reopen "/dev/null"; rescue ::Exception; end end