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