1

When I raise SIGUSR2 inside the SIGUSR1 handler, shouldn't it get blocked ? This code prints "second - Inside first"

void
hand1(int s) {
    kill(getpid(), SIGUSR2);
    printf("Inside first");
}

void
hand2(int s) {
    printf("second - ");
}

main() {
    signal(SIGUSR1, hand1);
    signal(SIGUSR2, hand2);
    kill(getpid(), SIGUSR1);
}
pilcrow
  • 56,591
  • 13
  • 94
  • 135

1 Answers1

2

When I raise SIGUSR2 inside the SIGUSR1 handler, shouldn't it get blocked ?

No. This is what's happening:

time  signal_mask  code
----  -----------  ----
 0         -       main:signal(SIGUSR1, hand1)
 1         -       main:signal(SIGUSR2, hand1)
 2         -       main:kill(getpid(), SIGUSR1)
 3    USR1         hand1:kill(getpid(), SIGUSR2)
 4    USR1|USR2    hand2:printf("second - ")
 5    USR1         hand1:printf("Inside first")
 6         -       main:...

But don't use signal(), instead prefer sigaction(). The former doesn't guarantee handler semantics on all platforms, the latter does.

Also, sigaction makes explicit which signals are blocked during the handler and which are not. If you wanted to block all signals during your handler (and I'd generally recommend that as it is easier to reason about the behavior of a function you know won't be interrupted), you could do something like:

int handle_signal(int sig, void (*handler)(int)) {
  struct sigaction sa = { .sa_flags = 0 };

  sigfillset(&sa.sa_mask); // block everything during handler
  sa.sa_handler = handler;

  return sigaction(sig, &sa, NULL);
}
Community
  • 1
  • 1
pilcrow
  • 56,591
  • 13
  • 94
  • 135