Module: Daemonize

### Home Classes Methods

### In Files

- lib/daemons/daemonize.rb

### Methods

- ::call_as_daemon
- ::close_io
- ::daemonize
- ::redirect_io
- ::safefork
- ::simulate

### Files

- README
- Releases
- TODO

### Class/Module Index

Quicksearch

- Daemons
- Daemons::Application
- Daemons::ApplicationGroup
- Daemons::CmdException
- Daemons::Controller
- Daemons::Error
- Daemons::Exception
- Daemons::Monitor
- Daemons::Optparse
- Daemons::Pid
- Daemons::PidFile
- Daemons::PidMem
- Daemons::RuntimeException
- Daemons::SystemError
- CurrentProcess
- Daemonize
- Object

No matching classes.

# Daemonize

### Public Class Methods

call_as_daemon(block, logfile_name = nil, app_name = nil) click to toggle source

Call a given block as a daemon

    # File lib/daemons/daemonize.rb, line 39
    def call_as_daemon(block, logfile_name = nil, app_name = nil)
      # we use a pipe to return the PID of the daemon
      rd, wr = IO.pipe

      if tmppid = safefork
        # in the parent

        wr.close
        pid = rd.read.to_i
        rd.close

        Process.waitpid(tmppid)

        return pid
      else
        # in the 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
        trap 'SIGHUP', 'IGNORE'
        exit if pid = safefork

        wr.write Process.pid
        wr.close

        $0 = app_name if app_name

        # Release old working directory
        Dir.chdir "/"

        close_io()

        redirect_io(logfile_name)

        # Split rand streams between spawning and daemonized process
        srand

        block.call

        exit
      end
    end

close_io() click to toggle source

    # File lib/daemons/daemonize.rb, line 121
    def close_io()
      # Make sure all input/output streams are closed
      # Part I: close all IO objects (except for STDIN/STDOUT/STDERR)
      ObjectSpace.each_object(IO) do |io|
        unless [STDIN, STDOUT, STDERR].include?(io)
          begin
            unless io.closed?
              io.close
            end
          rescue ::Exception
          end
        end
      end

      # Make sure all input/output streams are closed
      # Part II: close all file decriptors (except for STDIN/STDOUT/STDERR)
      ios = Array.new(8192) {|i| IO.for_fd(i) rescue nil}.compact
      ios.each do |io|
        next if io.fileno < 3
        io.close
      end
    end

daemonize(logfile_name = nil, app_name = nil) click to toggle source

Transform the current process into a daemon

    # File lib/daemons/daemonize.rb, line 91
    def daemonize(logfile_name = nil, app_name = nil)
      # Fork and exit from the parent
      safefork and exit

      # 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
      trap 'SIGHUP', 'IGNORE'
      exit if pid = safefork

      $0 = app_name if app_name

      # Release old working directory
      Dir.chdir "/"

      close_io()

      redirect_io(logfile_name)

      # Split rand streams between spawning and daemonized process
      srand

      return sess_id
    end

redirect_io(logfile_name) click to toggle source

Free STDIN/STDOUT/STDERR file descriptors and point them somewhere sensible

    # File lib/daemons/daemonize.rb, line 148
    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

safefork() click to toggle source

Try to fork if at all possible retrying every 5 sec if the maximum process limit for the system has been reached

    # File lib/daemons/daemonize.rb, line 5
    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

simulate(logfile_name = nil) click to toggle source

Simulate the daemonization process (:ontop mode) NOTE: STDOUT and STDERR will not be redirected to the logfile, because in :ontop mode, we normally want to see the output

    # File lib/daemons/daemonize.rb, line 26
    def simulate(logfile_name = nil)
      # Release old working directory
      Dir.chdir "/"

      close_io()

      # Free STDIN and point them somewhere sensible
      begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.