...
Code Block |
---|
|
#include <signal.h>
#include <stdlib.h>
#include <string<stdio.h>
typedef void (*pfv)(int);
void handler(int signum) {
pfv old_handler = signal(signum, SIG_DFL);
if (old_handler == SIG_ERR) {
perror("SIGINT handler"); /* undefined behavior */
/* Handle error condition */
}
}
int main(void) {
pfv old_handler = signal(SIGINT, handler);
if (old_handler == SIG_ERR) {
perror("SIGINT handler");
/* Handle error condition */
}
/* Main code loop */
return 0EXIT_SUCCESS;
}
|
The call to perror()
from handler()
also violates SIG30-C. Call only asynchronous-safe functions within signal handlers.
...
Code Block |
---|
|
#include <signal.h>
#include <stdlib.h>
#include <string<stdio.h>
typedef void (*pfv)(int);
void handler(int signum) {
pfv old_handler = signal(signum, SIG_DFL);
if (old_handler == SIG_ERR) {
abort();
}
}
int main(void) {
pfv old_handler = signal(SIGINT, handler);
if (old_handler == SIG_ERR) {
perror("SIGINT handler");
/* Handle error condition */
}
/* Main code loop */
return 0EXIT_SUCCESS;
}
|
Noncompliant Code Example (POSIX)
...
Code Block |
---|
|
#include <stddef.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
void reaper(int signum) {
errno = 0;
for (;;) {
int rc = waitpid(-1, NULL, WNOHANG);
if ( (0 == rc) || (-1 == rc && EINTR != errno) )
break;
}
if (ECHILD != errno) {
/* Handle error */
}
}
int main(void) {
struct sigaction act;
act.sa_handler = reaper;
act.sa_flags = 0;
if (sigemptyset(&act.sa_mask) != 0) {
/* Handle error */
}
if (sigaction(SIGCHLD, &act, NULL) != 0) {
/* Handle error */
}
/* ... */
return 0EXIT_SUCCESS;
}
|
Compliant Solution (POSIX)
...
Code Block |
---|
|
#include <stddef<signal.h>
#include <signal<stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
void reaper(int signum) {
int save_errno = errno;
errno = 0;
for (;;) {
int rc = waitpid(-1, NULL, WNOHANG);
if ( (0 == rc) || (-1 == rc && EINTR != errno) )
break;
}
if (ECHILD != errno) {
/* Handle error */
}
errno = save_errno;
}
int main(void) {
struct sigaction act;
act.sa_handler = reaper;
act.sa_flags = 0;
if (sigemptyset(&act.sa_mask) != 0) {
/* Handle error */
}
if (sigaction(SIGCHLD, &act, NULL) != 0) {
/* Handle error */
}
/* ... */
return 0EXIT_SUCCESS;
}
|
Risk Assessment
Referencing indeterminate values can result in undefined behavior.
...