...
When a signal occurs, the normal flow of control of a program is interrupted. If a signal occurs that is being trapped by a signal handler, that handler is invoked. When it is finished, execution continues at the point at which the signal occurred. This arrangement can cause problems if the signal handler invokes a library function that was being executed at the time of the signal.
In general, it is not safe to invoke I/O functions are not safe to invoke inside from within signal handlers. Check your Make sure a function is included in the list of system's asynchronous-safe functions for all implementations your code will run on before using them in signal handlers.
...
In this noncompliant example, the C standard library function functions fprintf()
is and free()
are called from the signal handler via the function log_message()
. The Neither function free()
is also not asynchronous-safe, and its invocation from within a signal handler is also a violation of this rule.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h> #include <stdio.h> #include <stdlib.h> enum { MAXLINE = 1024 }; char *info = NULL; void log_message(void) { fprintf(stderr, info); } void handler(int signum) { log_message(); free(info); info = NULL; } int main(void) { if (signal(SIGINT, handler) == SIG_ERR) { /* Handle error */ } info = (char *)malloc(MAXLINE); if (info == NULL) { /* Handle Error */ } while (1) { /* Main loop program code */ log_message(); /* More program code */ } return 0; } |
...
In this noncompliant code example, the int_handler()
function is used to carry out SIGINT
-specific tasks out tasks specific to SIGINT
and then raises a SIGTERM
. However, there is a nested call to the raise()
function, which results in undefined behavior.
...
In this compliant solution, the call to the raise()
function inside handler()
is replaced by the functionality that was in the term handler: int_handler()
invokes term_handler()
instead of raising SIGTERM
.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <signal.h> void term_handler(int signum) { /* SIGTERM handling specific */ } void int_handler(int signum) { /* SIGINT handling specific */ /* Pass control to the term handler */ term_handler(SIGTERM); } int main(void) { if (signal(SIGTERM, term_handler) == SIG_ERR) { /* Handle error */ } if (signal(SIGINT, int_handler) == SIG_ERR) { /* Handle error */ } /* Program code */ if (raise(SIGINT) != 0) { /* Handle error */ } /* More code */ return EXIT_SUCCESS; } |
...
All functions not listed in this table are considered to be unsafe with respect to signals. In the presence of signals, all functions defined by Standard for Information Technology—Portable Operating System Interface (POSIX®), Base Specifications, Issue 7 (IEEE Std 1003.1, 2013 Edition) POSIX functions behave as defined when called from or interrupted by a signal handler, with a single exception: when a signal interrupts an unsafe function and the signal handler calls an unsafe function, the behavior is undefined.
...