Chapter Contents |
Previous |
Next |
Signal-Handling Functions |
A signal handler may be identified by either the
signal
or the
sigaction
function, regardless of whether the signal is managed by SAS/C or
USS. In general,
sigaction
is more flexible
because it does not have to be reissued every time you enter a handler. However,
signal
is more portable because it is defined
by the ISO/ANSI standard and it is defined by traditional UNIX C compilers;
whereas, the
sigaction
function is defined
by the POSIX standard and is often not available with traditional UNIX C compilers.
Using signal |
These basic actions are used to define a signal handler using
the
signal
function defined by the ISO/ANSI
standard:
signal
or
sigaction
functions to identify a handler
for the signal in the beginning of the program or at some point before the
signal may occur.
signal
within the handler function to reinstate handling for
that signal.
(This is not necessary when a handler is defined using
sigaction
).
The
signal
function
requires two arguments: the name of the signal and the address of the function
that handles the signal when it occurs. When a signal occurs, the handler
defined by use of the
signal
function is
called. The handler can do anything a normal C function can do. Frequently,
a handler calls
exit
or
abort
to terminate program execution, or it calls
longjmp
to transfer control to a higher-level function. (For example,
a handler for
SIGINT
may use
longjmp
to transfer control to the main function to immediately get
new input from the terminal.)
After processing a signal, you may want the program
to continue execution from the point at which it was interrupted. In this
case, the handler simply executes a
return
statement. However, for some signals (such as
SIGILL
), it is impossible to resume at the point at which the signal
occurred. If a signal handler returns in such a situation, the program is
abnormally terminated.
The call to
signal
establishes signal handling for only one occurrence of a signal.
Before the signal-handling function is called, the library resets the signal
so that the default action is performed if the same signal occurs again.
Resetting signal handling helps to prevent an infinite loop if, for example,
an action performed in the signal handler raises the same signal again. If
you want your handler to be used for a signal each time it occurs, you must
call
signal
within the handler to reinstate
it. You should be cautious in reinstating signal handling. For example,
if you continually reinstate
SIGINT
handling,
you may lose the ability to interrupt and terminate your program.
Using sigaction |
These
basic actions are used to define a signal handler using the
sigaction
function defined by the POSIX standard:
sigemptyset
,
sigfillset
,
sigaddset
,
sigdelset
, and
sigismember
functions as required to define a
signal mask that will block signals while the handler is running.
sigaction
function to identify a handler for the signal at the beginning of
the program or at some point before the signal may occur.
As you can see
from the previous list, the signal handling
process used with
sigaction
is significantly
different from the one used with
signal
.
The
sigaction
structure, which contains
information that describes the action to be performed when a signal is received,
is defined as:
struct sigaction { _HANDLER sa_handler; sigset_t sa_mask; int sa_flags; };
sa_handler
is a pointer to the
signal handler;
sa_mask
is the signal mask
that will be used while the signal handler is running, and
sa_flags
specifies the flags that affect the handling of the signal.
Here is a brief example of how you can use the
sigaction
structure to define the action that
should be performed when a
SIGQUIT
signal
is received:
extern void quitHandler(int); #include <unistd.h> #include <signal.h> main() { struct sigaction quitAction; quitAction.sa_handler = quitHandler; sigfillset(&quitAction.sa_mask); quitAction.sa_flags = 0; sigaction(SIGQUIT, &quitAction, NULL); . . . } void quitHandler(int signum) { . . /* Signal handler code goes here. */ . }
If this code is executed, the
quitAction
signal handler is called whenever a
SIGQUIT
signal is received. The call to
sigfillset
causes the
quitAction.sa_mask
to
block all signals during the execution of the signal handler. Any signals
blocked by the signal-action mask are delivered after the handler returns.
Setting the
quitAction.sa_flags
to 0 specifies
that no flags are used to modify the behavior of the signal. See the description
of
sigaction
for a discussion of the signal
action flags that you can specify.
Notice that the
sigaction
function does not require you to reinstate the signal handler within
the signal handling function itself. The handling of a signal identified by
sigaction
is not reset to the default
action after an occurrence of the signal. This behavior is different from
the behavior of a signal handler identified by the
signal
function.
ABEND Handling |
Before Release 6.00, SAS/C used the signal
SIGTERM
to represent a system
ABEND of a C program.
USS defines the signal
SIGABND
for this
purpose. Therefore, with Release 6.00, SAS/C uses
SIGABND
rather than
SIGTERM
to represent
an ABEND to be compatible with USS and to allow programs to handle
SIGTERM
in a more portable fashion.
Note:
SIGABND
has been assigned the old signal number
for
SIGTERM
and
SIGTERM
has been given a new signal number. Thus, existing load modules
that use the
SIGTERM
signal to intercept
system ABENDs continue to work until they are recompiled.
SAS/C uses the signal
SIGABRT
to represent user ABENDs including library ABENDs. This is different
from USS, which expects all ABENDs to be treated as
SIGABND
.
Note:
If library ABEND handling is suppressed
by the
=nohtsig
run-time option, or if
library errors occur handling an ABEND, USS reports the status of an ABEND
as terminated by
SIGKILL
rather than as terminated by
SIGABND
.
Getting More Information about a Signal |
For
some signals, you can get more information about the signal
by calling the
siginfo
function in the
signal handler. The
siginfo
function returns
a pointer to the information associated with the signal being handled.
For example, when
SIGMEM
is raised, a call to
siginfo
provides
information on the number of bytes of memory needed for additional stack space.
If
SIGFPE
is raised,
siginfo
returns pointers to data that can be modified by the handler.
For example, when
SIGFPE
is raised by
a floating-point overflow, the information returned by
siginfo
includes the result of the computation that caused the overflow.
You can replace this value and resume execution.
Some signals have no additional information available.
If you call
siginfo
for one of these signals
or if no signal has occurred,
siginfo
returns
NULL
. Refer to the descriptions of each signal
for details on the information returned by
siginfo
. Summary of Information from siginfo summarizes the information returned by
siginfo
.
Note:
siginfo
is not a standard C function; avoid using it in programs that must be portable.
The return value of
siginfo
is always 0 for any signal managed by USS,
unless the signal was generated
by
siggen
or the signal was a program check
or ABEND directly associated with a program error.
Default Signal Handling |
If
you do not define a special handler for a signal or invoke a signal handler
with the
signal
function and do not reinstate
signal handling, the library performs default actions specific to each signal.
You can also invoke default signal handling by using the special action
SIG_DFL
as the second argument to
signal
. For most signals, the default action is to abnormally terminate
the program. Detailed discussions of default actions are in Signal Descriptions; default actions are listed
in Summary of Default Actions.
Ignoring Signals |
If
you want to ignore the occurrence of a signal, specify the special action
SIG_IGN
as the second argument to
signal
. Ignoring a signal causes the program to resume execution at
the point at which the signal occurred. Some signals, such as
SIGABRT
, cannot be ignored because it is impossible to resume program
execution at the point at which these signals occur.
Also, some signals such as
SIGSEGV
should not be ignored when they are managed by USS, even though
it is possible to do so because the results are unpredictable. These signals
are ignored if the specified action is
SIG_IGN
and they are generated by a call to the
kill
function; however, if the signal is generated by either a program
check or an ABEND, the most likely result is that another ABEND will occur.
Summary of Ignoring Signals lists which signals can be ignored. For more information, refer to the descriptions of the signals.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.