tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Library support for two-phase daemonization



On Thursday, at 09:23, Anthony Mallet wrote:
| 
| Or maybe just a kill(SIGHUP) to the parent?

More details: I've seen this pattern in X.org (IIRC) and I'm using this without
any issue so far:

  /* daemonize */
  if (daemonize) {
    switch(fork()) {
      case -1:
        perror("cannot fork");
        exit(2);

      case 0: /* child */ {
        int fd;

        if (setsid() == -1) exit(-1);
        if (chdir("/")) /*noop*/;

        fd = open("/dev/null", O_RDWR, 0);
        if (fd != -1) {
          (void)dup2(fd, STDIN_FILENO);
          if (fd > STDERR_FILENO)
            (void)close(fd);
        }
        signal(SIGUSR1, SIG_IGN);
      }

      default: /* parent */ {
        sigset_t sset;
        int sig = 0;

        sigemptyset(&sset);
        sigaddset(&sset, SIGUSR1);
        sigprocmask(SIG_BLOCK, &sset, NULL);
        do { sigwait(&sset, &sig); } while (sig == 0);
        assert(sig == SIGUSR1);
        _exit(0);
      }
    }
  }

  handler = signal(SIGUSR1, SIG_IGN);
  /* if SIGUSR1 is set to SIG_IGN, it was either set above or inherited from
   *  the parent (because we did not fiddle with signal handlers in the child
   *  yet). So either:
   *   - the parent really ignores it
   *   - the parent is in the 'parent' branch above
   */

  /* do initialization stuff etc ... then signal the parent */

  if (handler == SIG_IGN)
    kill(getppid(), SIGUSR1);


Home | Main Index | Thread Index | Old Index