I have some code that I want to use to print a list of signals that prints the names of the signals in the signal mask of the calling process.
The starting code that I h
Create a structure type, and preload an array with the appropriate information:
struct SigInfo
{
int signum;
char signame[16];
};
static const struct SigInfo siginfo[] =
{
#ifdef SIGINT
{ SIGINT, "SIGINT" },
#endif
#ifdef SIGQUIT
{ SIGQUIT, "SIGQUIT" },
#endif
…
};
enum { NUM_SIGINFO = sizeof(siginfo) / sizeof(siginfo[0]) };
And then:
printf("%s", str);
for (int i = 0; i < NUM_SIGINFO; i++)
{
if (sigismember(&sigset, siginfo[i].signum))
{
printf(" %s\n", siginfo[i].signame);
break;
}
}
You can package the information multiple different ways. Generating the signal information is fiddly. I use a Perl script to scrutinize the appropriate header (usually /usr/include/sys/errno.h) and extract the information shown, plus the text of what the signal is for, plus the number associated with the signal:
typedef struct sig_info
{
const char *sigsym; /* Signal symbol - "EINTR" */
int signum; /* Signal number - EINTR */
int sigdef; /* Signal define - 2 */
const char *sigmsg; /* Signal message - Interrupted system call */
} sig_info;
…
#ifdef SIGPIPE
{ "SIGPIPE", SIGPIPE, 13, "Broken pipe (POSIX)." },
#endif
#ifdef SIGPROF
{ "SIGPROF", SIGPROF, 27, "Profiling alarm clock (4.2 BSD)." },
#endif
#ifdef SIGPWR
{ "SIGPWR", SIGPWR, 30, "Power failure restart (System V)." },
#endif
…
The program this comes from allows me to find signals by name or number:
$ ./signal int 2
SIGINT (2): Interrupt (ANSI).
2 (SIGINT): Interrupt (ANSI).
$ ./signal -h
Usage: signal [-hlqV] [lo[:hi] ...]
-h Print help and exit
-l Print list of all signals
-q Validate signal but don't print messages
-V Print version and exit
$ ./signal -l
1 (SIGHUP): Hangup (POSIX).
2 (SIGINT): Interrupt (ANSI).
3 (SIGQUIT): Quit (POSIX).
4 (SIGILL): Illegal instruction (ANSI).
5 (SIGTRAP): Trace trap (POSIX).
6 (SIGIOT): IOT trap (4.2 BSD).
6 (SIGIOT): IOT trap (4.2 BSD).
7 (SIGBUS): BUS error (4.2 BSD).
8 (SIGFPE): Floating-point exception (ANSI).
9 (SIGKILL): Kill, unblockable (POSIX).
10 (SIGUSR1): User-defined signal 1 (POSIX).
11 (SIGSEGV): Segmentation violation (ANSI).
12 (SIGUSR2): User-defined signal 2 (POSIX).
13 (SIGPIPE): Broken pipe (POSIX).
14 (SIGALRM): Alarm clock (POSIX).
15 (SIGTERM): Termination (ANSI).
16 (SIGSTKFLT): Stack fault.
17 (SIGCHLD): Child status has changed (POSIX).
18 (SIGCONT): Continue (POSIX).
19 (SIGSTOP): Stop, unblockable (POSIX).
20 (SIGTSTP): Keyboard stop (POSIX).
21 (SIGTTIN): Background read from tty (POSIX).
22 (SIGTTOU): Background write to tty (POSIX).
23 (SIGURG): Urgent condition on socket (4.2 BSD).
24 (SIGXCPU): CPU limit exceeded (4.2 BSD).
25 (SIGXFSZ): File size limit exceeded (4.2 BSD).
26 (SIGVTALRM): Virtual alarm clock (4.2 BSD).
27 (SIGPROF): Profiling alarm clock (4.2 BSD).
28 (SIGWINCH): Window size change (4.3 BSD, Sun).
29 (SIGIO): I/O now possible (4.2 BSD).
30 (SIGPWR): Power failure restart (System V).
31 (SIGSYS): Bad system call.
34 (SIGRT34): Real time signal 34 (SIGRTMIN)
35 (SIGRT35): Real time signal 35
…
63 (SIGRT63): Real time signal 63
64 (SIGRT64): Real time signal 64 (SIGRTMAX)
$
This particular list of signals was generated on an ancient RedHat Linux machine (5.2, IIRC). The effect is similar on macOS, and other versions of Linux too.