...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
void exit1(void) {
/* ...cleanup code... */
return;
}
void exit2(void) {
extern int some_condition;
if (/* condition */some_condition) {
/* ...more cleanup code... */
exit(0);
}
return;
}
int main(void) {
if (atexit(exit1) != 0) {
/* Handle error */
}
if (atexit(exit2) != 0) {
/* Handle error */
}
/* ...program code... */
return exit(0);
}
|
Because all functions registered by the atexit()
function are called in the reverse order of their registration, if exit2()
exits in any way other than by returning, exit1()
will not be executed. This may also be true for atexit()
handlers installed by support libraries.
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
void exit1(void) {
/* ...cleanup code... */
return;
}
void exit2(void) {
extern int some_condition;
if (/* condition */some_condition) {
/* ...more cleanup code... */
}
return;
}
int main(void) {
if (atexit(exit1) != 0) {
/* Handle error */
}
if (atexit(exit2) != 0) {
/* Handle error */
}
/* ...program code... */
exit(return 0);
}
|
Noncompliant Code Example
...
Code Block |
---|
|
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf env;
int val;
void exit1(void) {
/* ... */
longjmp(env, 1);
}
int main(void) {
if (atexit(exit1) != 0) {
/* Handle error */
}
/* ... */
if (setjmp(env) == 0) {
exit(0);
}
else {
return 0;
}
}
|
Compliant Solution
...
Code Block |
---|
|
#include <stdlib.h>
void exit1(void) {
/* ... */
return;
}
int main(void) {
if (atexit(exit1) != 0) {
/* Handle error */
}
/* ... */
exit(0)return 0;
}
|
Risk Assessment
Terminating a call to an atexit()
-registered handler in any way other than by returning results in undefined behavior and may result in abnormal program termination or other unpredictable behavior. It may also prevent other registered handlers from being invoked.
...