Reputation: 41
i have a program which creates 2 child processes, so, child 1 sends SIGINT to child 2, child 2 handles SIGINT(the handler of SIGINT blocks SIGUSR1), after SIGINT, child 1 sends SIGUSR1 to child 2. I don't know why SIGUSR1 terminates child 2. SIGUSR1 gets blocked when SIGINT is sent.
#include <signal.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
sigset_t base_mask, waiting_mask;
void handler(int signum)
{
signal(SIGINT, handler);
sigemptyset (&base_mask);
sigaddset (&base_mask, SIGUSR1);
/* Block user interrupts while doing other processing. */
if(sigprocmask (SIG_BLOCK, &base_mask, NULL) != 0)
printf("cannot block\n");
else
printf("SIGUSR1 blocked\n");
if(sigismember(&base_mask, SIGUSR1))
printf("sigusr1 in mask\n");
}
int main()
{
if(fork())
{
if(fork())
{
printf("parent out\n");
}
else//child 2
{
printf("i am sib 2 with pid = %d\n", getpid());
signal(SIGINT, handler);
pause();
printf("before sleep\n");
sleep(10);
printf("after sleep\n");
/* After a while, check to see whether any signals are pending. */
sigpending (&waiting_mask);
if (sigismember (&waiting_mask, SIGUSR1))
printf("/* SIGUSR1 pending. */\n");
sleep(2);
printf("2 out\n");
}
}
else//child 1
{
printf("i am sib 1 with pid = %d\n", getpid());
sleep(2);
printf("SIGINT to %d\n", getpid() + 1);
if(kill(getpid() + 1, SIGINT))
printf("Signal cannot be sent\n");
sleep(4);
if(kill(getpid() + 1, SIGUSR1))
printf("Signal 2 cannot be sent\n");
else
printf("SIGUSR1 sent to %d\n", getpid() + 1);
sleep(4);
}
return 0;
}
output:
parent out,
i am sib 1 with pid = 2525,
i am sib 2 with pid = 2526,
SIGINT to 2526,
SIGUSR1 blocked,
sigusr1 in mask,
before sleep,
SIGUSR1 sent to 2526
Upvotes: 1
Views: 1111
Reputation: 18420
The problem is: You block the signal here in the signal handler:
void handler(int signum) {
...
if(sigprocmask (SIG_BLOCK, &base_mask, NULL) != 0)
printf("cannot block\n");
else
printf("SIGUSR1 blocked\n");
if(sigismember(&base_mask, SIGUSR1))
printf("sigusr1 in mask\n");
}
But after returning from the signal handler, the blocked signals mask is restored to the value it had on entry of the handler! So, calling sigprocmask()
has only effect on the blocked signals during the current handler invocation. You have to call it outside the signal handler.
Upvotes: 1