The signal() function behaves differently in Windows than it does on Linux/BSD systems. When a signal handler is installed with the signal() function in Windows, the default action is restored for that signal after the signal is triggered. Conversely, Linux/BSD systems leave the signal handler defined by the user in place until it is explicitly removed.
This non-complaint code example fails to persist the signal handler on Windows platforms.
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t e_flag = 0;
void handler(int signum) {
e_flag = 1;
}
int main(void) {
signal(SIGINT, handler);
while(!e_flag) {}
puts("Escaped from first while()");
e_flag = 0;
while(!e_flag) {}
puts("Escaped from second while()");
return 0;
}
|
When compiled with gcc 3.4.4 and executed under Red Hat Linux, the signal handler is automatically reinstalled upon handler execution.
% ./SIG01-A ^C Escaped from first while() ^C Escaped from second while() % |
However, when compiled with Microsoft Visual Studio 2005 version 8.0 and executed under Windows the signal handler is not automatically reinstalled.
> SIG01-A.exe ^C Escaped from first while() ^C > |
The second interrupt executes the default action for SIGINT, which is to terminate program execution.
A C99-compliant solution to persist the handler on a Windows system is to rebind the signal to the handler in the first line of the handler itself.
void handler(int signum) {
signal(signum, handler);
/* rest of handling code */
}
|
Failure to re-establish a persistent signal handler on Windows platforms can lead to unexpected behavior.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
SIG01-A |
1 (high) |
1 (likely) |
3 (low) |
P3 |
L3 |
\[[ISO/IEC 9899-1999TR2|AA. C References#ISO/IEC 9899-1999]\] "The {{signal}} function" |