Logo Search packages:      
Sourcecode: ldapdns version File versions  Download package

supervise.h

#ifndef __supervise_h
#define __supervise_h

#include "config.h"

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

#ifndef HAVE_SYSLOG
static void inline supervise(char *x)
{
      fatal("You probably don't want to supervise when you cannot log");
}
#else
static int supervised_pid = -1;
static int supervised_quit = 0;
static void handle_sign(int signo)
{
      if (supervised_pid != -1) {
            kill(supervised_pid, signo);
            supervised_quit = 1;
      }
}
static void inline supervise(char *x)
{
      int fd, status;
      int super_pid;
      /* GOOD DAEMON PRACTICES */

      /* do first fork */
      signal(SIGCHLD, SIG_IGN);
      switch (fork()) {
      case -1: cfatal("fork: %s");
      case 0: break;
      default: exit(0);
      };

      /* be a proper daemon */
      fd = open("/dev/null", O_RDWR);
      if (fd != 0) { close(0); dup2(fd, 0); }
      if (fd != 1) { close(1); dup2(fd, 1); }
      if (fd != 2) { close(2); dup2(fd, 2); }
      if (fd > 2) { close(fd); }

      super_pid = getpid();
#ifdef HAVE_SETSID
      /* change session ID if possible */
      (void) setsid();
#endif
      /* signore Sigpipe */
      signal(SIGPIPE, SIG_IGN);

      /* we want child notification */
      signal(SIGCHLD, SIG_DFL);

      /* setup other signals */
      signal(SIGSTOP, handle_sign);
      signal(SIGCONT, handle_sign);
      signal(SIGTERM, handle_sign);
      signal(SIGHUP, handle_sign);
      signal(SIGINT, handle_sign);

      /* do second fork */
restart_from_child_l:
      switch ((supervised_pid = fork())) {
      case -1: cfatal("fork: %s");
      case 0: /* child */ return;
      };

      /* pid file */
      if (x && *x == '/') {
            FILE *fp;

            fp = fopen(x, "w");
            fprintf(fp, "%d\n", super_pid);
            fclose(fp);
      }

wait_some_more_l:
#ifdef HAVE_WAITPID
      waitpid(supervised_pid, &status, 0);
#else
#ifdef HAVE_WAIT4
      wait4(supervised_pid, &status, 0, NULL);
#else
      while (wait(&status) != supervised_pid);
#endif
#endif
      if (kill(supervised_pid, 0) == -1) {
            sleep(1); /* go to sleep for 1 second */
            if ((volatile)supervised_quit)
                  exit(0);
            /* wasn't supposed to be dead yet... */
            goto restart_from_child_l;
      }
      supervised_quit = 0;
      goto wait_some_more_l;
}
#endif

#endif

Generated by  Doxygen 1.6.0   Back to index