text: 
  /* adopted from here http://www.itp.uzh.ch/~dpotter/howto/daemonize and it is in the public domain */
  #include <stdio.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <errno.h>
  #ifndef __MINGW32__
  	#include <pwd.h>
  #endif
  #include <signal.h>
  #include <string.h>
  #include "log.h"
  
  #define EXIT_SUCCESS 0
  #define EXIT_FAILURE 1
  
  #ifndef __MINGW32__
  static void child_handler(int signum)
  {
      switch(signum) {
      case SIGALRM: exit(EXIT_FAILURE); break;
      case SIGUSR1: exit(EXIT_SUCCESS); break;
      case SIGCHLD: exit(EXIT_FAILURE); break;
      }
  }
  #endif
  
  
  void daemonize(const char *lockfile,const char* daemonuser)
  {
  #ifdef __MINGW32__
      log_error("Daemonize not supported under MINGW32!");
  #else
      pid_t pid, sid, parent;
      int lfp = -1;
  
      if ( !daemonuser ) {
          log_error("empty daemon user");
          exit(EXIT_FAILURE);
      }
  
      /* already a daemon */
      if ( getppid() == 1 ) return;
  
      /* Create the lock file as the current user */
      if ( lockfile && lockfile[0] ) {
          lfp = open(lockfile,O_RDWR|O_CREAT,0640);
          if ( lfp < 0 ) {
              log_error("unable to acquire lock file %s, code=%d (%s)", lockfile, errno, strerror(errno) );
              exit(EXIT_FAILURE);
          }
      }
  
      /* Drop user if there is one, and we were run as root */
      if ( getuid() == 0 || geteuid() == 0 ) {
          struct passwd *pw = getpwnam(daemonuser);
          if ( pw ) {
              log_debug("setting user to %s",daemonuser );
              setuid( pw->pw_uid );
          }
      }
  
      /* Trap signals that we expect to recieve */
      signal(SIGCHLD,child_handler);
      signal(SIGUSR1,child_handler);
      signal(SIGALRM,child_handler);
  
      /* Fork off the parent process */
      pid = fork();
      if (pid < 0) {
          log_error("unable to fork daemon, code=%d (%s)", errno, strerror(errno) );
          exit(EXIT_FAILURE);
      }
      /* If we got a good PID, then we can exit the parent process. */
      if (pid > 0) {
  
          /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
             for two seconds to elapse (SIGALRM).  pause() should not return. */
          alarm(2);
          pause();
  
          exit(EXIT_FAILURE);
      }
  
      /* At this point we are executing as the child process */
      parent = getppid();
  
      /* Cancel certain signals */
      signal(SIGCHLD,SIG_DFL); /* A child process dies */
      signal(SIGTSTP,SIG_IGN); /* Various TTY signals */
      signal(SIGTTOU,SIG_IGN);
      signal(SIGTTIN,SIG_IGN);
      signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */
      signal(SIGTERM,SIG_DFL); /* Die on SIGTERM */
  
      /* Change the file mode mask */
      umask(0);
  
      /* Create a new SID for the child process */
      sid = setsid();
      if (sid < 0) {
          log_error("unable to create a new session, code %d (%s)", errno, strerror(errno) );
          exit(EXIT_FAILURE);
      }
  
      /* Change the current working directory.  This prevents the current
         directory from being locked; hence not being able to remove it. */
      if ((chdir("/")) < 0) {
          log_error("unable to change directory to %s, code %d (%s)", "/", errno, strerror(errno) );
          exit(EXIT_FAILURE);
      }
  
      /* Redirect standard files to /dev/null */
      freopen( "/dev/null", "r", stdin);
      freopen( "/dev/null", "w", stdout);
      freopen( "/dev/null", "w", stderr);
  
      /* Tell the parent process that we are A-okay */
      kill( parent, SIGUSR1 );
  #endif
  }
  