-Daemonization helper
-====================
+Daemon helpers
+==============
+
+Daemonization
+-------------
When programs run as daemons, they frequently forget to detach themselves
from the parent environment. LibUCW therefore offers a simple daemonization
* Writing a PID file. While the daemon is running, the PID file is kept locked
by `flock()`, so we can easily detect stale PID files.
+Example
+-------
+
+ #include <ucw/lib.h>
+ #include <ucw/daemon.h>
+
+ void daemon_body(struct daemon_params *dp)
+ {
+ // ... daemon's code ...
+ // When we are done, release the PID file and exit:
+ daemon_exit(dp);
+ }
+
+ int main(int argc, char **argv)
+ {
+ struct daemon_params dp = { .pid_file = "/var/run/example.pid" };
+ // ... parse arguments ...
+ daemon_init(&dp);
+ // ... initialize everything ...
+ // Let us fork off the daemon:
+ daemon_run(daemon_body);
+ // Here continues the parent process
+ return 0;
+ }
+
+Daemon control
+--------------
+
+Daemons using the LibUCW helpers can be controlled by traditional mechanisms present
+in most UNIX-like operating systems. These are usually based on PID files, but they
+are inherently racy, since they do not perform any locking. For example, attempts to
+start the daemon, while another process is trying to stop it often lead to undefined
+states. Also, detection of running daemons fails when the daemon dies and its PID
+is recycled. Checking of process name and similar tricks do not avoid the problem,
+since there can be multiple instances of the daemon running simultaneously.
+
+We therefore recommend the following daemon control protocol, which prevents all such
+race conditions. Its implementation is available in form of the daemon_control() library
+function or the `daemon-control` stand-alone utility.
+
+* There exist two files:
+** PID file (usually `/var/run/daemon.pid`), which contains the PID of the daemon
+ process and when the daemon runs, it keeps the file locked by `flock()`.
+** Guard file (usually `/var/run/daemon.lock`), which is locked (again by `flock()`)
+ whenever we want to perform an action on the daemon.
+* When we want to start the daemon:
+** Lock the guard file, creating it if it did not exist.
+** Try to lock the PID file. If it fails, the daemon is already running, so we are done.
+** Unlock the PID file.
+** Run the daemon. The daemon locks the PID file and when it has everything initialized,
+ it forks and the parent process writes the child's PID and exits.
+** Unlock the guard file.
+* When we want to stop it:
+** Lock the guard file, creating it if it did not exist.
+** Try to lock the PID file. If it succeeds, the daemon is not running, so we are done.
+** Read the PID from the PID file.
+** Send a signal to the process. [This is the only place when we can race. The daemon could
+ have exited in the meantime and its PID could have been recycled. Hopefully, the time window
+ between checking the lock and sending the signal will be short enough. Using 32-bit PIDs
+ is advisable anyway.]
+** Lock the PID file. This will wait until the daemon finishes and releases the lock.
+** Unlock the guard file.
+* When we want to query the daemon's status:
+** Lock the guard file, creating it if it did not exist.
+** Try to lock the PID file. If it succeeds, the daemon was not running.
+** Unlock everything.
+
+ucw/daemon.h
+------------
+
!!ucw/daemon.h