...
Note that the behavior of a program that calls exit()
from an atexit
handler is undefined. (See undefined behavior 172 behavior 182 in Annex J of C99C11. See also ENV32-C. All atexit handlers must return normally.)
...
Returning from main()
causes normal program termination to occur. This is , which is the preferred way to terminate a program. Evaluating the return
statement has the same effect as calling exit()
with the same argument.
Code Block | ||||
---|---|---|---|---|
| ||||
int main(int argc, char **argv) { /* ... */ if (/* something really bad happened */) { return EXIT_FAILURE; } /* ... */ return EXIT_SUCCESS; } |
C99The C standard, Section 5.1.2.2.3, has this to say about returning from main()
[ISO/IEC 9899:19992011]:
If the return type of the
main
function is a type compatible withint
, a return from the initial call to themain
function is equivalent to calling theexit
function with the value returned by themain
function as its argument; reaching the}
that terminates themain
function returns a value of 0. If the return type is not compatible withint
, the termination status returned to the host environment is unspecified.
...
Code Block |
---|
void _start(void) { /* ... */ exit(main(argc, argv)); } |
However, exiting from main
is conditional on correctly handling all errors in a way that does not force premature termination. (See recommendations ERR00-C. Adopt and implement a consistent and comprehensive error-handling policy and ERR05-C. Application-independent code should provide error detection without dictating error handling.)
...
Calling _Exit()
causes normal program termination to occur. Like the exit()
function, _Exit()
also takes one argument of type int
and never returns. However, unlike exit()
, whether _Exit()
closes open streams, flushes stream buffers #1,[1] or deletes temporary files is implementation-defined. Functions registered by atexit()
are not executed.
Anchor | ||||
---|---|---|---|---|
|
_Exit()
by prohibiting the function from flushing stream buffers. See the documentation
of the function in [IEEE Std 1003.1-2008]....
As with _Exit()
, whether open streams with unwritten buffered data are flushed #2,[2] open streams are closed, or temporary files are removed is implementation-defined. Functions registered by atexit()
are not executed. (See recommendation ERR06-C. Understand the termination behavior of assert() and abort().)
Anchor | ||||
---|---|---|---|---|
|
_Exit()
, POSIX ® explicitly permits but does not require implementations to flush stream buffers. See the documentation
of the function in [IEEE Std 1003.1-2008]....
Function | Closes | Flushes | Removes | Calls | Program |
---|---|---|---|---|---|
| |||||
| |||||
| |||||
return from |
...
While this particular example benefits from calling exit()
over abort()
, there will be situations where in some situations, abort()
is the better choice. Usually this occurs when , abort()
is preferable when a programmer does not need to close any file descriptors or call any handlers registered with atexit()
, for instance, if the speed of terminating the program is critical.
For more details on proper usage of abort()
, see recommendation ERR06-C. Understand the termination behavior of assert() and abort().
Risk Assessment
For As an example, using abort()
or _Exit()
in place of exit()
may leave written files in an inconsistent state , and may also leave sensitive temporary files on the file system.
...
CERT C++ Secure Coding Standard: ERR04-CPP. Choose an appropriate termination strategy
The CERT Oracle Secure Coding Standard for Java: FIO14-J. Perform proper cleanup at program termination
ISO/IEC 9899:19992011 Section 5.1.2.2.3, "Program termination," and Section 7.20.4, "Communication with the environment"
ISO/IEC PDTR 24772 "REU Termination strategy"
The CERT Oracle Secure Coding Standard for Java: FIO14-J. Perform proper cleanup at program termination
MITRE CWE: CWE-705, "Incorrect Control Flow Scopingcontrol flow scoping"
Bibliography
...