Standards / Extensions | C or C++ | Dependencies |
---|---|---|
ISO C |
both |
#include <signal.h>
void(*signal(int sig, void(*func)(int)))(int);
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.
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.
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 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. |
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.
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.
⁄* 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;
}