System Definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/signal.h
......
/* Clear all signals from SET. */
extern int sigemptyset (sigset_t *__set) __THROW __nonnull ((1));
/* Set all signals in SET. */
extern int sigfillset (sigset_t *__set) __THROW __nonnull ((1));
/* Add SIGNO to SET. */
extern int sigaddset (sigset_t *__set, int __signo) __THROW __nonnull ((1));
/* Remove SIGNO from SET. */
extern int sigdelset (sigset_t *__set, int __signo) __THROW __nonnull ((1));
/* Return 1 if SIGNO is in SET, 0 if not. */
extern int sigismember (const sigset_t *__set, int __signo)
__THROW __nonnull ((1));
......
sigset_t is one integer type, for which each bit represents one type of signal. If that bit is on, corresponding signal is masked off.
sigemptyset just zero out all bits in sigset_t integer.
sigfillset just turn on all bits in sigset_t integer.
sigaddset turn on one specific bit in sigset_t integer
sigdelset turn off one specific bit in sigset_t integer
sigismember test if one specific bit in sigset_t integer is on.
2. sigprocmask system call
System Definition:
ubuntu@ip-172-31-23-227:~$ less /usr/include/signal.h
......
/* Get the system-specific definitions of `struct sigaction'
and the `SA_*' and `SIG_*'. constants. */
# include <bits/sigaction.h>
/* Get and/or change the set of blocked signals. */
extern int sigprocmask (int __how, const sigset_t *__restrict __set,
sigset_t *__restrict __oset) __THROW;
......
ubuntu@ip-172-31-23-227:~$ less /usr/include/x86_64-linux-gnu/bits/sigaction.h
......
/* Values for the HOW argument to `sigprocmask'. */
#define SIG_BLOCK 0 /* Block signals. */
#define SIG_UNBLOCK 1 /* Unblock signals. */
#define SIG_SETMASK 2 /* Set the set of blocked signals. */
......
For system call sigprocmask, first argument should be one of following macros:
SIG_BLOCK: block the specific signals in 2nd argument
SIG_UNBLOCK: unblock the specific signals in 2nd argument
SIG_SETMASK: assign the specific signals in 2nd argument as current mask
second argument is the pointer pointing to the sigset_t type for which each bit represents one type of signal.
If third argument is not null, then the current mask will be returned in that variable.
If second argument is null, then first argument is ignored, and current signal mask doesn't change.
3. Example of sigprocmask:
sigmask.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<errno.h>
void pr_mask(const char *str)
{
sigset_t sigset;
int errno_save;
// Back up the errno value since this function may change it
errno_save = errno;
// Get the current signal mask
if(sigprocmask(0, NULL, &sigset) < 0) {
printf("sigprocmask error!\n");
exit(1);
}
printf("%s", str);
// Output the signal mask
if(sigismember(&sigset, SIGINT)) printf("SIGINT ");
if(sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
if(sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
if(sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
printf("\n");
// Restore the errno value
errno = errno_save;
}
int main(int argc, char* argv[])
{
sigset_t sigset;
sigemptyset(&sigset);
// Block one empty signal mask set
if(sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
printf("sigprocmask error!\n");
exit(1);
}
pr_mask("BLOCK Empty Set:");
// Block the SIGINT, SIGUSR1 signal
if(sigaddset(&sigset, SIGINT) < 0) {
printf("sigaddset error!\n");
exit(2);
}
if(sigaddset(&sigset, SIGUSR1) < 0) {
printf("sigaddset error!\n");
exit(2);
}
if(sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) {
printf("sigprocmask error!\n");
exit(1);
}
pr_mask("BLOCK SIGINT, SIGUSR1: ");
// Unblock the SIGUSR1 signal:
if(sigdelset(&sigset, SIGINT) < 0) {
printf("sigdelset error!\n");
exit(2);
}
if(sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) {
printf("sigprocmask error!\n");
exit(1);
}
pr_mask("UNBLOCK SIGUSR1: ");
exit(0);
}
shell:
The program firstly setup the empty signal mask. And then add the SIGINT, SIGUSR1 to the signal set, use sigprocmask to block the signals.
After that, it removes SIGINT from signal set, only left the SIGUSR1 in the set, at this time, it use sigprocmask with SIG_UNBLOCK to unblock the specified SIGUSR1 signal.
ubuntu@ip-172-31-23-227:~$ ./sigmask.out
BLOCK Empty Set:
BLOCK SIGINT, SIGUSR1: SIGINT SIGUSR1
UNBLOCK SIGUSR1: SIGINT
No comments:
Post a Comment