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
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.
OUCH! - I got signal 2
OUCH! - I got signal 2
Chapter 11: Processes and Signals
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,
After running this program, you may find a core dump (in a file called core) has been created. You can
safely delete it.