tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Library support for two-phase daemonization
Anthony Mallet wrote:
> 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);
> }
Missing a "break;" here?
> 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);
I think this suffers from a similar race condition as Iain's code;
the SIGUSR1 may be delivered to the parent before it has called
sigprocmask().
--
Andreas Gustafsson, gson%gson.org@localhost
Home |
Main Index |
Thread Index |
Old Index