Fix guards for qecvt
[platform/upstream/glibc.git] / stdlib / exit.c
1 /* Copyright (C) 1991-2013 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
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.
8
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
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <sysdep.h>
22 #include "exit.h"
23
24 #include "set-hooks.h"
25 DEFINE_HOOK (__libc_atexit, (void))
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
32 attribute_hidden
33 __run_exit_handlers (int status, struct exit_function_list **listp,
34                      bool run_list_atexit)
35 {
36   /* First, call the TLS destructors.  */
37 #ifndef SHARED
38   if (&__call_tls_dtors != NULL)
39 #endif
40     __call_tls_dtors ();
41
42   /* We do it this way to handle recursive calls to exit () made by
43      the functions registered with `atexit' and `on_exit'. We call
44      everyone on the list and use the status value in the last
45      exit (). */
46   while (*listp != NULL)
47     {
48       struct exit_function_list *cur = *listp;
49
50       while (cur->idx > 0)
51         {
52           const struct exit_function *const f =
53             &cur->fns[--cur->idx];
54           switch (f->flavor)
55             {
56               void (*atfct) (void);
57               void (*onfct) (int status, void *arg);
58               void (*cxafct) (void *arg, int status);
59
60             case ef_free:
61             case ef_us:
62               break;
63             case ef_on:
64               onfct = f->func.on.fn;
65 #ifdef PTR_DEMANGLE
66               PTR_DEMANGLE (onfct);
67 #endif
68               onfct (status, f->func.on.arg);
69               break;
70             case ef_at:
71               atfct = f->func.at;
72 #ifdef PTR_DEMANGLE
73               PTR_DEMANGLE (atfct);
74 #endif
75               atfct ();
76               break;
77             case ef_cxa:
78               cxafct = f->func.cxa.fn;
79 #ifdef PTR_DEMANGLE
80               PTR_DEMANGLE (cxafct);
81 #endif
82               cxafct (f->func.cxa.arg, status);
83               break;
84             }
85         }
86
87       *listp = cur->next;
88       if (*listp != NULL)
89         /* Don't free the last element in the chain, this is the statically
90            allocate element.  */
91         free (cur);
92     }
93
94   if (run_list_atexit)
95     RUN_HOOK (__libc_atexit, ());
96
97   _exit (status);
98 }
99
100
101 void
102 exit (int status)
103 {
104   __run_exit_handlers (status, &__exit_funcs, true);
105 }
106 libc_hidden_def (exit)