John Laszlo
John Laszlo

Reputation: 41

SIGUSR1 terminates the process although i have blocked it

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

Answers (1)

Ctx
Ctx

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

Related Questions