signal() — Handle interrupts
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
ISO C
POSIX.1 POSIX.4a XPG4 XPG4.2 C99 Single UNIX Specification, Version 3 |
both |
Format
#include <signal.h>
void(*signal(int sig, void(*func)(int)))(int);
General description
Allows a process to choose one of several ways to handle an interrupt signal sig from the operating system or from the raise() function.
The sig argument
must be one of the macros defined in the signal.h
header
file. See Table 1.
The func argument
must be one of the macros, SIG_DFL or SIG_IGN, defined in the signal.h
header
file, or a function address.
If the value of func is SIG_DFL, default handling for that signal will occur. If the value of func is SIG_IGN, the signal will be ignored. Otherwise, func points to a function to be called when that signal occurs. Such a function is called a signal handler.
- First the equivalent of
signal(sig,SIG_DFL);
is executed or an implementation-defined blocking of the system is performed. (If the value of sig is SIGILL, the occurrence of the reset to SIG_DFL is implementation-defined.) - Next, the equivalent of
(*func)(sig);
is executed. The function func may terminate by executing areturn
statement or by calling the abort(), exit(), or longjmp() function. If func executes a return statement and the value of sig was SIGFPE or any other implementation-defined value corresponding to a computational exception, the behavior is undefined. Otherwise, the program will resume execution at the point it was interrupted.
If a signal occurs for a reason other than having called
the abort() or raise() function, the behavior is undefined if the
signal handler calls any function in the standard library other than
the signal() function itself (with a first argument of the signal
number corresponding to the signal that caused the invocation of the
handler). Behavior is also undefined if the signal handler refers
to any object with static storage duration other than by assigning
a value to a static storage duration variable of type volatile
sig_atomic_t
. Furthermore, if such a call to the signal()
function returns SIG_ERR, the value of errno is indeterminate.
At
program startup, the equivalent of signal(sig, SIG_IGN);
may
be executed for some selected signals. The equivalent of signal(sig,
SIG_DFL);
is executed for all other signals.
- Value
- Meaning
- SIG_DFL
- Default handling for the signal will occur.
- SIG_IGN
- The signal is to be ignored.
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
These calls may be made either in the source or they can be made from the HLL user exit CEEBINT, which will require a re-link.
Special behavior for POSIX: For a z/OS® UNIX C application running POSIX(ON), the interrupt signal can also come from kill() or from another process. A program can use sigaction() to establish a signal handler; sigaction() blocks the signal while the signal handler has control. If you use signal() to establish a signal handler, the signal reverts back to the default action. If you want the signal handler to get control for the next signal of this type, you must reissue signal().
signal(sig, func)
is
equivalent to sigaction(sig, &act, NULL)
,
where act points to a sigaction structure
containing an sa_action of func, an sa_mask
by sigemptyset(), and an sa_flags containing _SA_OLD_STYLE.
For a list of considerations for coding signal-catching functions that will support asynchronous signals, refer to sigaction() — Examine or change a signal action.
The sig argument must be one of the macros defined in the signal.h header file.
- The behavior when mixing signal-handling with C++ exception handling is undefined. Also, the use of signal-handling with constructors and destructors is undefined.
- C++ and
C language linkage conventions are incompatible, and therefore signal()
cannot receive C++ function
pointers. If you attempt to pass a C++ function
pointer to signal(), the compiler will flag it as an error. Therefore,
to use the signal() function in the C++ language,
you must ensure that signal handler routines established have C linkage,
by declaring them as
extern "C"
.
The signals supported are listed below.
Value | Default Action | Meaning |
---|---|---|
SIGABND | 1 | Abend |
SIGABRT | 1 | Abnormal termination (sent by abort()) |
SIGFPE | 1 | Arithmetic exceptions that are not masked, for example, overflow, division by zero, and incorrect operation |
SIGILL | 1 | Detection of an incorrect function image |
SIGINT | 1 | Interactive attention |
SIGSEGV | 1 | Incorrect access to memory |
SIGTERM | 1 | Termination request sent to the program |
SIGUSR1 | 1 | Intended for use by user applications |
SIGUSR2 | 1 | Intended for use by user applications |
SIGIOERR | 2 | A serious I/O error was detected. |
- 1
- Normal termination of the process.
- 2
- Ignore the signal.
When the runtime option POSIX(ON) is specified, if a signal catcher for a SIGABND, SIGFPE, SIGILL or SIGSEGV signal runs as a result of a program check or an ABEND, and the signal catcher executes a RETURN statement, the process will be terminated.
Returned value
If successful, signal() returns the most recent value of func.
If unsuccessful, signal() returns a value of SIG_ERR and a positive value in errno.
There are no documented errno values. If an error occurs, issue perror() using the errno value.
Example
/* CELEBS20
This example shows you how to establish a signal handler.
*/
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#define ONE_K 1024
#define OUT_OF_STORAGE (SIGUSR1)
/* The SIGNAL macro does a signal() checking the return code */
#define SIGNAL(handler, StrCln) { \
if (signal((handler), (StrCln)) == SIG_ERR) { \
perror("Could not signal user signal"); \
abort(); \
} \
}
#ifdef __cplusplus /* the __cplusplus macro */
extern "C" void StrCln(int); /* is automatically defined */
#else /* by the C++/MVS compiler */
void StrCln(int);
#endif
void DoWork(char **, int);
int main(int argc, char *argv[]) {
int size;
char *buffer;
signal(OUT_OF_STORAGE, StrCln);
if (argc != 2) {
printf("Syntax: %s size \n", argv[0]);
return(-1);
}
size = atoi(argv[1]);
DoWork(&buffer, size);
return(0);
}
void StrCln(int SIG_TYPE) {
printf("Failed trying to malloc storage\n");
signal(SIG_TYPE, SIG_DFL);
exit(0);
}
void DoWork(char **buffer, int size) {
int rc;
while (*buffer !=NULL)
*buffer = (char *)malloc(size*ONE_K);
if (*buffer == NULL) {
if (raise(OUT_OF_STORAGE)) {
perror("Could not raise user signal");
abort();
}
}
return;
}
Related information
- Signal-handling in z/OS XL C/C++ Programming Guide.
- signal.h — Exception handling
- abort() — Stop a program
- atexit() — Register program termination function
- bsd_signal() — BSD version of signal()
- exit() — End program
- kill() — Send a signal to a process
- pthread_kill() — Send a signal to a thread
- raise() — Raise signal
- sigaction() — Examine or change a signal action
- sigignore() — Set disposition to ignore a signal
- sigprocmask() — Examine or change a thread
- sigset() — Change a signal action or a thread
- sigsuspend() — Change mask and suspend the thread
- waitid() — Wait for child process to change state
- wait3() — Wait for child process to change state