lib/daemons/daemonize.rb in daemons-0.3.0 vs lib/daemons/daemonize.rb in daemons-0.4.0

- old
+ new

@@ -110,18 +110,115 @@ end end module_function :safefork + def simulate(logfile_name = nil) + # NOTE: STDOUT and STDERR will not be redirected to the logfile! + + 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 + + STDIN.reopen "/dev/null" rescue nil + end + module_function :simulate + + + def call_as_daemon(block, logfile_name = nil, oldmode = 0) + rd, wr = IO.pipe + + if tmppid = safefork + # parent + wr.close + pid = rd.read.to_i + rd.close + + Process.waitpid(tmppid) + + return pid + else + 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 + + 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 + + STDIN.reopen "/dev/null" rescue nil + + if logfile_name + begin + STDOUT.reopen logfile_name, "a" + rescue ::Exception + STDOUT.reopen "/dev/null" rescue nil + end + else + STDOUT.reopen "/dev/null" rescue nil + end + + STDERR.reopen STDOUT rescue nil + + block.call + + exit + end + end + module_function :call_as_daemon + + # This method causes the current running process to become a daemon def daemonize(logfile_name = nil, oldmode=0) 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 controlled terminal') + raise Daemons.RuntimeException.new('cannot detach from controlling terminal') end # Prevent the possibility of acquiring a controlling terminal if oldmode.zero? trap 'SIGHUP', 'IGNORE' @@ -158,10 +255,9 @@ else STDOUT.reopen "/dev/null" rescue nil end STDERR.reopen STDOUT rescue nil - return oldmode ? sess_id : 0 # Return value is mostly irrelevant end module_function :daemonize