Fragment of class DaemonImpl

Unix Daemon & Windows Service

The challenge is to write clear code that enables the application to function as a daemon on Unix and as a service on Windows. These two systems work in very different ways to achieve the same basic aim.

My solution was an interface class (Daemon), with separate implementations for Unix (class DaemonImpl) and Windows (class Service).

The interface class is used in main() as follows:

 int main(int argc, char* argv[])
 {
   // On Windows: read argc & argv values from the registry.
   Daemon daemon(argc,argv);
   
   // Read arguments.
   //  Set daemon.pidfile(), daemon.foreground() & daemon.tracefile().
   ...
   
   // Perform initial set up (prior to forking on Unix).
   ...
   
   // On Unix: fork child, write pidfile.
   // Also redirects output to tracefile
   daemon.daemonize();
   
   // Perform set up that requires us to be in the child process.
   ...
   
   // On Unix: Allow the parent process to exit.
   // On Windows: Sets the service status to 'running'.
   daemon.runningOk();
   
   // Main program loop.
   ...
   
   return 0;
 }

The core of the Unix implementation is the DaemonImpl::daemonize() method. It contains the call to fork(), writes the pidfile and redirects output streams.

The core of the Windows implementation is the Service::start() method, which is called when the wrapper class is constructed. Service::start() implements a tiny command-line service install/uninstall application, and also fools Windows into running main() as the service's main procedure.

Portfolio Multithreaded Programming Unix Daemon & Windows Service Windows Registry GNU Autoconf Documentation Web Design Java Python

2005, Alex Tingle. This work is licensed under a Creative Commons License.
Permission granted to copy but NOT TO MODIFY this document.