You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

void exit(int status)

The exit function is used for normal program termination to occur.  

If more than one call to exit() is executed by a program, the behavior is undefined.

This type of situation typically only happens when functions are registered with atexit(), a function that causes the functions registered to it to be called with when the program exits. If a function called due to being registered with atexit() has an exit() call in it there is undefined behavior.

Non-Compliant Code Example

In this code as the main function exits two functions registered with atexit() are called. Given the define statement exitearly=1 the program calls exit within the first function called in the atexit() cycle. The behavior that follows is undefined: some implementations will ignore the second call to exit and just continue calling the atexit functions in the appropriate order. Other implementations will enter an infinite loop with the atexit functions being called repeatedly.

\#include <stdio.h>
\#include <stdlib.h>

\#define exitearly 1

void exit1 (void)
{
&nbsp; printf("Exit second.\n");

}

void exit2 (void)
{
&nbsp; printf("Exit first.\n");
&nbsp; if(exitearly)
&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp; exit(1);
&nbsp; }
}

int main ()
{
&nbsp; atexit (exit1);
&nbsp; atexit (exit2);
&nbsp; printf("In main\n");
&nbsp; exit(1);

&nbsp; return 0;
}


Compliant Code

To have functionality where the program can quit from within a function registered by at_exit() one has to use a function used for abnormal termination such as _exit() or abort().

From the man page of _exit():
The function _exit terminates the calling process "immediately". Any open file descriptors belonging to the process are closed; any children of the process are inherited by process 1, init, and the process's parent is sent a SIGCHLD signal.


\#include <stdio.h>
\#include <stdlib.h>

\#define exitearly 1

void exit1 (void)
{
&nbsp; printf("Exit second.\n");

}

void exit2 (void)
{
&nbsp; printf("Exit first.\n");
&nbsp; if(exitearly)
&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp; \_exit(1);
&nbsp; }
}

int main ()
{
&nbsp; atexit (exit1);
&nbsp; atexit (exit2);
&nbsp; printf("In main\n");
&nbsp; exit(1);

&nbsp; return 0;
}

Risk Assessment

|| Rule || Severity || Likelihood || Remediation Cost || Priority || Level ||
| MSC31-C | *1* (low) | *1* (unlikely) | *3*(low) | P3 | L3 |

References

[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]]  Section 7.20.4.3, "The exit function"

  • No labels