summaryrefslogtreecommitdiff
path: root/src/stdlib/exit.c
blob: e6423891a79fa11aae4081f42f2fb7ff60c73f71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdlib.h>
#include <stdio.h>
#include "_stdlib.h"
#include "_syscall.h"

#include "_forced/_Exit.h"

/** cause normal program termination **/
_Noreturn void exit(int status)
{
	struct atexit *ae = &(__stdlib.atexit);

	SIGNAL_SAFE(0);

	if (__stdlib.exit_called == QUICK) {
		__stdlib.constraint_handler("Undefined behavior: exit() called after quick_exit()", NULL, 0);
	}
	if (__stdlib.exit_called == REGULAR) {
		__stdlib.constraint_handler("Undefined behavior: exit() called twice", NULL, 0);
	}
	__stdlib.exit_called = REGULAR;

	/* execute all atexit() registered functions in reverse order */
	while (ae) {
		int i = ae->nfns;
		while (i > 0) {
			ae->fns[--i]();
		}
		ae = ae->prev;
	}

	fflush(NULL);
	
	_Exit(status);
}

/***
causes the program to terminate normally, returning the
value ARGUMENT(status) to the host environment.

First, all functions registered by FUNCTION(atexit) are called in the reverse
order in which they were registered.

Then, all open streams with unwritten buffered data are flushed. All open
streams are closed. All temporary files created by FUNCTION(tmpfile) are
removed.
***/

/*
IMPLEMENTATION(The successful termination value returned to the host environment when ARGUMENT(status) is 0 or CONSTANT(EXIT_SUCESS))
IMPLEMENTATION(The unsuccessful termination value returned to the host environment when ARGUMENT(status) is CONSTANT(EXIT_FAILURE))
*/

/*
STDC(1)
*/