I have written a simple daemon in C, running on Linux. I'm trying to understand how to correctly setup signal masks. I have the following code in my daemon:
struct sigaction new_sig_action;
sigset_t new_sig_set;
/* Set signal mask - signals we want to block */
sigemptyset(&new_sig_set);
sigaddset(&new_sig_set, SIGCHLD); /* ignore child - i.e. we don't need to wait for it */
sigaddset(&new_sig_set, SIGTSTP); /* ignore Tty stop signals */
sigaddset(&new_sig_set, SIGTTOU); /* ignore Tty background writes */
sigaddset(&new_sig_set, SIGTTIN); /* ignore Tty background reads */
sigprocmask(SIG_BLOCK, &new_sig_set, NULL); /* Block the above specified signals */
/* Set up a signal handler */
new_sig_action.sa_handler = signal_handler;
sigemptyset(&new_sig_action.sa_mask);
new_sig_action.sa_flags = 0;
/* Signals to handle */
sigaction(SIGHUP, &new_sig_action, NULL); /* catch hangup signal */
sigaction(SIGTERM, &new_sig_action, NULL); /* catch term signal */
sigaction(SIGINT, &new_sig_action, NULL); /* catch interrupt signal */
where signal_handler is a defined function. I have a problem stopping the daemon, described in this thread.
I have now tracked the problem to the block mask being different when the daemon is started in different environments (same user, same system). Starting the daemon from the command line yields the following 'ps' output:
> ps -C powid -o pid,ppid,command,blocked,caught,ignored
PID PPID COMMAND BLOCKED CAUGHT IGNORED
11406 1 ./powid 0000000000390000 0000000180004003 0000000000000000
and when starting the exact same daemon via a PHP script, yields:
> ps -C powid -o pid,ppid,command,blocked,caught,ignored
PID PPID COMMAND BLOCKED CAUGHT IGNORED
11491 1 ./powid fffffffe3bfbe207 0000000180004003 00000000010010
My question is, why is the blocked mask different. My understanding suggests that the given C code would force the blocked mask to be the same under all conditions?
The libc documentation states:
Each process has its own signal mask. When you create a new process (see Creating a Process), it inherits its parent’s mask.
So the answer to why is the blocked mask different is because the parents used to have different masks...
Your given C code adds some signals to the block list since you use sigprocmask
with the first parameter set to SIG_BLOCK
. If you want to overwrite the signal mask, use SIG_SETMASK
. With that, you should end up with a parent independent signal block mask.
来源:https://stackoverflow.com/questions/43931229/setting-up-signal-masks-in-a-linux-c-daemon