Release 6.00 of the SAS/C library provides OpenEdition and POSIX support for signal handling. Consequently, many new signals and signal-handling functions have been added to the library. Wherever possible, the SAS/C library preserves the behavior of previously existing signal-handling programs and treats POSIX signals and non-POSIX signals similarly. Where the POSIX definition of a signal and the SAS/C definition differ, a choice of behavior is offered on a per-signal basis.
sigchk
is called to
discover pending asynchronous signals. See
Discovering Asynchronous Signals for details on how the SAS/C library
treats asynchronous signals.
SIGABND SIGFPOFL SIGMEM SIGABRT SIGFPUFL SIGSEGV SIGFPDIV SIGIDIV SIGTERM SIGFPE SIGILLEight synchronous user signals (
SIGUSR1 through SIGUSR8
) are also
available.
SIGALRM SIGIUCV SIGINTEight asynchronous user signals (
SIGASY1 through SIGASY8
) are also
available.
SIGPIPE
may be raised synchronously by
OpenEdition when an attempt is made to read a pipe without a
writer process, or it may be raised asynchronously by another process's
use of the kill
function to send this signal. Each signal has a
default action, which is usually abnormal process termination, with
some exceptions. For example, the default handling for the SIGTSTP
signal is to suspend process execution.
Almost all signals can be blocked, which means they are delayed
from having an effect on the target process until that process
unblocks the signal. (Two signals, SIGKILL
and SIGSTOP
,
cannot be blocked. These signals also cannot be handled and, therefore,
always cause their default actions.)
Note:
This definition differs considerably from the way SAS/C previously
implemented signals. Traditionally, SAS/C only allowed
asynchronous signals to be blocked. The synchronous/asynchronous
distinction does not apply to POSIX signals, and blocking has an
effect even on synchronously generated signals like SIGPIPE
,
with a few exceptions.
Signals managed exclusively by SAS/C are
SIGASY1-8
SIGFPDIV
SIGFPOFL
SIGFPUFL
SIGIDIV
SIGIUCV
SIGMEM
SIGUSR3-8
SIGCHLD
SIGCONT
SIGHUP
SIGKILL
SIGPIPE
SIGQUIT
SIGSTOP
SIGTRAP
SIGTSTP
SIGTTIN
SIGTTOU
SIGABND
SIGABRT
SIGALRM
SIGFPE
SIGILL
SIGINT
SIGIO
SIGSEGV
SIGTERM
SIGUSR1-2
<signal.h>
. Always refer to signals by their names, not their numbers,
because signal numbers are not portable.
Note:
The library permits you to raise the signals SIGIO
and SIGTERM
,
but at the present it does not assign a meaning to these signals.
oesigsetup
function enables you to
control which signals are managed by OpenEdition and which
use support internal to the SAS/C library. oesigsetup
must be
called before any other signal-related function.
If there is no call to oesigsetup
in a program called with
exec
linkage, the library assumes that all signals should be managed
by OpenEdition, if possible. If there is no call to oesigsetup
in a program not called with exec
linkage (a regular batch or TSO
execution), the library assumes that no signals should be managed
by OpenEdition.
Note:
This means that you must call oesigsetup
in a program
without exec
linkage if you need to use OpenEdition signals.
The arguments to oesigsetup
are two signal sets. The first defines
the set of signals to be managed by OpenEdition, and the second defines
the signals to be managed by SAS/C. oesigsetup
fails if any
signal is included in both sets; unspecified signals are handled as if
oesigsetup
had not been called.
SIGABND
, SIGABRT
,
SIGFPE,
SIGILL
, and SIGSEGV
. If these signals are
handled as SAS/C conditions,
OpenEdition is not informed of the error when the corresponding error condition occurs.
If the error leads to termination,
OpenEdition sets the final status of the terminated process to
terminated by SIGKILL
rather than a more specific status; otherwise,
you can expect no undesirable effects.
Note:
The SIGABND
signal is used in Release 6.00 of SAS/C software
to indicate a
system ABEND. As described in the next section, this is a behavior change from previous versions
of SAS/C.
SIGALRM
,
SIGINT
, SIGIO
, SIGTERM
, SIGUSR1
, and
SIGUSR2
. If OpenEdition handles SIGALRM
, the
SAS/C extension functions alarmd
and sleepd
are not
available. If the SAS/C library handles SIGALRM
, the
ps
shell command does not accurately indicate when the
process is sleeping.
If SAS/C handles SIGINT
, SIGINT
is generated by use of
the TSO attention key for a program running under TSO.
If OpenEdition handles SIGINT
, SAS/C does not use the STAX
macro or
attempt to handle TSO attentions. Be aware that SAS/C handling of
SIGINT
is not useful in non-TSO address spaces.
SIGIO
has no special meaning at present to either OpenEdition
or SAS/C but might be used by future versions of either product.
SIGTERM
has no defined meaning to SAS/C and, therefore, can be
generated only by use of the raise
function if managed by SAS/C.
SIGUSR1
and SIGUSR2
have no special meaning to OpenEdition. If
oesigsetup
defines
these signals as managed by SAS/C, then you can use SAS/C
user-added signal support to
define a meaning for one of these symbols.
Note:
If you have defined a signal as handled by SAS/C and the signal
is generated by OpenEdition, the result is always the OpenEdition
default action for the signal. For example, if you define SIGTERM
as a SAS/C signal and establish a handler, after which another
process uses the kill
function to send your process a SIGTERM
signal, your handler will not be called and the process will be
terminated.
A program can use kill
to send a signal that oesigsetup
has defined as a signal managed by SAS/C. If a program sends the
signal to itself, only default handling will take place.
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 OpenEdition. 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.
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.
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.
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.
SIGTERM
to represent a
system ABEND of a C program. OpenEdition 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 OpenEdition 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 OpenEdition, 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,
OpenEdition reports the status of an ABEND as terminated by
SIGKILL
rather than as terminated by SIGABND
.
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
.
Table 5.1 summarizes the information returned by siginfo
.
Note:
siginfo
is not a standard C function; avoid using it in
programs that must be portable.
Table 5.1 Summary of Information from siginfo
Signal Information Returned by siginfo for Signals Raised Naturally
SIGABND pointer to structure of type ABND_t SIGABRT pointer to structure of type ABRT_t SIGALRM NULL SIGFPE pointer to structure of type FPE_t SIGFPDIV pointer to structure of type FPE_t SIGFPOFL pointer to structure of type FPE_t SIGFPUFL pointer to structure of type FPE_t SIGIDIV pointer to structure of type FPE_t SIGILL pointer to structure of type ILL_t SIGINT NULL SIGIUCV pointer to various types of structures; refer to Chapter 5, "Inter-User Communications Vehicle (IUCV) Functions," in the SAS/C Library Reference, Third Edition, Volume 2,& Release 6.00. SIGMEM pointer to integer SIGSEGV pointer to structure of type SEGV_t SIGTERM NULL
siginfo
is always 0 for any signal
managed by OpenEdition, unless the signal was generated by
siggen
or the signal was a program check or ABEND directly
associated with a program error.
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 Table 5.2.
Table 5.2 Summary of Default Actions
Signal Default Action Default Action SAS/C Library OpenEdition (SIG_DFL Handler) (SIG_DFL Handler)
SIGABND ABEND with system code ends the process ABE SIGABRT ABEND with user code ends the process 1210 SIGALRM ABEND with user code ends the process 1225 SIGCHLD not supported signal is ignored SIGCONT not supported continues a stopped process; otherwise, the signal is ignored SIGFPDIV ABEND with 0CF. not supported SIGFPE raises another signal: ends the process SIGFPOFL, SIGFPUFL, SIGFPDIV, or SIGIDIV. Refer to the descriptions of these signals for defaults. SIGFPOFL ABEND with 0CC not supported SIGFPUFL changes result of not supported computation to 0; execution continues SIGHUP not supported ends the process SIGKILL not supported ends the process SIGIDIV ABEND with 0C9 not supported SIGILL ABEND with appropriate ends the process code (0C1, 0C2, 0C3, or 0C6) SIGINT no default actions by ends the process library; TSO default action is to ABEND; CMS default action ignores the signal SIGIO ignored ignored SIGIUCV ABEND with user code not supported 1225 SIGMEM attempts to continue not supported execution; ABEND with code 80A (under TSO) or 0F7 (under CMS) if more than 4K of stack space is required. SIGPIPE not supported ends the process SIGQUIT not supported ends the process SIGSEGV ABEND with appropriate ends the process code (0C4 or 0C5) SIGSTOP not supported stops the process SIGTERM ABEND with user code ends the process 1225 SIGTRAP not supported ends the process SIGTSTP not supported stops the process SIGTTIN not supported stops the process SIGTTOU not supported stops the process
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 OpenEdition, 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.
Table 5.3 lists which signals can be ignored. For more information, refer to the descriptions of the signals.
Table 5.3 Summary of Ignoring Signals
Signal SAS/C Library OpenEdition Ignored Signals Ignored Signals (SIG_IGN Handler) (SIG_IGN Handler)
SIGABND cannot be ignored; should not be ABEND as described in ignored; results Table 5.2 unpredictable SIGABRT cannot be ignored; should not be ABEND as described in ignored; results Table 5.2 unpredictable SIGALRM program continues; program continues; signal has no effect signal has no effect SIGCHLD not supported program continues; signal has no effect SIGCONT not supported program continues; signal has no effect SIGFPDIV program continues; not supported result of computation undefined SIGFPE program continues; same as SAS/C result of computation undefined except for SIGFPUFL signals (see SIGFPUFL ) SIGFPOFL program continues; not supported result of computation undefined SIGFPUFL program continues; not supported result of computation set to 0 SIGHUP not supported program continues; signal has no effect SIGKILL not supported cannot be ignored SIGIDIV program continues; not supported result of computation undefined SIGILL cannot be ignored; should not be ABEND as described in ignored; results Table 5.2 unpredictable SIGINT use of ATTN or PA1 key program continues; under MVS, or IC signal has no effect command under CMS; signal has no effect SIGIO program continues; program continues; signal has no effect signal has no effect SIGIUCV cannot be ignored; not supported ABEND as described in Table 5.2 SIGMEM execution continues not supported until storage exhausted SIGPIPE not supported program continues; signal has no effect SIGQUIT not supported program continues; signal has no effect SIGSEGV cannot be ignored; should not be ABEND as described in ignored; results Table 5.2 unpredictable SIGSTOP not supported cannot be ignored SIGTERM program continues; not supported signal has no effect SIGTRAP not supported program continues; signal has no effect SIGTSTP not supported program continues; signal has no effect SIGTTIN not supported program continues; signal has no effect SIGTTOU not supported program continues; signal has no effect
SIGFPOFL
signal if it determines that an overflow is certain
to occur during its processing.
The library provides three functions for generating signals:
raise
, siggen
, and kill
.
raise
is an ISO/ANSI Standard function
that raises the signal you pass as the argument.
siggen
is
provided by the SAS/C library; it is not portable. Besides raising the
signal you pass, siggen
also enables you to define the
value returned by a subsequent call to siginfo
.
kill
is a POSIX function used to send a signal to a process.
A process can use the
kill
function to send a signal to itself.
However, kill
does not support SAS/C signals, and it can only be
used with signals managed by OpenEdition.
If you raise a signal with raise
or siggen
the handler is
called immediately, even if the signal is asynchronous, unless it is a
blocked signal managed by OpenEdition. Therefore, these functions are not
useful for testing signal blocking.
If you use raise
or siggen
to generate a signal with no
special handler defined and the default action is abnormal termination,
the program abnormally terminates. However, this abnormal termination
may not be exactly the same as it would be if the signal had occurred
naturally.
User-defined signals (SIGUSR1 through SIGUSR8
and
SIGASY1 through SIGASY8)
can be generated by using raise
or
siggen
. Refer to Chapter 12, "User-Added Signals," in the SAS/C Library Reference, Volume 2
for another method of raising user-defined signals.
sigchk
is called to discover pending
asynchronous signals.
sigchk
in your program to decrease the
number of statements that are executed before a signal is discovered.
The library limits the times that an asynchronous signal can be discovered to improve your control of signal handling. There are two reasons the SAS/C library delays processing asynchronous signals:
exit
and longjmp
. Using these facilities
bypasses return to the operating system, which causes
unpredictable results. By limiting signal discovery (and signal
handling) to times when the library has control, the library permits
you to use all of the facilities
of C, including longjmp
and
exit
. (For some signals under CMS, I/O also would not be available
to handlers if they were called immediately.)
++elements; table[elements] = value;If a signal handler were called between these two statements, an attempt by a handler to add an element to the table would cause an entry to be skipped. Knowing that signals are not discovered at this point, you do not need to worry about skipped entries.
Note: Combining the two statements into one does not improve the situation because signals can occur between any two machine instructions whether or not they are part of the same statement.
This method of discovering asynchronous signals is a feature of the SAS/C implementation. If you are writing portable code be aware that, on some systems, handlers are always called immediately. In such systems, you must write code carefully to avoid incorrect results if signals are inconveniently timed.
sigaction
function makes it
easy to block signals during the execution of a signal handler.
For non-POSIX applications, the situation is more complicated, and
it may be difficult to block asynchronous signals during the execution
of a signal handler. To assist in the writing of reliable code, the
SAS/C library suppresses the discovery of new asynchronous signals within
a handler. An exception is when the handler calls sigchk
, signal
, or
sigaction
, which indicates its readiness to handle new signals. This
applies only to asynchronous signals; for example, if a handler divides by 0,
the resulting signal cannot be delayed no matter how convenient that might be.
Also, any signals that are pending while a handler executes are
discovered and processed when the handler returns.
If you are writing portable code be aware that, on some systems, asynchronous signals are discovered even while a handler is executing. On such systems, you must write code carefully to avoid incorrect results if signals are inconveniently timed.
pause
, sigpause
, and sigsuspend
suspend execution
until a signal is received
ecbpause
and ecbsuspend
wait
for either a signal or for an Event Control Block (ECB) to be posted
sleep
and sleepd
suspend execution until a signal is
received or an elapsed time interval expires. If a signal is received while
program execution is suspended by one of these functions, the signal is handled
immediately, unless the signal is blocked.
sigprockmask
and sigsuspend
sigprocmask
and sigsuspend
are portable to
POSIX-conforming systems.
sigblock
, sigsetmask
, and sigpause
sigblock
, sigsetmask
, and sigpause
are provided for compatibility with previous releases of SAS/C and code
that will be ported to BSD UNIX operating systems. You are
encouraged to use sigprockmask
and sigsuspend
when possible
because they are more flexible, and they can handle signals managed by
both SAS/C and OpenEdition.
sigprocmask
function
manipulates a signal mask that determines which signals are blocked.
A blocked signal is not ignored; it is simply blocked from having any
effect until the signal mask is reset. SIGKILL
and
SIGSTOP
cannot be blocked by sigprocmask
; otherwise, all
signals managed by OpenEdition may be blocked. You can also use
sigprocmask
to block any of the asynchronous signals managed by SAS/C.
The sigprocmask
function receives sigset_t
structures for both
a new and an old signal mask. sigprocmask
also requires
one of the following int
arguments that specify how to use these signal masks.
SIG_BLOCK
SIG_UNBLOCK
SIG_SETMASK
Here is an example that illustrates the sigprocmask
function:
#include <sys/types.h> #include <signal.h> #include <lcsignal.h> #include <stdlib.h> main() { sigset_t omvsManaged, sascManaged, pendingSignals, newMask, oldMask; sigfillset(&omvsManaged); /* Request OpenEdition management */ sigemptyset(&sascManaged); /* of all signals. */ sigemptyset(&pendingSignals); sigemptyset(&newMask); sigemptyset(&oldMask); /* Tell the system which signals should be managed by SAS/C */ /* and which by OpenEdition. */ oesigsetup(&omvsManaged, &sascManaged); /* Block the SIGHUP signal. */ sigaddset(&newMask, SIGHUP); sigprocmask(SIG_BLOCK, &newMask, &oldMask); /* Actions to take while SIGHUP is blocked go here. */ /* Check to see if SIGHUP is pending. */ sigpending(&pendingSignals); if (sigismember(&pendingSignals, SIGHUP){ /* Actions to take if SIGHUP is pending go here. */ } /* Restore the old mask. */ sigprocmask(SIG_SETMASK, &oldMask, NULL); . . . }Notice that if you don't like the defaults value for signal management you must use
oesigsetup
to specify which signals are managed
by OpenEdition before you can use sigprocmask
to block
a signal.
The sigpending
function can be used to determine whether any
signals are pending. A pending signal is a blocked signal
that has occurred and for which the signal action is still pending.
The sigset_t
structure passed to sigpending
is filled with
the pending signals for the calling process. You can also use the
sigismember
function to determine if a specific signal is pending,
as illustrated in the previous example.
If a call to sigprocmask
causes the signal mask to be changed
so that one or more blocked signals become unblocked, then at least
one of these signals is delivered to the calling process before
the return from sigprocmask
. When the first signal is
delivered, the signal mask changes according to the action
specified for that signal; this might or might not reblock any
remaining pending signals. If there are remaining pending signals
blocked by the action for the first signal, then on return from the
handler, the previous mask is restored and the next signal is delivered,
and so on.
Note:
The sigsuspend
function also modifies the signal mask. See
Using sigsuspend and sigpause for more information.
sigblock
, sigsetmask
, and sigpause
functions
can also be used to block signals managed by SAS/C. However,
these functions cannot be used to block signals managed by OpenEdition.
Note:
None of the facilities described in this section are completely
portable. They are similar to facilities provided by the Berkeley 4.2
BSD UNIX implementation. The sigprocmask
function described in
the previous section provides a more flexible method of blocking signals.
When you generate a signal with raise
or siggen
, the library
permits the signal to be recognized even when it is blocked. Using the
sleep
function also permits the SIGALRM
signal to be recognized
even if it is blocked. In addition, the library may block signals
temporarily to preserve the integrity of its data areas as it performs
certain actions. When it has completed processing, the library
restores the mask defined by your program.
The library allows any asynchronous signal managed by SAS/C (those defined
by the library or SIGASY1 through SIGASY8
) to be blocked by use of the
functions sigblock
, sigsetmask
, and sigpause
.
Note: Signal blocking is meaningful only for asynchronous signals. Calls to these functions for synchronous signals do not generate errors; the calls have no effect.
All of the signal-blocking functions require an argument that changes
the bit string used to mask signals, but the effect of the argument
differs among the functions. The sigblock
function blocks the
signals indicated by the argument but does not change the rest of the
mask. sigsetmask
and sigpause
reset the mask so that only the
signals indicated by the argument are blocked.
The form of the argument is the same for sigblock
, sigsetmask
,
and sigpause
. Use the left shift operator as shown here to specify a
mask for a single signal:
1<<(signal - 1)
The following call to sigblock
sets the mask to block interrupt
signals in addition to any other masks already in effect:
/* Block SIGINT; retain rest of mask. */ sigblock(1<<(SIGINT - 1));A similar call to
sigsetmask
changes the mask so that only
interrupt signals are blocked:
sigsetmask(1<<(SIGINT - 1)); /* Block only SIGINT */
To block several signals with the sigsetmask
function, use the
bitwise OR operator. For example, this code blocks both the
interrupt signal and the user-defined signal SIGASY1
:
/* Block SIGINT and SIGASY1. */ sigsetmask(1<<(SIGINT - 1)|1<<(SIGASY1 - 1));
sigprocmask
, sigblock
, and
sigsetmask
are typically used to
protect the execution of small sections of code that must run
without interruption. To do this, use one of the signal-blocking
functions to block interruptions before beginning the critical code.
Then, when the critical actions are completed, restore the mask that
was in effect before all signals were blocked. For example, the
following code calls sigprocmask
to block the additional signals
identified by blockedSignals
and store the
previous mask in oldMask
. Note that the new mask is the
union of the current signal mask and the additional signals that are
identified by blockedSignals
. The example then calls
sigprocmask
a second time to restore the previous mask after the
critical code is completed:
sigprocmask(SIG_BLOCK, &blockedSignals, &oldMask); /* Block signals. */ take_ckpt(); /* Checkpoint data. */ sigprocmask(SIG_SETMASK, &oldmask, NULL); /* Restore previous mask. */In this example, you could instead use
sigsetmask
and sigblock
if you were blocking only signals managed by SAS/C. Both sigblock
and
sigsetmask
return the previous signal mask. For example, you could call
sigblock
as follows to block all signals and
store the value of the old mask in oldMask
:
oldMask = sigblock(0xffffffff);
Besides sigprocmask
, sigblock
, and sigsetmask
, the
library provides the sigsuspend
and sigpause
functions. These
functions combine the actions of the pause
and sigprocmask
functions. Here is an example of a call to sigsuspend
:
sigsuspend(&newMask);The call to
sigsuspend
has approximately the same effect as the
following code:
sigprocmask(SIG_SETMASK, &newMask, &oldMask); pause(); sigprocmask(SIG_SETMASK, &oldMask, NULL);
sigpause
is similar to sigsuspend
except that its signal
mask is in the BSD format rather than the POSIX sigset_t
format,
and it only allows you to change the blocking of signals managed by SAS/C.
There is one important difference between the call to sigsuspend
and
the sequence of the other function calls shown when sigsuspend
is
used: the second call to sigprocmask
occurs before any handler is called.
sigsuspend
and sigpause
are useful for interrupt-driven programs,
which can perform necessary processing with all signals blocked and then pause
with some or all signals unblocked when the program is ready to receive another
signal. If a signal is pending, the handler for that signal is called; otherwise,
the program waits until a new signal is received. In either case, the old mask,
which blocked all signals, is restored before the handler is called.
This ensures that no signals are discovered during execution of the
handler, which guarantees that all signals are processed one at a time in
the order they are received. Thus, processing of one signal is never
interrupted by another. Programs that process only one signal at a
time are more reliable and easier to write than those that permit
interruption during most or all of their execution. Refer to the
example in the description of sigpause
on page 5-16 for an illustration of how
to use these functions to process one signal at a time.
Signal blocking is useful even though, in many cases, the library suspends
processing of other asynchronous signals while a signal handler is
executing. Remember that the library allows processing of other
asynchronous signals as soon as the signal handler calls signal
to
reinstate signal handling. Even if the handler issues the call to
signal
as the last instruction in the function, the handler may not
complete execution before the next signal is discovered and handled.
Also, when you use sigaction
to define a signal handler, you can use
the arguments to sigaction
to further control the blocking of signals
within the handler. A signal is blocked during execution of a handler for a
signal discovered during a call to sigsuspend
or sigpause
if it
is blocked by either the signal mask in effect when sigsuspend
or
sigpause
were called, or by the mask specified by sigaction
.
SIGFPE
, SIGSEGV
,
SIGILL
, SIGINT
, SIGABRT
, and SIGTERM
. Note
that different implementations of C do not always generate signals for
the same reasons. For example, in some implementations, a floating-point
underflow may set the result to 0 instead of raising SIGFPE
. The
only signals that are guaranteed are those generated by calls to
raise
or abort
.
raise
and signal
are in the ANSI Standard library. The remaining
functions, which may be convenient, cannot be used in a portable
program. The functions sigaction
, sigprocmask
, sigpending
,
and sigsuspend
are portable to other systems that implement the POSIX
1003.1 standard.
signal
again immediately after entering the handler. This call
minimizes the chance that the same signal will occur again and cause
program termination.
Note:
If you are writing programs to run only with the SAS/C
library, you can delay calling signal
until the end of the handler,
because new asynchronous signals are not discovered until the handler
returns, or signal
is called. If you call signal
at the
beginning of the handler to reinstate signal handling, refer to the
third list item.
longjmp
in a signal handler.
Also, in implementations other than SAS/C, library data may be left in
an inconsistent state if longjmp
is called in a handler after a
library function is interrupted. This can cause unpredictable results
if the same function or a related function is called again. (The SAS/C library
uses the blkjmp
function in many cases to intercept longjmp
from a handler, so the problem should not arise in a SAS/C program,
except for signals associated with ABEND.)
longjmp
, abort
,
exit
, or signal
from a handler is dangerous. This is
especially true of memory allocation and I/O functions.
signal
.
static volatile sig_atomic_t
variable defined outside the handler.
(The SAS/C library defines sig_atomic_t
as char
.)
static
variable
set by the handler to determine whether a signal has occurred. Even using
this process, incorrect results can occur if the compiler optimizes references
to the variable. Making the variable volatile
may help prevent such
optimizations.
signum
argument
even if it is not used in the handler. Here is an example:
void int_handler(int signum)
Some of the ways you can use the library facilities to control when signals must be handled are discussed here. Note that these techniques, with the exception of the first one, are specific to the SAS/C library.
sigprocmask
or sigblock
before
calling the function to minimize the chance of being interrupted. Then
call sigprocmask
or sigsetmask
to restore the signal mask
when the critical activity is completed. The call to sigprocmask
or sigblock
allows any pending signals to be
discovered, so interruption is possible at this point. However, if no
signals are pending, no other interruptions occur until you reset the
mask with sigprocmask
or sigsetmask
.
signal
in the handler for as long as possible. The
library postpones processing new asynchronous signals while a handler
is executing, unless the handler calls sigchk
or signal
.
As soon as you call signal
, any pending signals are
discovered and handled. Alternately, use sigaction
rather than
signal
to define your handlers. In this case, you do not need to call
signal
again to reinstate your handler, and you can have any signals
you wish blocked automatically during the handler's execution.
sigprocmask
to block signals until the program is ready to process
interruptions. When an interruption can be processed, call sigsuspend
to wait
for the next signal. When the signal occurs, the library automatically
restores the pre-sigsuspend
signal mask before calling
your handler.
sigchk
to discover signals at points in your code that do not call any
functions. Be sure to select points at which all data structures used by
handlers are in a consistent state.
longjmp
function, you may want
to use the blkjmp
function in routines that can be interrupted to
protect some portions of the routine. This permits the routine to
successfully complete activities that should not be interrupted. Note
that if a handler calls longjmp
while I/O is being performed, the
error flag is set for the file. You must call clearerr
to
continue to use the file, but be aware that information may be lost
from the file.
SIGINT
signal (as well as OpenEdition signals
such as SIGTTIN
) can occur at any time while the program is waiting
for input from the terminal.
SIGIO
. (The SIGIO
signal is not included because it
currently has no special meaning for the SAS/C library.)
Each description explains the information returned by a call to
siginfo
when a signal is generated naturally. When your
program raises a signal by calling the raise
function, a call
to siginfo
returns NULL
except where noted otherwise.
If the program raises a signal by calling siggen
, siginfo
returns the value of the second argument to siggen
.
Note:
The POSIX signals (SIGCHLD
, SIGCONT
, SIGHUP
,
SIGKILL
, SIGPIPE
, SIGQUIT
, SIGSTOP
, SIGTSTP
,
SIGTTIN
, and SIGTTOU
) are not included
in this section because all pertinent information about them is
contained in Tables 5.2 and 5.3 on pages 5-9 and 5-10, respectively.
For general information about POSIX
signal handling, refer to The POSIX.1 Standard: A Programmer's Guide.
siggen
, the ABEND code is taken from the ABRT_t
structure passed to siggen
.
SIGABND
signal cannot be ignored. Similarly, a handler for
SIGABND
cannot return to the point of interrupt; an attempt to do so causes
ABEND to be reissued.
siginfo
after a SIGABND
signal occurs, siginfo
returns a pointer to a structure of type ABND_t
. This structure
is defined as:
typedef struct { unsigned ABEND_code; /* ABEND code */ char *ABEND_str; /* formatted ABEND code, */ /* e.g., "B14", "U0240", */ void *ABEND_info; /* OS SDWA, or CMS ABWSECT */ } ABND_t;The
ABEND_code
contains the unmodified system ABEND code.
For example, after a system 106 ABEND, the ABEND_code value is 0x106.
The ABEND_str
is a null-terminated string giving a
printable form of the ABEND code.
The ABEND_info
pointer addresses an ABEND status block provided
by the operating system, which gives the ABEND PSW, registers, and other such
information. Under MVS, ABEND_str
addresses an SDWA. Under CMS, it
addresses an ABWSECT. For an ABEND issued by the SAS/C library,
ABEND_info
may be NULL
.
fopen
function may
ABEND if you attempt to open a file you are not authorized to access. If
you provide a SIGTERM
handler and use the longjmp
function to
continue program execution after such an ABEND, the library is not always able
to clean up after the failure. This may prevent memory or other resources
used by the library from being freed. For instance, after recovery from
an ABEND in fopen
, it may not be possible to open FOPEN_MAX
files.
SIGABRT
signal is raised when the abort
function is called or
when a user ABEND occurs. SIGABRT
may not be raised for an ABEND issued by
the SAS/C library, depending on the severity of the problem.
SIGABRT
causes abnormal program termination. If
SIGABRT
results from a call to abort
or raise
, the program is
terminated with user ABEND code 1210. If SIGABRT
results from a call
to siggen
, the ABEND code is taken from the ABRT_t
structure
passed to siggen
.
SIGABRT
signal cannot be ignored. Similarly, a handler for
SIGABRT
cannot return to the point of interrupt; an attempt to do so causes
ABEND to be reissued.
siginfo
after a SIGABRT
signal occurs, siginfo
returns a pointer to a structure of type ABRT_t
. This structure
is defined as:
typedef struct { unsigned ABEND_code; /* ABEND code */ char *ABEND_str; /* formatted ABEND code, */ /* e.g., "B14", "U0240", */ void *ABEND_info; /* OS SDWA, or CMS ABWSECT */ } ABRT_t;The
ABEND_code
is an integer from 0 through 4095 giving the ABEND code.
The ABEND_str
is a null-terminated string giving a printable form
of the ABEND code.
The ABEND_info
pointer addresses an ABEND status block provided by
the operating system, which gives the ABEND PSW, registers, and other such
information. Under MVS, ABEND_str
addresses an SDWA. Under CMS, it
addresses an ABWSECT. For an ABEND issued by the SAS/C library,
ABEND_info
may be NULL
.
SIGABRT
to signal a user ABEND, including a library ABEND.
This differs from OpenEdition, which expects every ABEND to be
signaled by SIGABND
.
SIGALRM
is an asynchronous signal. The SIGALRM
signal is
raised when a time interval specified in a call to the alarm
or
alarmd
function expires.
Because SIGALRM
is an asynchronous signal, the SAS/C library discovers
the signal only when you call a function, when a function returns, or
when you issue a call to sigchk
. For this reason and because of
inaccuracies and overhead in operating system timing functions, you can consider the
time interval requested by alarm
a lower bound; the handler may not be
invoked immediately after the interval expires.
SIGALRM
causes the program to abnormally terminate with a
user ABEND code of 1225.
SIGALRM
.
siginfo
is called in a handler for SIGALRM
, it returns
NULL
.
SIGALRM
is managed by OpenEdition, the SAS/C alarmd
and
sleepd
functions are not available. If
the SAS/C library manages SIGALRM
, the ps
shell command will not
accurately indicate when the process is sleeping.
SIGFPDIV
signal is raised when the second operand of the division
operator (/) is 0, and default handling is in effect for SIGFPE
. If you
have specified a handler for SIGFPE
(either SIG_IGN
or a function
you define), SIGFPDIV
is not raised.
SIGFPDIV
signal is raised and default handling is in effect, the
program abnormally terminates with an ABEND code of 0CF.
SIGFPDIV
, program execution continues, but the
results of the failed expression are unpredictable.
siginfo
after a SIGFPDIV
signal occurs, siginfo
returns a pointer to a structure of type FPE_t
. Refer to the
description of SIGFPE
for a discussion of this structure.
SIGFPDIV
, you can change the result of the
computation by using the information returned by siginfo
. Refer
to the example in the description of the siginfo
function for an
illustration of this technique.
SIGFPE
signal is raised when a computational error occurs. These
errors include floating-point overflow, floating-point underflow, and
either integer- or floating-point division by 0. Note that integer
overflow never causes a signal; when integer overflow occurs, the
result is reduced to 32 bits by discarding the most significant bits
and is then interpreted as a signed integer.
SIGFPE
is to raise a more specific signal for
the SIGFPOFL
, SIGFPUFL
, SIGFPDIV
, or
SIGIDIV
conditions. Handling of the more specific signal depends on whether a
handler has been defined for it. Refer to the descriptions of each of these
signals for more details.
SIGFPE
, the result of the computation that
raises SIGFPE
is undefined, unless the computation causes an underflow.
For underflows, the result is set to 0.
siginfo
after a SIGFPE
signal occurs, siginfo
returns a pointer to a structure of type FPE_t
. This structure
is defined as:
typedef struct { int int_code; /* interrupt code */ union { int *intv; /* result for integer expression */ double *doublev; /* result for double expression */ } result; char *EPIE; /* pointer to hardware program check info */ double *fpregs; /* floating-point register contents */ } FPE_t;The
int_code
field contains the number of the more specific signal
associated with the SIGFPOFL
, SIGFPUFL
,
SIGFPDIV
, or SIGIDIV
conditions. The result
field
is a pointer
to the result of the computation that raises the signal.
If you want to continue processing, you can change
the value that result
points to.
The EPIE
field is a pointer to a control block containing hardware
information available at the time the signal occurs. (This information
includes program status word and registers.) For information on the
EPIE format, see IBM publication
MVS/XA Supervisor Services and Macro Instructions.
(Although an EPIE is provided only
by the XA versions of the MVS and CMS operating systems, one is created
by the run-time library for all MVS and CMS systems.)
The fpregs
field is a pointer to an array of doubles that contains
the contents of the floating-point registers at the time of the signal
and stored in the order 0, 2, 4, 6.
SIGFPE
, you can determine what type of
error caused the signal by testing the int_code
field of the
information returned by siginfo
. You can also use this
information to reset the result of the computation by changing the
value that result
points to. Refer to the example in the
description of the siginfo
function for an illustration of this
technique.
SIGFPE
is managed by OpenEdition, the default action for
SIGFPE
is abnormal process termination, and SIGFPE
is never
converted into another signal. If you want to handle one or more of the
SIGFPDIV
, SIGFPOFL
, SIGFPUFL
,
or SIGIDIV
signals specific to SAS/C, you must define
SIGFPE
as a signal managed by SAS/C.
SIGFPOFL
signal is raised when the magnitude of the result of a
floating-point computation exceeds the maximum supported by the
hardware and default handling is in effect for SIGFPE
. If you have
specified a handler for SIGFPE
(either SIG_IGN
or a function you
define), SIGFPOFL
is not raised.
SIGFPOFL
signal is raised and default handling is in effect, the
program abnormally terminates with an ABEND code of 0CC.
SIGFPOFL
, program execution continues, but the
results of the failed expression are unpredictable.
siginfo
after a SIGFPOFL
signal occurs, siginfo
returns a pointer to a structure of type FPE_t
. Refer to the
description of SIGFPE
for a discussion of this structure.
SIGFPOFL
, you can change the result of the
computation by using the information returned by siginfo
. Refer
to the example in the description of the siginfo
function for an
illustration of this technique.
SIGFPUFL
signal is raised when the magnitude of the nonzero result
of a floating-point computation is smaller than the smallest nonzero
floating-point value supported by the hardware and default handling is
in effect for SIGFPE
. If you specified a handler for SIGFPE
(either SIG_IGN
or a function you define), SIGFPUFL
is not raised.
SIGFPUFL
signal is raised and default handling is in effect, the
result of the computation that raised the signal is set to 0 and
execution continues normally.
SIGFPUFL
, program execution continues, and the
result of the computation that raised the signal is set to 0.
siginfo
after a SIGFPUFL
signal occurs, siginfo
returns a pointer to a structure of type FPE_t
. Refer to the
description of SIGFPE
for a discussion of this structure.
SIGFPUFL
, you can change the result of the
computation by using the information returned by siginfo
. Refer
to the example in the description of the siginfo
function for an
illustration of this technique.
Note:
If a handler defined for SIGFPUFL
does not change the
value of the result, the result of the computation is undefined and it is
not automatically set to 0.
SIGIDIV
signal is raised when the second operand of a division
operator (/ or %) is 0 and default handling is in effect for SIGFPE
.
If you have specified a handler for SIGFPE
(either SIG_IGN
or a
function you define), SIGIDIV
is not raised.
SIGIDIV
signal is raised and default handling is in effect, the
program abnormally terminates with an ABEND code of 0C9.
SIGIDIV
, program execution continues but the
result of the computation that raised the signal is undefined.
siginfo
after a SIGIDIV
signal occurs, siginfo
returns a pointer to a structure of type FPE_t
. Refer to the
description of SIGFPE
for a discussion of this structure.
SIGIDIV
, you can change the result of the
computation by using the information returned by siginfo
. Refer
to the example in the description of the siginfo
function for an
illustration of this technique.
SIGILL
signal is raised when an attempt is made to execute an
invalid, privileged, or ill-formed instruction. SIGILL
is usually
caused by a program error that overlays code with data or by a call to
a function that is not linked into the program load module.
SIGILL
causes program termination with an appropriate ABEND
code (0C1 for an operation error, 0C2 for a privileged operation error,
0C3 for an execute error, or 0C6 for a specification error).
SIGILL
signal cannot be ignored. If you code SIG_IGN
as
the second argument to signal
, the call to signal
is rejected.
siginfo
in a handler for SIGILL
, siginfo
returns
a pointer to a structure of type ILL_t
. This structure is
defined as:
typedef struct { int int_code; /* interrupt code */ char *EPIE; /* pointer to hardware program check info */ } ILL_t;The
int_code
field of this structure contains the program code
indicating what type of illegal instruction occurred. Refer to
"Default handling" above.
The EPIE
field is a pointer to a control block containing hardware
information available at the time the signal occurred. (This
information includes program status word and registers.) For
information on the EPIE format, see IBM publication
MVS/XA Supervisor Services and Macro Instructions.
(Although an
EPIE is provided only by the XA versions of the MVS and CMS operating systems,
one is created by the run-time library for all MVS and CMS systems.)
SIGILL
, you can call siginfo
and test
the int_code
field of the structure (returned by a call to
siginfo
) to determine what error occurred. Note that a handler for
SIGILL
cannot return to the point of interrupt; an attempt to do so
causes the program to terminate as described in "Default handling" above.
SIGINT
is an asynchronous signal. The SIGINT
signal is raised
when the terminal user requests a program interruption. Under MVS, the terminal
PA1 or ATTN key raises the SIGINT
signal; under CMS, the IC (Interrupt C)
immediate command raises SIGINT
. However, if you are executing the program
using the debugger, you must use the debugger attn
command to generate a
SIGINT
signal. (The PA1/ATTN key or the IC command is intercepted and
handled by the debugger.) The debugger attn
command is handled as if
SIGINT
were raised by the normal methods.
SIGINT
signal. If the program is executing under MVS, the PA1/ATTN key is
handled by the program that invoked the C program (for example, ISPF or
the TSO terminal monitor program). If the program is executing under
CMS, the IC command is treated as an unknown command.
SIGINT
by coding SIG_IGN
as the second argument in
the call to signal
does not have the same effect as default handling. If
SIGINT
is ignored, use of the PA1/ATTN key or the IC command is
recognized but it has no effect on the program.
siginfo
is called in a handler for SIGINT
, it returns
NULL
.
SIGINT
is an asynchronous signal, the library discovers the
signal only when you call a function, when a function returns, or when
you issue a call to sigchk
. SIGINT
frequently occurs
while the program is reading from the terminal. If this occurs and the
handler for SIGINT
returns to the point at which the signal occurred, the
input request is reissued, unless the handler set the error flag for the file.
SIGIUCV
signal is raised as a result of communication between two
VM users. The SIGIUCV
signal can be generated only for programs that
have used the iucvset
function to initialize communication.
SIGIUCV
is an asynchronous signal. For this reason, a handler for
SIGIUCV
can only be invoked when a function is called or returns, or
when sigchk
is used.
SIGIUCV
causes the program to abnormally terminate with a
user ABEND code of 1225. For this reason, you must have a SIGIUCV
handler defined at all times that a signal can be discovered, if your
program uses SIGIUCV
.
SIGIUCV
signal cannot be ignored. If you code SIG_IGN
as the
second argument to signal
and an IUCV signal is received, the program
terminates, as described in "Default handling" above.
siginfo
in a handler for SIGIUCV
, it returns a pointer
to a structure of one of several types, depending on the particular
interrupt. This structure contains information about the communication
that caused the signal. For example, if the signal indicates that a
message has been sent by another user, you can call the iucvrecv
function to obtain the message text. Refer to Chapter 5, "Inter-User
Communications Vehicle (IUCV) Functions," in SAS/C Library Reference, Volume 2 for more information on
what is returned by siginfo
.
raise
or siggen
with SIGIUCV
has no effect
on the status of any pending signals. Signals generated with
raise
are always synchronous; that is, they are never delayed, even if
blocked, so an artificially generated SIGIUCV
signal may be handled
before any pending real SIGIUCV
signals.
SIGMEM
signal is raised when a function call requires additional
stack space, but little space is available. At the start of program
execution, 4K of stack space is reserved for emergency use; when no
other space is available, the SIGMEM
signal is raised. The reserved
stack space is available to ensure that you can still execute a handler
for the SIGMEM
signal.
Note:
If you use the =minimal
run-time option to suppress
stack overflow checking, the SIGMEM
signal does not occur. In this
case, if you run out of stack space, your program will probably ABEND as it
tries to write past the end of the stack.
SIGMEM
signal is to ignore the condition.
If the program can finish executing in the 4K of stack space reserved
for emergency use, the program completes normally. If the program
requires more than the emergency allocation, the program abnormally
terminates with an 80A ABEND in MVS or a 0F7 in CMS.
SIGMEM
, processing proceeds as described in
"Default handling" above.
siginfo
after a SIGMEM
signal occurs, siginfo
returns a pointer to an integer that contains the number of bytes
required. This is only an approximation, and there is no guarantee
that freeing this amount of memory will permit the failed allocation to succeed.
SIGMEM
handler is called when there is little memory
available, you should avoid using any functions that require large
amounts of memory. In particular, avoid opening files in a SIGMEM
handler. You also should avoid output to stdout
or stderr
,
unless these files have been used because these files are only
partially open until they are first used. If you want to handle SIGMEM
by writing an error message and terminating and you cannot guarantee
that you have already used the diagnostic file, use longjmp
to
exit from the handler and write the message on completion of the jump.
Termination of intermediate routines by longjmp
may cause
additional stack space to become available.
If the handler for SIGMEM
returns to the point of interrupt, another
attempt is made to allocate more stack space. If this attempt fails,
the emergency allocation is used if less than 4K is required. If the
emergency space is not sufficient, the program abnormally terminates.
After SIGMEM
is raised during a program's execution, it is not raised
again until one or more stack allocations have been successfully
performed. This avoids the possibility of endless loops in which
SIGMEM
is raised repeatedly.
SIGSEGV
signal is raised when you attempt to illegally access or
modify memory. SIGSEGV
is usually caused by using uninitialized or
NULL
pointer values or by memory overlays.
SIGSEGV
causes program termination with an appropriate
ABEND code (0C4 for a protection error or 0C5 for an addressing error).
SIGSEGV
signal cannot be ignored. If you code SIG_IGN
as the
second argument to signal
, the call to signal
is rejected.
siginfo
in a handler for SIGSEGV
, siginfo
returns
a pointer to a structure of type SEGV_t
. This structure is
defined as:
typedef struct { int int_code; /* interrupt code */ char *EPIE; /* pointer to hardware program check info */ } SEGV_t;The fields in this structure are the same as those in the structure type
ILL_t
; refer to the description of SIGILL
for details on
this structure.
SIGSEGV
, you can call siginfo
and test
the int_code
field of the structure (returned by a call to
siginfo
) to determine what error occurred. A handler for
SIGSEGV
cannot return to the point of interrupt; an attempt to do so
causes the program to terminate, as described in "Default handling" above.
Note:
If the program overlays library control blocks, the SIGSEGV
signal
may cause an immediate unrecoverable program ABEND, even when a signal
handler has been defined.
SIGTERM
signal can only be generated by a call to either
raise
or siggen
when SIGTERM
is managed by SAS/C.
SIGTERM
, program execution proceeds.
siginfo
is called in a handler for SIGTERM
, it
returns NULL
.
Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.