What is the role of the signal?
To let you know that something on the system with enough privileges has sent you a signal, each signal had a disposition
ie a default action that unless caught will do something ie in lots of cases terminate your process or generate a core dump etc.
Okay the OS sends the signal to the process. How exactly is it even done?
The OS can do whatever it wants. I could call arbitrary functions in your program if it wanted, in the case of a signal it checks to see if you have a signal handler set and if so it calls that with the signal number. If not it does what ever the default is for that system.
How does the process know that the signal has arrived to be handled?
You can set a handler that lets you know when it arrives. If you don't set a handler a default action will occur.
In the following code compile it and run it then use CTRL-c
to terminate it or use kill to send it various signal numbers. This demonstrate catching signals.
CAVEAT. The following code has been run on Mac and Linux and makes a lot of assumptions about the integer values if the signals, it's certainly not portable it's here as an example on how you can use signal to set up a signal_handler function only.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
extern char *taunts[];
int taunt();
void sig_handler(int signo) {
switch(signo) {
case SIGHUP: printf("\t%s %d\n", taunts[taunt()], SIGHUP);break;
case SIGINT: printf("\t%s %d\n", taunts[taunt()], SIGINT);break;
case SIGQUIT: printf("\t%s %d\n", taunts[taunt()], SIGQUIT);break;
case SIGILL: printf("\t%s %d\n", taunts[taunt()], SIGILL);break;
case SIGTRAP: printf("\t%s %d\n", taunts[taunt()], SIGTRAP);break;
case SIGABRT: printf("\t%s %d\n", taunts[taunt()], SIGABRT);break;
case SIGFPE: printf("\t%s %d\n", taunts[taunt()], SIGFPE);break;
case SIGKILL: printf("\t%s %d\n", taunts[taunt()], SIGKILL);break;
case SIGBUS: printf("\t%s %d\n", taunts[taunt()], SIGBUS);break;
case SIGSEGV: printf("\t%s %d\n", taunts[taunt()], SIGSEGV);break;
case SIGSYS: printf("\t%s %d\n", taunts[taunt()], SIGSYS);break;
case SIGPIPE: printf("\t%s %d\n", taunts[taunt()], SIGPIPE);break;
case SIGALRM: printf("\t%s %d\n", taunts[taunt()], SIGALRM);break;
case SIGTERM: printf("\t%s %d\n", taunts[taunt()], SIGTERM);break;
default: printf("\tMerde\n");
}
#ifdef __linux__
if (signal(signo, sig_handler) == SIG_ERR) {
printf("Merde: %d\n", signo);
}
#endif
}
int main(void) {
srand(time(NULL));
int i = 0;
for(i = 0; i < 15; i ++) {
if (signal(i, sig_handler) == SIG_ERR) {
printf("Merde: %d\n", i);
}
}
while(1) {
sleep(10);
}
return 0;
}
int taunt() {
return rand() % 12;
}
char *taunts[13] = {
"\n No, now go away or I shall taunt you a second time! With youri\n rubbish signal... ",
"\n You don't frighten us, English pig dogs with your daft signal... ",
"\n Go and boil your bottoms, you sons of a silly person and your\n \
nincompoop signal... ",
"\n I blow my nose at you, so-called \"Arthur King,\" you and all\n \
your silly English K-nig-hts. With your silly signal... ",
"\n I'm French. Why do you think I have this outrageous accent, you\n \
silly king? With your silly signal... ",
"\n Mind your own business With your ludicrous signal... ",
"\n You don't frighten us with your silly knees-bent running around\n \
advancing behavior! With your silly signal... ",
"\n How you English say, I one more time-a unclog my nose in your\n"
" direction, sons of a window-dresser! With your weak signal... ",
"\n No chance, English bedwetting types. With your outrageous signal... ",
"\n Yes, depart a lot at this time and cut the approaching any more\n \
or we fire arrows at the tops of your heads and make castanets\n \
out of your testiclesi already! With your stupido signal.."
"\n And now remain gone illegitimate faced buggerfolk! and your farty\n signal... ",
"\n And, if you think you got nasty taunting this time, you ain't\n heard nothing yet! I signal in your general direction... ",
"\n Daffy English kniggets! Thpppt!... ",
};