sigsuspend is a function that changes the mask and suspends the process until a new signal is delivered, but what surprised me is that the pending signals are being delivered also after the sigsuspend.
For example: while the process is sleeping (5 sec), a ctrl-z will not execute the SIGTSTP handler because it's masked, but after the sigsuspend the signal is received automatically so the sigsuspend executes the pending signal handler also, it's right? `
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void handlerSIGTSTP()
{
printf("I have recieved the signal \n");
}
int main()
{
sigset_t mask;
sigset_t ancien;
signal(SIGTSTP,handlerSIGTSTP);
sigaddset(&mask,SIGTSTP);
sigprocmask(SIG_SETMASK,&mask,&ancien);
printf("J'entre en sleep\n");
sleep(5);
printf("J'entre en suspend\n");
sigsuspend(&ancien);
}
Execution:
J'entre en sleep
^ZJ'entre en suspend
J'ai recu le signal maintenant
CodePudding user response:
Although your example code has some issues that are addressed in comments, I'll focus in this answer on the main questions you raise, which are not fundamentally dependent on the example program.
sigsuspend is a function that changes the mask and suspends the process until a new signal is delivered,
Your use of the word "new" in that description suggests a misunderstanding. The docs do not use it, and it doesn't really make sense in context.
but what surprised me is that the pending signals are being delivered also after the sigsuspend.
Yes. sigsuspend()
temporarily replaces the signal mask and suspends execution until a signal is delivered whose action is to invoke a signal handler or terminate the process. That can be a signal that was already pending before sigsuspend()
was called. That is one of the circumstances that the idiomatic combination of sigprocmask()
with sigsuspend()
is specifically aimed at handling. This allows a process to avoid handling an expected signal before it is ready for it.
For example: while the process is sleeping (5 sec), a ctrl-z will not execute the SIGTSTP handler because it's masked, but after the sigsuspend the signal is received automatically so the sigsuspend executes the pending signal handler also, it's right?
Yes. In your example code, sigsuspend()
unblocks SIGTSTP
, so if there is a pending SIGTSTP
then it is delivered within the scope of the sigsuspend()
. That triggers a signal handler in your case, so when the handler returns, sigsuspend()
terminates.