ptg10805159
Section 13.6 Daemon Conventions 477
sigfillset(&mask);
if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
err_exit(err, "SIG_BLOCK error");
/*
*Create a thread to handle SIGHUP and SIGTERM.
*/
err = pthread_create(&tid, NULL, thr_fn, 0);
if (err != 0)
err_exit(err, "can’t create thread");
/*
*Proceed with the rest of the daemon.
*/
/* ... */
exit(0);
}
Figure 13.7Daemon rereading configuration files
We calldaemonizefrom Figure13.1 to initialize the daemon. When it returns, we
callalready_runningfrom Figure13.6 to ensurethat only one copy of the daemon is
running. At this point,SIGHUPis still ignored, so we need to reset the disposition to
the default behavior; otherwise, the thread callingsigwaitmay never see the signal.
We block all signals, as is recommended for multithreaded programs, and create a
thread to handle signals. The thread’s only job is to wait forSIGHUPandSIGTERM.
When it receivesSIGHUP,the thread callsrereadto reread its configuration file. When
it receivesSIGTERM,the thread logs a message and exits.
Recall from Figure10.1 that the default action forSIGHUPandSIGTERMis to
terminate the process. Because we block these signals, the daemon will not die when
one of them is sent to the process. Instead, the thread callingsigwaitwill return with
an indication that the signal has been received.
Example
Not all daemons aremultithreaded. The program in Figure13.8 shows how a single-
threaded daemon can catchSIGHUPand reread its configuration file.
#include "apue.h"
#include <syslog.h>
#include <errno.h>
extern int lockfile(int);
extern int already_running(void);
void
reread(void)
{
/* ... */