SIGPAUSE(2)

πŸ’– SIGPAUSE(2) πŸ’–

okay bestie, gather round, we're doing a system calls manual moment. this is the System Calls Manual page for SIGPAUSE and friends, and honestly? it's giving ✨legacy✨. buckle up. πŸŽ€


🌸 NAME 🌸

<pink>sighold</pink>, <pink>sigignore</pink>, <pink>sigpause</pink>, <pink>sigrelse</pink>, <pink>sigset</pink> β€” the whole legacy interface for signal management, no cap. it's the old-school squad 🫢

πŸ“š LIBRARY πŸ“š

Standard C Library (libc, -lc). your fave, your ride-or-die, <cyan>libc</cyan> πŸ’…

✨ SYNOPSIS ✨

#include <signal.h>

int
sighold(int sig);

int
sigignore(int sig);

int
xsi_sigpause(int sigmask);

int
sigrelse(int sig);

void (*)(int)
sigset(int, void (*disp)(int));

int
sigpause(int sigmask);

like, look at that. <purple>six functions</purple> in one header file, all just vibing in signal.h`. iykyk πŸ¦‹

🧚 DESCRIPTION 🧚

okay so first things first, and this is the tea: this whole interface is made obsolete by sigsuspend(2) and sigaction(2). so like, it still works, but it's the grandma of signal APIs. respect her, but maybe don't build your whole app on her. 😭

sigset() β€” the main character πŸ‘‘

<hotpink>sigset()</hotpink> modifies signal dispositions. here's the deets:

  • the sig argument says which signal we're talking about, and it can be <green>any signal except SIGKILLandSIGSTOP</green>. those two are literally not negotiable, sorry bestie.
  • the disp argument says what the signal's disposition should be β€” and it can be SIG_DFL, SIG_IGN, or the address of a signal handler. pick your fighter πŸ’…

now the little special-case lore, because this is where it gets juicy:

  • if sigset() is used and disp is the address of a signal handler, the system adds sig to the signal mask of the calling process before executing the signal handler. then, when the signal handler returns, the system restores the signal mask of the calling process to whatever it was prior to the delivery of the signal. <lavender>automatic cleanup, we love to see it</lavender> ✨
  • if sigset() is used and disp is equal to SIG_HOLD, then sig gets added to the signal mask of the calling process and sig's disposition stays exactly the same. <mint>unchanged. untouched. unbothered.</mint> 🧘
  • if sigset() is used and disp is not equal to SIG_HOLD, then sig is removed from the signal mask of the calling process. bye boo πŸ‘‹

the rest of the squad 🌈

  • sighold() β€” adds sig to the signal mask of the calling process. that's it, that's the function. short queen πŸŽ€
  • sigrelse() β€” removes sig from the signal mask of the calling process. the opposite of the above, we stan a balanced pair 🫢
  • sigignore() β€” sets the disposition of sig to SIG_IGN. <yellow>ignoring your problems, but make it a syscall</yellow> πŸ™ˆ
  • xsi_sigpause() β€” removes sig from the signal mask of the calling process and suspends the calling process until a signal is received. then, before returning, it restores the signal mask of the process to its original state. <cyan>nap time, but with rules</cyan> 😴

sigpause() β€” the historic one πŸ›οΈ

  • sigpause() assigns sigmask to the set of masked signals and then just… waits for a signal to arrive. on return, the set of masked signals is restored.
  • the sigmask argument is usually 0, which indicates that no signals are to be blocked. <purple>zero. nada. nothing blocked.</purple> ⭐

🫢 RETURN VALUES 🫢

okay so this part matters, don't skip it:

  • sigpause() and xsi_sigpause() always terminate by being interrupted, returning -1 with errno set to EINTR. always. <red>they literally cannot succeed normally, that's the whole bit</red> πŸ’€
  • sigset(), on successful completion, returns SIG_HOLD if the signal had been blocked, and the signal's previous disposition if it had not been blocked. otherwise, SIG_ERR is returned and errno is set to indicate the error.
  • for all the other functions, successful completion returns 0. otherwise, -1 is returned and errno is set to indicate the error:

and here are the errors, in their own little numbered-ish bullet list because the manpage uses error codes:

  • [EINVAL] β€” the sig argument is not a valid signal number. <peach>not a real signal, bestie</peach> 🚫
  • [EINVAL] β€” for the sigset() and sigignore() functions, an attempt was made to catch or ignore SIGKILL or SIGSTOP. you cannot catch or ignore these two. do not try. it will not work. πŸ‘‘

πŸ”₯ SEE ALSO πŸ”₯

go read these next, they're the glow-ups:


πŸ“œ STANDARDS πŸ“œ

the lore drop πŸ“:

  • sigpause() is implemented for compatibility with historic <blue>4.3BSD</blue> applications.
  • there was an incompatible interface by the same name, which used a single signal number rather than a mask, present in <purple>AT&T System V UNIX</purple>, and it got copied from there into the X/Open System Interfaces (XSI) option of IEEE Std 1003.1-2001 (β€œPOSIX.1”).
  • <hotpink>FreeBSD</hotpink> implements it under the name xsi_sigpause(). iconic name change honestly πŸ’…
  • sighold(), sigignore(), sigrelse() and sigset() are implemented for compatibility with System V and XSI interfaces. old friends, still hanging around 🫢

πŸ•°οΈ HISTORY πŸ•°οΈ

  • sigpause() appeared in <mint>4.2BSD</mint> and has been deprecated. sad but true 😭
  • all the other functions appeared in <cyan>FreeBSD 8.1</cyan> and were deprecated before being implemented. not them being cancelled before their debut πŸ’€ like, imagine getting deprecated before you even drop.

and that's the whole page bestie, you're officially fluent in legacy signal management πŸŒˆπŸ’–

this page came from the Debian crew, dated June 2, 1993 β€” yeah, 1993, it's vintage, it's archival, it's older than most of us, and it's still out here explaining itself. mwah. 😘 πŸŽ€βœ¨πŸ¦‹

πŸ“¦ where this page comes from