I have done work several times on making a program run as a daemon under Linux.
- In one case, I've just used
daemon()
. - On another occasion, I've written my own daemon code (based on something like this) because I wanted to do more complicated redirection of STDIN, STDOUT, etc.
- I've also used the Busybox
start-stop-daemon
to start a C# Mono program as a daemon, and also generate a PID file with the-m
option.
The problem is, all of these solutions have a race condition on PID file creation, which is to say, the PID file is written by the program by its background process, some indeterminate time after the foreground process has exited. This is a problem e.g. in an embedded Linux if the program is started by an initscript, and then lastly a watchdog process is started which monitors the program is running by checking its PID file. In the C# Mono case using start-stop-daemon
, I've had such a system get rebooted occasionally at start-up by the watchdog because the program's PID file hadn't yet been written by the time the watchdog process begins monitoring (surprising as that may be that this would ever happen in a practical scenario).
How can a program be daemonized without a PID file race condition? That is, in such a way to guarantee that the PID file is fully created and written with the valid PID value when the foreground process exits.
Note, this is made a little more difficult with the Linux daemon fork-setsid-fork idiom (to prevent the daemon from acquiring a controlling tty), because the parent can't so easily get the grandchild's PID.