During exec()
the mask of blocked signals (as set by sigprocmask()
) is inherited by child processes.
But now I've noticed that under Linux, there is also mask of ignored signals (grep < /proc/self/status ^SigIgn
), and it's also inherited by child processes. Since these are set by sigaction()
with act.sa_handler = SIG_IGN
, I would have expected that, as signal handlers, they are reset during exec. But they are not.
Consider example below: parent wants to ignore the SIGINT, but that also extends to the child, thus the sleep 120
can't be killed with kill -INT $(pidof sleep)
anymore.
Questions:
Is this POSIX compliant? Documentation of sigaction() explicitly states that effect of
sigaction
doesn't surviveexec
(Quote: "... until one of the exec functions is called"). Linux man page says "the dispositions of ignored signals are left unchanged" which I guess makes that a Linux specific feature.How to reset the ignore mask correctly & reliably? I have found no analog of
sigprocmask()
- manages blocked signals - to manage the mask of ignored signals. Should I simply iterate over all signals and reset them withsigaction()
?
P.S. Tested with kernels v3.x & v4.9, same behavior.
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
struct sigaction act;
sigset_t ss;
system("grep -n < /proc/self/status ^SigIgn");
memset(&act, 0, sizeof(act));
act.sa_handler = SIG_IGN;
sigaction( SIGINT, &act, NULL );
system("grep -n < /proc/self/status ^SigIgn");
sigemptyset(&ss);
sigprocmask(SIG_SETMASK, &ss, NULL);
system("grep -n < /proc/self/status ^SigIgn");
system("sleep 120");
return 0;
}