]>
Commit | Line | Data |
---|---|---|
bfff8b1b | 1 | /* Copyright (C) 1991-2017 Free Software Foundation, Inc. |
7cc27f44 | 2 | This file is part of the GNU C Library. |
28f540f4 | 3 | |
7cc27f44 | 4 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
28f540f4 | 8 | |
7cc27f44 UD |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 12 | Lesser General Public License for more details. |
28f540f4 | 13 | |
41bdb6e2 | 14 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
15 | License along with the GNU C Library; if not, see |
16 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 | 17 | |
28f540f4 RM |
18 | #include <stdio.h> |
19 | #include <stdlib.h> | |
20 | #include <unistd.h> | |
a3c88553 | 21 | #include <sysdep.h> |
28f540f4 RM |
22 | #include "exit.h" |
23 | ||
28f540f4 RM |
24 | #include "set-hooks.h" |
25 | DEFINE_HOOK (__libc_atexit, (void)) | |
28f540f4 RM |
26 | |
27 | ||
28 | /* Call all functions registered with `atexit' and `on_exit', | |
29 | in the reverse of the order in which they were registered | |
30 | perform stdio cleanup, and terminate program execution with STATUS. */ | |
31 | void | |
610e67ed UD |
32 | attribute_hidden |
33 | __run_exit_handlers (int status, struct exit_function_list **listp, | |
47dd3543 | 34 | bool run_list_atexit, bool run_dtors) |
28f540f4 | 35 | { |
ba384f6e | 36 | /* First, call the TLS destructors. */ |
e57b0c61 RM |
37 | #ifndef SHARED |
38 | if (&__call_tls_dtors != NULL) | |
39 | #endif | |
47dd3543 CD |
40 | if (run_dtors) |
41 | __call_tls_dtors (); | |
ba384f6e | 42 | |
cc3fa755 UD |
43 | /* We do it this way to handle recursive calls to exit () made by |
44 | the functions registered with `atexit' and `on_exit'. We call | |
45 | everyone on the list and use the status value in the last | |
46 | exit (). */ | |
610e67ed | 47 | while (*listp != NULL) |
28f540f4 | 48 | { |
610e67ed | 49 | struct exit_function_list *cur = *listp; |
c4563d2d | 50 | |
610e67ed | 51 | while (cur->idx > 0) |
28f540f4 | 52 | { |
cc3fa755 | 53 | const struct exit_function *const f = |
610e67ed | 54 | &cur->fns[--cur->idx]; |
28f540f4 RM |
55 | switch (f->flavor) |
56 | { | |
a3c88553 UD |
57 | void (*atfct) (void); |
58 | void (*onfct) (int status, void *arg); | |
59 | void (*cxafct) (void *arg, int status); | |
60 | ||
28f540f4 | 61 | case ef_free: |
ba1ffaa1 | 62 | case ef_us: |
28f540f4 RM |
63 | break; |
64 | case ef_on: | |
a3c88553 UD |
65 | onfct = f->func.on.fn; |
66 | #ifdef PTR_DEMANGLE | |
67 | PTR_DEMANGLE (onfct); | |
68 | #endif | |
69 | onfct (status, f->func.on.arg); | |
28f540f4 RM |
70 | break; |
71 | case ef_at: | |
a3c88553 UD |
72 | atfct = f->func.at; |
73 | #ifdef PTR_DEMANGLE | |
74 | PTR_DEMANGLE (atfct); | |
75 | #endif | |
76 | atfct (); | |
28f540f4 | 77 | break; |
c41041bc | 78 | case ef_cxa: |
a3c88553 UD |
79 | cxafct = f->func.cxa.fn; |
80 | #ifdef PTR_DEMANGLE | |
81 | PTR_DEMANGLE (cxafct); | |
82 | #endif | |
83 | cxafct (f->func.cxa.arg, status); | |
3bbddbe4 | 84 | break; |
28f540f4 RM |
85 | } |
86 | } | |
c4563d2d | 87 | |
610e67ed UD |
88 | *listp = cur->next; |
89 | if (*listp != NULL) | |
bca9f4ab UD |
90 | /* Don't free the last element in the chain, this is the statically |
91 | allocate element. */ | |
610e67ed | 92 | free (cur); |
28f540f4 RM |
93 | } |
94 | ||
610e67ed UD |
95 | if (run_list_atexit) |
96 | RUN_HOOK (__libc_atexit, ()); | |
28f540f4 | 97 | |
ba1ffaa1 | 98 | _exit (status); |
28f540f4 | 99 | } |
610e67ed UD |
100 | |
101 | ||
102 | void | |
103 | exit (int status) | |
104 | { | |
47dd3543 | 105 | __run_exit_handlers (status, &__exit_funcs, true, true); |
610e67ed | 106 | } |
a757607d | 107 | libc_hidden_def (exit) |