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
sigactiondoesn'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;
}