While playing around with errno I decided to test what happens if I sent (and handled) every possible UNIX signal to a program.
Running this as a non-root user, I figured I couldn’t break anything if I tried – so I went ahead and ran it.
Let’s see:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void hndl(int sig) {
printf("SIGNAL %d HANDLED\n", sig);
}
int main(int argc, char **argv){
int ret=0;
for (int i=0;i<256;i++) {
ret = signal(i, hndl);
printf("SIGNAL %d ret %d\n", i, ret);
}
for (int i=0;i<256;i++) {
switch(i){
case 9:
case 19:
case 32:
case 33:
continue;
break;
}
ret = kill(getpid(), i);
printf("KILL %d ret %d\n", i, ret);
}
return 0;
}
I skipped sending SIGKILL
(9) for obvious reasons (the program dies).
Also note that SIGKILL
can’t be intercepted/handled, so the signal()
handler setup fails with -1
.
Here’s the program output:
SIGNAL 0 ret -1
SIGNAL 1 ret 0
SIGNAL 2 ret 0
SIGNAL 3 ret 0
SIGNAL 4 ret 0
SIGNAL 5 ret 0
SIGNAL 6 ret 0
SIGNAL 7 ret 0
SIGNAL 8 ret 0
SIGNAL 9 ret -1
SIGNAL 10 ret 0
SIGNAL 11 ret 0
SIGNAL 12 ret 0
SIGNAL 13 ret 0
SIGNAL 14 ret 0
SIGNAL 15 ret 0
SIGNAL 16 ret 0
SIGNAL 17 ret 0
SIGNAL 18 ret 0
SIGNAL 19 ret -1
SIGNAL 20 ret 0
SIGNAL 21 ret 0
SIGNAL 22 ret 0
SIGNAL 23 ret 0
SIGNAL 24 ret 0
SIGNAL 25 ret 0
SIGNAL 26 ret 0
SIGNAL 27 ret 0
SIGNAL 28 ret 0
SIGNAL 29 ret 0
SIGNAL 30 ret 0
SIGNAL 31 ret 0
SIGNAL 32 ret -1
SIGNAL 33 ret -1
SIGNAL 34 ret 0
SIGNAL 35 ret 0
SIGNAL 36 ret 0
SIGNAL 37 ret 0
SIGNAL 38 ret 0
SIGNAL 39 ret 0
SIGNAL 40 ret 0
SIGNAL 41 ret 0
SIGNAL 42 ret 0
SIGNAL 43 ret 0
SIGNAL 44 ret 0
SIGNAL 45 ret 0
SIGNAL 46 ret 0
SIGNAL 47 ret 0
SIGNAL 48 ret 0
SIGNAL 49 ret 0
SIGNAL 50 ret 0
SIGNAL 51 ret 0
SIGNAL 52 ret 0
SIGNAL 53 ret 0
SIGNAL 54 ret 0
SIGNAL 55 ret 0
SIGNAL 56 ret 0
SIGNAL 57 ret 0
SIGNAL 58 ret 0
SIGNAL 59 ret 0
SIGNAL 60 ret 0
SIGNAL 61 ret 0
SIGNAL 62 ret 0
SIGNAL 63 ret 0
SIGNAL 64 ret 0
SIGNAL 65 ret -1
[ ... ]
SIGNAL 255 ret -1
KILL 0 ret 0
SIGNAL 1 HANDLED
KILL 1 ret 0
SIGNAL 2 HANDLED
KILL 2 ret 0
SIGNAL 3 HANDLED
KILL 3 ret 0
SIGNAL 4 HANDLED
KILL 4 ret 0
SIGNAL 5 HANDLED
KILL 5 ret 0
SIGNAL 6 HANDLED
KILL 6 ret 0
SIGNAL 7 HANDLED
KILL 7 ret 0
SIGNAL 8 HANDLED
KILL 8 ret 0
SIGNAL 10 HANDLED
KILL 10 ret 0
SIGNAL 11 HANDLED
KILL 11 ret 0
SIGNAL 12 HANDLED
KILL 12 ret 0
SIGNAL 13 HANDLED
KILL 13 ret 0
SIGNAL 14 HANDLED
KILL 14 ret 0
SIGNAL 15 HANDLED
KILL 15 ret 0
SIGNAL 16 HANDLED
KILL 16 ret 0
SIGNAL 17 HANDLED
KILL 17 ret 0
SIGNAL 18 HANDLED
KILL 18 ret 0
SIGNAL 20 HANDLED
KILL 20 ret 0
SIGNAL 21 HANDLED
KILL 21 ret 0
SIGNAL 22 HANDLED
KILL 22 ret 0
SIGNAL 23 HANDLED
KILL 23 ret 0
SIGNAL 24 HANDLED
KILL 24 ret 0
SIGNAL 25 HANDLED
KILL 25 ret 0
SIGNAL 26 HANDLED
KILL 26 ret 0
SIGNAL 27 HANDLED
KILL 27 ret 0
SIGNAL 28 HANDLED
KILL 28 ret 0
SIGNAL 29 HANDLED
KILL 29 ret 0
SIGNAL 30 HANDLED
KILL 30 ret 0
SIGNAL 31 HANDLED
KILL 31 ret 0
SIGNAL 34 HANDLED
KILL 34 ret 0
SIGNAL 35 HANDLED
KILL 35 ret 0
SIGNAL 36 HANDLED
KILL 36 ret 0
SIGNAL 37 HANDLED
KILL 37 ret 0
SIGNAL 38 HANDLED
KILL 38 ret 0
SIGNAL 39 HANDLED
KILL 39 ret 0
SIGNAL 40 HANDLED
KILL 40 ret 0
SIGNAL 41 HANDLED
KILL 41 ret 0
SIGNAL 42 HANDLED
KILL 42 ret 0
SIGNAL 43 HANDLED
KILL 43 ret 0
SIGNAL 44 HANDLED
KILL 44 ret 0
SIGNAL 45 HANDLED
KILL 45 ret 0
SIGNAL 46 HANDLED
KILL 46 ret 0
SIGNAL 47 HANDLED
KILL 47 ret 0
SIGNAL 48 HANDLED
KILL 48 ret 0
SIGNAL 49 HANDLED
KILL 49 ret 0
SIGNAL 50 HANDLED
KILL 50 ret 0
SIGNAL 51 HANDLED
KILL 51 ret 0
SIGNAL 52 HANDLED
KILL 52 ret 0
SIGNAL 53 HANDLED
KILL 53 ret 0
SIGNAL 54 HANDLED
KILL 54 ret 0
SIGNAL 55 HANDLED
KILL 55 ret 0
SIGNAL 56 HANDLED
KILL 56 ret 0
SIGNAL 57 HANDLED
KILL 57 ret 0
SIGNAL 58 HANDLED
KILL 58 ret 0
SIGNAL 59 HANDLED
KILL 59 ret 0
SIGNAL 60 HANDLED
KILL 60 ret 0
SIGNAL 61 HANDLED
KILL 61 ret 0
SIGNAL 62 HANDLED
KILL 62 ret 0
SIGNAL 63 HANDLED
KILL 63 ret 0
SIGNAL 64 HANDLED
KILL 64 ret 0
[ ... ]
KILL 255 ret -1
As you can see signals 0, 9, 19, 32 and 33 can’t be hooked up to a handler and every signal # beyond 33 fails as well.
Signals start at 1, so zero
is an invalid signal nr.
Signals 9 and 19 are SIGKILL, SIGSTOP respectively. These cannot be handled by the application.
Starting with 32, the kernel handles real time signals. As you can see on allocrtsig.c
the signal number jumps by 2 when it reaches 32.
So signals 32 and 33 can’t normally be set up under an unmodified Linux kernel, thus the signal()
handler setup returns -1
.
Why does `kill -l` not list signal numbers of 32 and 33?
The signals SIGKILL and SIGSTOP cannot be caught, blocked or orignored, why?