All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Protected Member Functions | Static Protected Member Functions
GpCoreTools::DaemonApplication Class Reference

Brief description of class still missing. More...

#include <DaemonApplication.h>

Inheritance diagram for GpCoreTools::DaemonApplication:
GpCoreTools::CoreApplication CubeDaemonApplication GpsDaemonApplication

List of all members.

Public Member Functions

const std::string & basePath () const
virtual void close ()
 DaemonApplication (int &argc, char **argv, ApplicationHelp *(*help)(), bool reportBugs=true)
void fork ()
void start ()
 ~DaemonApplication ()

Protected Member Functions

virtual void installInterruptSignals ()
virtual void parentProcessWait ()

Static Protected Member Functions

static void childInterrupted (int signum)
static void parentInterrupted (int signum)

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

GpCoreTools::DaemonApplication::DaemonApplication ( int &  argc,
char **  argv,
ApplicationHelp *(*)()  help,
bool  reportBugs = true 
)

Description of constructor still missing

References GpCoreTools::CoreApplication::checkOptionArg(), GpCoreTools::CoreApplication::exit(), and help().

    : CoreApplication(argc, argv, 0, reportBugs)
  {
    _doFork=true;
    _basePath="/var/log";

    // Check arguments
    int i, j=1;
    for(i=1; i<argc; i++) {
      const char * arg=argv[i];
      if(strcmp(arg, "-N")==0) {
        _doFork=false;
      } else if(strcmp(arg, "-b")==0) {
        checkOptionArg(i, argc, argv, true);
        _basePath=argv[i];
      } else if(strcmp(arg, "-l")==0) {
        checkOptionArg(i, argc, argv, true);
        _logFileName=argv[i];
      } else if(help && (strcmp(arg, "--help")==0 || strcmp(arg, "-help")==0 || strcmp(arg, "-h")==0)) {
        showHelp(i, argc, argv, help);
        ::exit(0);
      } else {
        argv[j++]=argv[i];
      }
    }
    if(j<argc) {
      argv[j]=0;
      argc=j;
    }

    if(_doFork) {
      checkPidFile();
    }
    checkBasePath();
    initLogFile();

    // Allocate it after initializing log
    _leds=new Leds;
  }
  {
    delete _leds;
  }

Member Function Documentation

const std::string& GpCoreTools::DaemonApplication::basePath ( ) const [inline]

Referenced by main().

{return _basePath;}
void GpCoreTools::DaemonApplication::childInterrupted ( int  signum) [static, protected]

Reimplemented in GpsDaemonApplication, and CubeDaemonApplication.

References GpCoreTools::EventLoop::mainInstance(), GpCoreTools::EventLoop::terminate(), and GpCoreTools::Log::writeNoMutex().

Referenced by installInterruptSignals().

  {
    // Do not use TRACE here because it uses a mutex which can be locked while this function
    // is called inside a signal exception.
    Log::writeNoMutex(0, "received TERM or INTERRUPT signal\n");
    EventLoop::mainInstance()->terminate();
    // Returns to default handler in case the process did not stop properly
    signal(SIGTERM, SIG_DFL);
    signal(SIGINT, SIG_DFL);
  }

Description of destructor still missing

Reimplemented from GpCoreTools::CoreApplication.

Reimplemented in GpsDaemonApplication, and CubeDaemonApplication.

References GpCoreTools::CoreApplication::applicationName(), and GpCoreTools::Log::write().

Referenced by main().

  {
    Log::write(0, "stop daemon with pid %i\n",getpid());
    remove(pidFile(applicationName()).data());
    CoreApplication::close();
  }

References GpCoreTools::CoreApplication::exit(), GpCoreTools::CoreApplication::initInternalDebugger(), parentInterrupted(), parentProcessWait(), and GpCoreTools::Log::write().

Referenced by main().

  {
    if(_doFork) {
      // Our process ID and Session ID
      pid_t pid, sid;
      pid=::fork();
      if(pid<0) { // Error, no child is created, -1 is returned to parent
        Log::write(0, "cannot fork off the parent process: %s\n", strerror(errno));
        exit(2);
      }
      // If we got a good PID, then we can exit the parent process.
      if(pid>0) {
        writePidFile(pid);
        // Eventually wait before exiting
        signal(SIGTERM, parentInterrupted);
        signal(SIGINT, parentInterrupted);
        parentProcessWait();
        ::exit(0); // Exits silently
      }
      // pid is null, hence we are in the child process
      // Change the file mode mask
      umask(0);
      // Create a new SID for the child process
      sid=setsid();
      if(sid < 0) {
        Log::write(0, "cannot create a new SID for the child process\n");
        exit(2);
      }
      initInternalDebugger();
    }
  }

Reimplemented in GpsDaemonApplication, and CubeDaemonApplication.

References childInterrupted().

Referenced by start().

  {
    signal(SIGTERM, childInterrupted);
    signal(SIGINT, childInterrupted);
  }
void GpCoreTools::DaemonApplication::parentInterrupted ( int  signum) [static, protected]

References GpCoreTools::CoreApplication::applicationName(), GpCoreTools::CoreApplication::exit(), and GpCoreTools::CoreApplication::instance().

Referenced by fork().

  {
    // Kill child process
    std::string pf=pidFile(CoreApplication::instance()->applicationName());
    FILE * fpid=fopen(pf.data(), "rt");
    if(fpid) {
      pid_t pid;
      if(fscanf(fpid, "%u\n", &pid)==1) {
        kill(pid, SIGINT);
      }
      fclose(fpid);
    }
    // Nicer output of runscript if parent process is printing messages
    printf("\n");
    exit(2);
  }
virtual void GpCoreTools::DaemonApplication::parentProcessWait ( ) [inline, protected, virtual]

Reimplemented in GpsDaemonApplication.

Referenced by fork().

{};

References installInterruptSignals(), and GpCoreTools::Log::write().

Referenced by main().

  {
    installInterruptSignals();

    Log::write(0, "start new daemon with pid %i\n",getpid());
  }

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines