sigprocmask(2)
๐ sigprocmask โ bestie edition ๐
okay so this is sigprocmask(2), and yes it lives in the System Calls Manual, but honestly it's more like the group chat settings for your signals. grab a snack, we're learning signal masks ๐
โจ NAME โจ
sigprocmask, rt_sigprocmask โ examine and change blocked signals
๐ LIBRARY ๐
Standard C library (libc, -lc) โ she's a libc girlie ๐
๐ธ SYNOPSIS ๐ธ
#include <signal.h>
/* Prototype for the glibc wrapper function */
int sigprocmask(int how, const sigset_t *_Nullable restrict set,
sigset_t *_Nullable restrict oldset);
#include <signal.h> /* Definition of SIG_* constants */
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
/* Prototype for the underlying system call */
int syscall(SYS_rt_sigprocmask, int how,
const kernel_sigset_t *_Nullable set,
kernel_sigset_t *_Nullable oldset,
size_t sigsetsize);
/* Prototype for the legacy system call */
[[deprecated]] int syscall(SYS_sigprocmask, int how,
const old_kernel_sigset_t *_Nullable set,
old_kernel_sigset_t *_Nullable oldset);
๐ Feature Test Macro Requirements for glibc ๐
(see feature_test_macros(7), iykyk)
sigprocmask():_POSIX_C_SOURCE
๐ฆ DESCRIPTION ๐ฆ
sigprocmask() is the function you call to fetch and/or change the signal mask of the calling thread โ no cap. And what's the signal mask, bestie? It's literally the set of signals whose delivery is currently blocked for whoever's calling (peep signal(7) for the full tea ๐).
The way the call behaves totally depends on how, and here's the breakdown:
SIG_BLOCKโ the set of blocked signals becomes the union of the current set and thesetargument. union, slay โจSIG_UNBLOCKโ the signals insetget removed from the current set of blocked signals. and yes, it is totally permissible to attempt to unblock a signal that isn't even blocked. no gatekeeping here ๐ซถSIG_SETMASKโ the set of blocked signals is just set to thesetargument. periodt.
If oldset is non-NULL, the previous value of the signal mask gets stored in oldset. lil time capsule moment ๐ฆ
And if set is NULL? then the signal mask stays unchanged (like, how is fully ignored, not even looked at), but the current value of the signal mask is still returned in oldset (as long as oldset isn't NULL). iconique behaviour tbh.
There's a whole squad of functions for modifying and inspecting variables of type sigset_t โ aka "signal sets" โ and they're described over in sigsetops(3).
โ ๏ธ heads up: usingsigprocmask()in a multithreaded process is unspecified. it's giving chaos. go seepthread_sigmask(3)instead, fr fr.
๐ฅ RETURN VALUE ๐ฅ
sigprocmask() returns 0 on success. On failure, -1 comes back and errno is set to tell you what went wrong. she said "here's your error code, you're welcome" ๐ญ
๐ ERRORS ๐
EFAULTโ thesetoroldsetargument points outside the process's allocated address space. ma'am that is NOT your memory ๐EINVALโ either the value specified inhowwas invalid, or the kernel does not support the size passed insigsetsize. nope, rejected ๐
๐ VERSIONS ๐
๐ง C library/kernel differences ๐ง
okay this part is lowkey important so listen up:
The kernel's definition of sigset_t differs in size from the one the C library uses. In this manual page, the kernel's version is referred to as kernel_sigset_t โ although it is nevertheless named sigset_t in the kernel sources. two things, same name, different sizes ๐
The glibc wrapper function for sigprocmask() silently ignores attempts to block the two real-time signals that are used internally by the NPTL threading implementation. sneaky! see nptl(7) for details.
The original Linux system call was named sigprocmask(). But then real-time signals showed up in Linux 2.2, and the fixed-size, 32-bit sigset_t (called old_kernel_sigset_t in this manual page) that the old system call supported was no longer fit for purpose โ it just couldn't serve the look anymore. So a new system call, rt_sigprocmask(), was added to support an enlarged sigset_t type (referred to as kernel_sigset_t in this manual page). The new system call takes a fourth argument, size_t sigsetsize, which specifies the size in bytes of the signal sets in set and oldset. This argument is currently required to have a fixed architecture specific value (equal to sizeof(kernel_sigset_t)). no flexibility, sorry bestie, it's architecture-locked ๐
And the glibc sigprocmask() wrapper function hides all of these details from us, transparently calling rt_sigprocmask() whenever the kernel provides it. she's doing the work behind the scenes, main character energy ๐
๐ STANDARDS ๐
POSIX.1-2024.
๐ HISTORY ๐
POSIX.1-2001.
๐ NOTES ๐
- It is not possible to block
SIGKILLorSIGSTOP. attempts to do so are silently ignored. you cannot stop these two, they said no ๐ - Each of the threads in a process has its own signal mask. everybody's got their own vibe ๐ฆ
- A child created via
fork(2)inherits a copy of its parent's signal mask; and the signal mask is preserved acrossexecve(2). family heirloom behaviour tbh ๐ - If
SIGBUS,SIGFPE,SIGILL, orSIGSEGVare generated while they are blocked, the result is undefined, unless the signal was generated bykill(2),sigqueue(3), orraise(3). undefined = we do not know what happens. do not test this. i am begging ๐ - See
sigsetops(3)for details on manipulating signal sets. - Note that it is permissible (although not very useful) to specify both
setandoldsetasNULL. technically allowed! practically pointless! that's the whole note! ๐ญ
๐ SEE ALSO ๐
kill(2), pause(2), sigaction(2), signal(2), sigpending(2), sigsuspend(2), pthread_sigmask(3), sigqueue(3), sigsetops(3), signal(7)
and that's the whole page bestie, you ate that ๐ โจ
this edition came from Linux man-pages 6.20, dated 2026-02-08, and it's still sigprocmask(2) at heart โ go block some signals responsibly, mwah ๐ซถ๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 2005, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms