I need a clarification on sigsuspend topic. I have a simplified example
sigset_t mask, oldmask;
sigemptyset (&mask);
sigaddset (&mask, SIGRTMIN+1);
sigprocmask (SIG_BLOCK, &mask, &oldmask);
sigsuspend(&oldmask);
sigprocmask (SIG_UNBLOCK, &mask, NULL);
Here is how I understand this:
Secondly, let's suppose I have such sigsuspend in a loop and there arrived a few SIGRTMIN+1 signals. Will such loop continue for each signal ? in some kind of queue?
while(1){
sigsuspend(&oldmask)
printf("recieved signal");
}
so that for each signal I have 'recieved signal' printed?
Major parts of the previous edition of this answer were wrong. I apologize for my mistake. I thank Wotim for pointing out the error.
sigsuspend()
The POSIX standard describes sigsuspend()
fairly clearly:
#include <signal.h>
int sigsuspend(const sigset_t *sigmask);
DESCRIPTION
The
sigsuspend()
function shall replace the current signal mask of the calling thread with the set of signals pointed to bysigmask
and then suspend the thread until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process. This shall not cause any other signals that may have been pending on the process to become pending on the thread.If the action is to terminate the process then
sigsuspend()
shall never return. If the action is to execute a signal-catching function, thensigsuspend()
shall return after the signal-catching function returns, with the signal mask restored to the set that existed prior to thesigsuspend()
call.It is not possible to block signals that cannot be ignored. This is enforced by the system without causing an error to be indicated.
RETURN VALUE
Since
sigsuspend()
suspends thread execution indefinitely, there is no successful completion return value. If a return occurs, -1 shall be returned and errno set to indicate the error.ERRORS
The
sigsuspend()
function shall fail if:
[EINTR]
A signal is caught by the calling process and control is returned from the signal-catching function.
Also, the POSIX Signal concepts says:
Each thread has a "signal mask" that defines the set of signals currently blocked from delivery to it.
The sigsuspend()
function is the modern analogue of the old pause()
function.
Major change: two code blocks reversed.
It allows you to send your thread to sleep until one of its selected signals occurs. If you want it to sleep until SIGRTMIN+1 arrives, you use:
sigfillset(&mask);
sigdelset(&mask, SIGRTMIN+1);
sigsuspend(&mask);
This blocks every signal except SIGRTMIN+1.
If you want to sleep until a signal other than SIGRTMIN+1 arrives, you use:
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN+1);
sigsuspend(&mask);
This blocks only SIGRTMIN+1.
Your loop won't print Received signal
reliably unless you add a newline at the end (and maybe not even then; you might need to fflush(stdout)
or equivalent). However, if you have SIGRTMIN+1 blocked in the ordinary course of events and then you set up &oldmask
to allow only SIGRTMIN+1, then your signals will be reliably delivered while your code is in sigsuspend()
.
Your description of sigprocmask()
is not correct:
sigprocmask
sets all signals inmask+oldmask
to be blocked
When you do:
sigset_t mask, oldmask;
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN+1);
sigprocmask(SIG_BLOCK, &mask, &oldmask);
You add SIGRTMIN+1 to the list of blocked signals (because you used SIG_BLOCK and mask
only contains SIGRTMIN+1). The output in oldmask
is the signal mask before SIGRTMIN+1 was added. It might or might not already have contained SIGRTMIN+1. The process's signal mask is changed (if you needed to set the signal mask for a thread, you'd use pthread_sigprocmask()
instead) from its current value to a new value containing SIGRTMIN+1, and you get told the old value.
So is it wrong to use
sigsuspend(&oldmask)
as in my first example if I want to block SIGRTMIN+1?
Major change.
Yes, it is wrong. Calling sigsuspend(&oldmask)
sends your thread to sleep until one of the signals in oldmask
is received. The content of oldmask
is the set of signals that was blocked before you added SIGRTMIN+1.
Yes, it is wrong. Calling sigsuspend(&oldmask)
sends your thread to sleep until one of the signals not in oldmask
is received. The content of oldmask
is the set of signals that was blocked before you added SIGRTMIN+1.
The following two paragraphs are withdrawn rather than necessarily condemned as wrong. I think there are elements of truth in both, though there is room for improvement in both, too.
You do not use sigsuspend()
to block signals per se; you use it to wait for one of a specified set of signals to arrive.
If you want to ignore SIGRTMIN+1, then you need to use sigaction()
or you can use sigprocmask()
as you did; that specifically blocks SIGRTMIN+1 as well as all the other signals that were already blocked.
Do I understand correctly that it will block the same signals the way it was?
Assuming 'it' is sigsuspend()
, then it will block any signal not in oldmask
and wait for one of the signals in oldmask
to arrive.
Assuming 'it' is sigsuspend()
, then it will block any signal in oldmask
and wait for one of the signals not in oldmask
to arrive.
And if I do
sigsuspend(&mask)
then it will block SIGRTMIN+1 and all of the signals inoldmask
because ofsigprocmask(SIG_BLOCK, &mask, &oldmask)
?
Major change
Absolutely not! This will suspend the thread until one of the signals in mask
arrives. Since the only signal in mask
is SIGRTMIN+1, only when that arrives will sigsuspend()
return. The sigprocmask()
reported what was being blocked before the call in oldmask
; it did not modify mask
(your variable) at all; it did modify the process's signal mask by adding SIGRTMIN+1.
Absolutely not! This will suspend the thread until one of the signals not in mask
arrives. Since the only signal in mask
is SIGRTMIN+1, only that signal is blocked and when any other signal arrives, it will be handled and sigsuspend()
will return. The sigprocmask()
reported what was being blocked before the call in oldmask
; it did not modify mask
(your variable) at all; it did modify the process's signal mask by adding SIGRTMIN+1.
I strongly recommend reading, or rereading, the POSIX Signal concepts and the various functions that manipulate signal handling. (And yes, this is, in part, a prescription of "Physician, heal thyself".)
Please let me know if there are still mistakes in here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With