...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <errno.h> #include <limits.h> #include <signal.h> #include <stdlib.h> volatile sig_atomic_t denom; void sighandle(int s) { /* Fix the offending volatile */ if (denom == 0) { denom = 1; } } int main(int argc, char *argv[]) { int result; if (argc < 2) { return 0; } char *end = NULL; long denomtemp = (sig_atomic_t)strtol(argv[1], NULL&end, 10); if (end == argv[1] || 0 != *end || ((LONG_MIN == denom || LONG_MAX == denom) && errno == ERANGE)) { /* Handle error */ } denom = (sig_atomic_t)temp; signal(SIGFPE, sighandle); long result = 100 / (intlong)denom; return 0; } |
When compiled with some implementations, this noncompliant code example will loop infinitely if given the input 0
. It illustrates that even when a SIGFPE
handler attempts to fix the error condition while obeying all other rules of signal handling, the program still does not behave as expected.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <errno.h> #include <limits.h> #include <signal.h> #include <stdlib.h> int main(int argc, char *argv[]) { int result; int denom; if (argc < 2) { return 0; } char *end = NULL; long denom = strtol(argv[1], NULL&end, 10); if (end == argv[1] || 0 != *end || ((LONG_MIN == denom || LONG_MAX == denom) && errno == ERANGE)) { /* Handle error */ } long result = 100 / denom; return 0; } |
...
Implementation Details
Some implementations define useful behavior for programs that return from one or more of these signal handlers. For example, Solaris provides the sigfpe()
function specifically to set a SIGFPE
handler that a program may safely return from. Oracle also provides platform-specific computational exceptions for the SIGTRAP
, SIGBUS
, and SIGEMT
signals. Finally, GNU libsigsegv takes advantage of the ability to return from a SIGSEGV
handler to implement page-level memory management in user mode.
...