C Function Sigprocmask
# C Library Function - sigprocmask()
The `sigprocmask()` function is a fundamental system call in C (defined in the `` header) used to examine, change, or both examine and change the **signal mask** of the calling thread.
A signal mask is a set of signals currently blocked from delivery to the active process or thread. When a signal is blocked, it will not trigger its associated signal handler or default action; instead, it remains pending until it is unblocked.
---
## Syntax
```c
#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
```
### Parameters
* **`int how`**: A flag specifying how the signal mask should be modified. It must be set to one of the following constants:
* `SIG_BLOCK`: The signals in the input `set` are added to the current signal mask (i.e., `mask = mask | set`).
* `SIG_UNBLOCK`: The signals in the input `set` are removed from the current signal mask (i.e., `mask = mask & ~set`).
* `SIG_SETMASK`: The current signal mask is completely replaced by the input `set` (i.e., `mask = set`).
* **`const sigset_t *set`**: A pointer to the signal set containing the signals to be blocked, unblocked, or set. If this parameter is `NULL`, the `how` argument is ignored, the signal mask remains unchanged, and the current mask is simply returned in `oldset` (if provided).
* **`sigset_t *oldset`**: A pointer to a `sigset_t` structure where the previous signal mask will be stored. If you do not need to retrieve the previous mask, you can pass `NULL`.
### Return Value
* **`0`**: On success.
* **`-1`**: On failure. The global variable `errno` is set to indicate the error (e.g., `EINVAL` if the value of `how` is invalid).
---
## Code Example
The following program demonstrates how to use `sigprocmask()` to temporarily block the `SIGINT` signal (typically triggered by pressing `Ctrl+C` in the terminal), execute a critical section of code, and then unblock it.
```c
#include
#include
#include
int main() {
sigset_t new_mask, old_mask;
// Initialize the signal set and add SIGINT to it
sigemptyset(&new_mask);
sigaddset(&new_mask, SIGINT);
// Block SIGINT and save the previous signal mask in old_mask
if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) == -1) {
perror("sigprocmask - block");
return 1;
}
printf("SIGINT signal is blocked. Sleeping for 5 seconds...\n");
printf("Try pressing Ctrl+C during this time; the program will not exit immediately.\n");
sleep(5);
// Unblock SIGINT using the saved old_mask (or by explicitly unblocking new_mask)
printf("\nUnblocking SIGINT...\n");
if (sigprocmask(SIG_UNBLOCK, &new_mask, NULL) == -1) {
perror("sigprocmask - unblock");
return 1;
}
printf("SIGINT signal is unblocked. Program exiting normally.\n");
return 0;
}
```
### Expected Output
If you run the program and do not press `Ctrl+C`:
```text
SIGINT signal is blocked. Sleeping for 5 seconds...
Try pressing Ctrl+C during this time; the program will not exit immediately.
Unblocking SIGINT...
SIGINT signal is unblocked. Program exiting normally.
```
If you press `Ctrl+C` while the program is sleeping:
```text
SIGINT signal is blocked. Sleeping for 5 seconds...
Try pressing Ctrl+C during this time; the program will not exit immediately.
^C
Unblocking SIGINT...
```
*(The program terminates immediately upon unblocking because the pending `SIGINT` signal is delivered as soon as the block is lifted).*
---
## Important Considerations
1. **Unblockable Signals**: The signals `SIGKILL` and `SIGSTOP` cannot be blocked. If you attempt to include them in the signal set passed to `sigprocmask()`, the system will silently ignore them without returning an error.
2. **Multi-threaded Programs**: The behavior of `sigprocmask()` is undefined in multi-threaded programs (POSIX.1). In a multi-threaded environment, you must use **`pthread_sigmask()`** instead of `sigprocmask()` to manage signal masks for individual threads.
3. **Critical Sections**: `sigprocmask()` is highly useful for protecting critical sections of code (e.g., updating shared data structures) from being interrupted by asynchronous signal handlers.
4. **Pending Signals**: If a signal is generated while it is blocked, it remains pending. Once the signal is unblocked, at least one instance of the pending signal is delivered to the process.
YouTip