Lab 8 Preparation: Signals
Read Sections 10.1 to 10.10 in Stevens to prepare for Lab Exercise 7 on signals.
Signals are software interrupts that are sent from one process to another, a simple form of inter-process communication. Use kill(2) to send a signal, and sigaction(2) to set up a function to receive signals. You can also send a signal from the keyboard to a running process with kill(1) and killall(1).
A signal function (or signal handler, or signal catcher) should service the signal as rapidly as possible and then exit. In this and other aspects it's similar to a hardware interrupt handler. Therefore many signal handlers will simply set a flag to show that a signal has occurred. You should not normally attempt to do any stream I/O from a signal handler, and certainly not printf()!
Be aware that it's not your program that calls your signal handler - it is called by a piece of the operating system, and that's where control goes back to when the signal handler function returns. As a result, your program will continue to execute while the signal is being caught.
You can use the sleep(3) and pause(2) functions to wait for a signal to be caught. The sleep() function suspends your program for some number of seconds, so you can check your signal flag whenever you wake up. The pause() function will return whenever a signal is received.
The standard prototype for a signal handler is:
void signal-function(int signal-name);
where signal-function is whatever name you select for your function, and signal-name is the name of the signal (corresponding to a signal number) that caused your function to be called. You cannot change the form of this prototype, of course, since it is the operating systems calling it, not your own program.
You establish a function as a signal handler by use of the sigaction(2) function, calling it once for each signal number you want your function to receive. Once your handler is established, you do not need to call sigaction() again (unless you want to stop handling the signal, or change the function), so you will normally put these function calls in your program initialization. You can also restore default signal behaviour for your process or set a signal to be ignored by using the special function names SIG_DFL and SIG_IGN.
There is a list of the supported signals in signal(7) but the definitive list for any system will always be found by following through the signal.h include file. You should never use the signal number, only the name, since different systems will use different numbers. There are a few exceptions for the first-defined signals. For example, you will hear of the kill signal used to force a process to terminate. Its formal name is SIGKILL but it's also quite well-known (in the proper circles) as signal number 9, as in the keyboard command, "kill -9 pid-number" (as in, "I'm going to kill-nine that <bad-word> program!").
As well as SIGKILL, and the SIGUSR1 and SIGUSR2 used in Lab Exercise 7, you will also have occasion to use SIGTERM and SIGINT, while SIGSEGV, SIGPIPE, SIGBUS and some other signals are the kind that happen to you.
Now read over the instructions for Lab 7 and follow them carefully.