signal(SIGx, signalhandler);
for every signal or is there a better way?
|
|
A Robust Signals Interface We’ve covered raising and catching signals using signal and friends in some depth, because they are very common in older UNIX programs. However, the X/Open and UNIX specifications recommend a newer programming interface for signals that is more robust: sigaction.
The sigaction structure, used to define the actions to be taken on receipt of the signal specified by sig, is defined in signal.h and has at least the following members:
The sigaction function sets the action associated with the signal sig. If oact is not null, sigaction writes the previous signal action to the location it refers to. If act is null, this is all sigaction does. If act isn’t null, the action for the specified signal is set. As with signal, sigaction returns 0 if successful and -1 if not. The error variable errno will be set to EINVAL if the specified signal is invalid or if an attempt is made to catch or ignore a signal that can’t be caught or ignored. Within the sigaction structure pointed to by the argument act, sa_handler is a pointer to a function called when signal sig is received. This is much like the function func you saw earlier passed to signal. You can use the special values SIG_IGN and SIG_DFL in the sa_handler field to indicate that the signal is to be ignored or the action is to be restored to its default, respectively. The sa_mask field specifies a set of signals to be added to the process’s signal mask before the sa_handler function is called. These are the set of signals that are blocked and won’t be delivered to the process. This prevents the case you saw earlier where a signal is received before its handler has run to completion. Using the sa_mask field can eliminate this race condition. However, signals caught with handlers set by sigaction are by default not reset, and the sa_flags field must be set to contain the value SA_RESETHAND if you want to obtain the behavior you saw earlier with signal. Before we look in any more detail at sigaction, let’s rewrite the program ctrlc.c, using sigaction instead of signal. Try It Out sigaction Make the changes that follow so that SIGINT is intercepted by sigaction. Call the new program ctrlc2.c.
When you run this version of the program, you always get a message when you type Ctrl+C because SIGINT is handled repeatedly by sigaction. To terminate the program, you have to type Ctrl+\, which generates the SIGQUIT signal by default. $ ./ctrlc2 Hello World! Hello World! Hello World! ^C OUCH! - I got signal 2 Hello World! Hello World! ^C OUCH! - I got signal 2 488 Chapter 11: Processes and Signals Hello World! Hello World! ^\ Quit $ How It Works The program calls sigaction instead of signal to set the signal handler for Ctrl+C (SIGINT) to the function ouch. It first has to set up a sigaction structure that contains the handler, a signal mask, and flags. In this case, you don’t need any flags, and an empty signal mask is created with the new function, sigemptyset. After running this program, you may find a core dump (in a file called core) has been created. You can safely delete it. |