22.4. Running as a Daemon
Programs that are designed to run as system daemons need to be a little careful how they become daemons to get all of the details right. Here is a list of things that should be done:
Most of the initialization work should be done before the program becomes an actual daemon. This allows any errors to be reported to the user starting the program and a meaningful exit code to be returned. This type of work includes parsing configuration files and opening sockets.
The current directory should be changed to whatever is appropriate. This is often the root directory, but it is never the directory from which the program was run. If the daemon does not do this, it may work properly, but it is preventing the directory from which it was started from being removed, as it is still a program's current directory. It is a good idea to chroot() to a directory if it is possible to do so for the reasons discussed earlier in this chapter.
Any unneeded file descriptors should be closed. This may seem obvious, but it can be easy to neglect to close file descriptors that have been inherited instead of opened by the program itself. See page 549 for information on how to do this.
The program should then call fork() and the parent process should call exit(), allowing the program that ran the daemon (often a shell) to continue.
The child process, which is continuing, should close stdin, stdout, and stderr, as it will no longer use the terminal. Rather than reuse file descriptors 0, 1, or 2, it is a good idea to open those files as /dev/null. This ensures that any library functions that report error conditions to stdout or stderr do not write those errors into other files the daemon has opened, and it allows the daemon to run external programs without worrying about their output.
To completely disassociate from the terminal from which the daemon was run, it should call setsid() to place it in its own process group. This prevents it from getting signals when the terminal is closed, as well as job-control signals.
The C library provides a daemon() function that handles some of these tasks.
int daemon(int nochdir, int noclose);
This function forks immediately, and if the fork succeeds, the parent process calls _exit() with an exit code of 0. The child process then changes to the root directory unless nochdir is nonzero and redirects stdin, stdout, and stderr to /dev/null unless noclose is nonzero. It also calls setsid() before returning to the child. This could still leave open inherited file descriptors, so programs that use daemon() should check for that. If possible, the programs should also use chroot().