PHP Classes
Icontem

File: Daemon.class.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Michal Golebiowski  >  Daemon  >  Daemon.class.php  
File: Daemon.class.php
Role: Class source
Content type: text/plain
Description: Daemon base class
Class: Daemon
Create and control Unix daemon processes
 

Contents

Class file image Download
<?php
/**
 * @package binarychoice.system.unix
 * @since 1.0.3
 */

// Log message levels
define('DLOG_TO_CONSOLE'1);
define('DLOG_NOTICE'2);
define('DLOG_WARNING'4);
define('DLOG_ERROR'8);
define('DLOG_CRITICAL'16);

/**
 * Daemon base class
 *
 * Requirements:
 * Unix like operating system
 * PHP 4 >= 4.3.0 or PHP 5
 * PHP compiled with:
 * --enable-sigchild
 * --enable-pcntl
 *
 * @package binarychoice.system.unix
 * @author Michal 'Seth' Golebiowski <seth at binarychoice dot pl>
 * @copyright Copyright 2005 Seth
 * @since 1.0.3
 */
class Daemon
{
   
/**#@+
    * @access public
    */
   /**
    * User ID
    * 
    * @var int
    * @since 1.0
    */
   
var $userID 99;

   
/**
    * Group ID
    * 
    * @var integer
    * @since 1.0
    */
   
var $groupID 99;
   
   
/**
    * Terminate daemon when set identity failure ?
    * 
    * @var bool
    * @since 1.0.3
    */
   
var $requireSetIdentity false;

   
/**
    * Path to PID file
    * 
    * @var string
    * @since 1.0.1
    */
   
var $pidFileLocation '/tmp/daemon.pid';

   
/**
    * Home path
    * 
    * @var string
    * @since 1.0
    */
   
var $homePath '/';
   
/**#@-*/


   /**#@+
    * @access protected
    */
   /**
    * Current process ID
    * 
    * @var int
    * @since 1.0
    */
   
var $_pid 0;

   
/**
    * Is this process a children
    * 
    * @var boolean
    * @since 1.0
    */
   
var $_isChildren false;

   
/**
    * Is daemon running
    * 
    * @var boolean
    * @since 1.0
    */
   
var $_isRunning false;
   
/**#@-*/


   /**
    * Constructor
    *
    * @access public
    * @since 1.0
    * @return void
    */
   
function Daemon()
   {
      
error_reporting(0);
      
set_time_limit(0);
      
ob_implicit_flush();

      
register_shutdown_function(array(&$this'releaseDaemon'));
   }

   
/**
    * Starts daemon
    *
    * @access public
    * @since 1.0
    * @return bool
    */
   
function start()
   {
      
$this->_logMessage('Starting daemon');

      if (!
$this->_daemonize())
      {
         
$this->_logMessage('Could not start daemon'DLOG_ERROR);

         return 
false;
      }


      
$this->_logMessage('Running...');

      
$this->_isRunning true;


      while (
$this->_isRunning)
      {
         
$this->_doTask();
      }

      return 
true;
   }

   
/**
    * Stops daemon
    *
    * @access public
    * @since 1.0
    * @return void
    */
   
function stop()
   {
      
$this->_logMessage('Stoping daemon');

      
$this->_isRunning false;
   }

   
/**
    * Do task
    *
    * @access protected
    * @since 1.0
    * @return void
    */
   
function _doTask()
   {
          
// override this method
   
}

   
/**
    * Logs message
    *
    * @access protected
    * @since 1.0
    * @return void
    */
   
function _logMessage($msg$level DLOG_NOTICE)
   {
         
// override this method
   
}

   
/**
    * Daemonize
    *
    * Several rules or characteristics that most daemons possess:
    * 1) Check is daemon already running
    * 2) Fork child process
    * 3) Sets identity
    * 4) Make current process a session laeder
    * 5) Write process ID to file
    * 6) Change home path
    * 7) umask(0)
    * 
    * @access private
    * @since 1.0
    * @return void
    */
   
function _daemonize()
   {
      
ob_end_flush();

      if (
$this->_isDaemonRunning())
      {
         
// Deamon is already running. Exiting
         
return false;
      }

      if (!
$this->_fork())
      {
         
// Coudn't fork. Exiting.
         
return false;
      }

      if (!
$this->_setIdentity() && $this->requireSetIdentity)
      {
         
// Required identity set failed. Exiting
         
return false;
      }

      if (!
posix_setsid())
      {
         
$this->_logMessage('Could not make the current process a session leader'DLOG_ERROR);

         return 
false;
      }

      if (!
$fp = @fopen($this->pidFileLocation'w'))
      {
         
$this->_logMessage('Could not write to PID file'DLOG_ERROR);

         return 
false;
      }
      else
      {
         
fputs($fp$this->_pid);
         
fclose($fp);
      }

      @
chdir($this->homePath);
      
umask(0);

      declare(
ticks 1);

      
pcntl_signal(SIGCHLD, array(&$this'sigHandler'));
      
pcntl_signal(SIGTERM, array(&$this'sigHandler'));

      return 
true;
   }

   
/**
    * Cheks is daemon already running
    *
    * @access private
    * @since 1.0.3
    * @return bool
    */
   
function _isDaemonRunning()
   {
      
$oldPid = @file_get_contents($this->pidFileLocation);

      if (
$oldPid !== false && posix_kill(trim($oldPid),0))
      {
         
$this->_logMessage('Daemon already running with PID: '.$oldPid, (DLOG_TO_CONSOLE DLOG_ERROR));

         return 
true;
      }
      else
      {
         return 
false;
      }
   }

   
/**
    * Forks process
    *
    * @access private
    * @since 1.0
    * @return bool
    */
   
function _fork()
   {
      
$this->_logMessage('Forking...');

      
$pid pcntl_fork();

      if (
$pid == -1// error
      
{
         
$this->_logMessage('Could not fork'DLOG_ERROR);

         return 
false;
      }
      else if (
$pid// parent
      
{
         
$this->_logMessage('Killing parent');

         exit();
      }
      else 
// children
      
{
         
$this->_isChildren true;
         
$this->_pid posix_getpid();

         return 
true;
      }
   }

   
/**
    * Sets identity of a daemon and returns result
    *
    * @access private
    * @since 1.0
    * @return bool
    */
   
function _setIdentity()
   {
      if (!
posix_setgid($this->groupID) || !posix_setuid($this->userID))
      {
         
$this->_logMessage('Could not set identity'DLOG_WARNING);

         return 
false;
      }
      else
      {
         return 
true;
      }
   }

   
/**
    * Signals handler
    *
    * @access public
    * @since 1.0
    * @return void
    */
   
function sigHandler($sigNo)
   {
      switch (
$sigNo)
      {
         case 
SIGTERM:   // Shutdown
            
$this->_logMessage('Shutdown signal');
            exit();
            break;

         case 
SIGCHLD:   // Halt
            
$this->_logMessage('Halt signal');
            while (
pcntl_waitpid(-1$statusWNOHANG) > 0);
            break;
      }
   }

   
/**
    * Releases daemon pid file
    * This method is called on exit (destructor like)
    *
    * @access public
    * @since 1.0
    * @return void
    */
   
function releaseDaemon()
   {
      if (
$this->_isChildren && file_exists($this->pidFileLocation))
      {
         
$this->_logMessage('Releasing daemon');

         
unlink($this->pidFileLocation);
      }
   }
}
?>

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products