diff options
Diffstat (limited to 'REORG.TODO/stdlib/exit.c')
-rw-r--r-- | REORG.TODO/stdlib/exit.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/REORG.TODO/stdlib/exit.c b/REORG.TODO/stdlib/exit.c new file mode 100644 index 0000000000..c0b6d666c7 --- /dev/null +++ b/REORG.TODO/stdlib/exit.c @@ -0,0 +1,107 @@ +/* Copyright (C) 1991-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sysdep.h> +#include "exit.h" + +#include "set-hooks.h" +DEFINE_HOOK (__libc_atexit, (void)) + + +/* Call all functions registered with `atexit' and `on_exit', + in the reverse of the order in which they were registered + perform stdio cleanup, and terminate program execution with STATUS. */ +void +attribute_hidden +__run_exit_handlers (int status, struct exit_function_list **listp, + bool run_list_atexit, bool run_dtors) +{ + /* First, call the TLS destructors. */ +#ifndef SHARED + if (&__call_tls_dtors != NULL) +#endif + if (run_dtors) + __call_tls_dtors (); + + /* We do it this way to handle recursive calls to exit () made by + the functions registered with `atexit' and `on_exit'. We call + everyone on the list and use the status value in the last + exit (). */ + while (*listp != NULL) + { + struct exit_function_list *cur = *listp; + + while (cur->idx > 0) + { + const struct exit_function *const f = + &cur->fns[--cur->idx]; + switch (f->flavor) + { + void (*atfct) (void); + void (*onfct) (int status, void *arg); + void (*cxafct) (void *arg, int status); + + case ef_free: + case ef_us: + break; + case ef_on: + onfct = f->func.on.fn; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (onfct); +#endif + onfct (status, f->func.on.arg); + break; + case ef_at: + atfct = f->func.at; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (atfct); +#endif + atfct (); + break; + case ef_cxa: + cxafct = f->func.cxa.fn; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (cxafct); +#endif + cxafct (f->func.cxa.arg, status); + break; + } + } + + *listp = cur->next; + if (*listp != NULL) + /* Don't free the last element in the chain, this is the statically + allocate element. */ + free (cur); + } + + if (run_list_atexit) + RUN_HOOK (__libc_atexit, ()); + + _exit (status); +} + + +void +exit (int status) +{ + __run_exit_handlers (status, &__exit_funcs, true, true); +} +libc_hidden_def (exit) |