Missing the setsid step causes child processes to set a SIGHUP when the session is exited.
Daemonization is weird and complicated under unix. To correctly daemonize the following steps should be taken in order
- explicitly set umask since the inherited umask is unknown
- call fork() and exit in the parent. This forces the child to have a process group ID which is not the same as the process id (thus ensuring we're not the process group leader).
- calls setsid() (this is now safe since we're not the process group leader). This forces us to become the PGL of a new session, and ensures we have no controlling terminal.
- At this point in highly portable programs it is typical to fork() yet again to prevent the child from being a session leader. This is known as the 'double fork daemonize' method.
- change the cwd to / to ensure that if the working directory is removed from underneath it the daemons continue to work. This also allows for the filesystem to unmounted.
- close open file descriptors (and possibly reopen 0,1,2).
In C without error checking this looks like
umask(0); int pid = fork(); if (pid != 0) exit(0); setsid(); int pid = fork(); if (pid != 0) exit(0); chdir("/"); closefrom(0); open("/dev/null", O_RDWR); dup(0); dup(0);