Merge branch 'master' of ssh://sourceware.org/git/glibc
[glibc.git] / stdlib / exit.c
blob2235990285f80c7482d2dcc7dcd92463967f4eb1
1 /* Copyright (C) 1991,95,96,97,99,2001,2002,2005,2009
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sysdep.h>
24 #include "exit.h"
26 #include "set-hooks.h"
27 DEFINE_HOOK (__libc_atexit, (void))
30 /* Call all functions registered with `atexit' and `on_exit',
31 in the reverse of the order in which they were registered
32 perform stdio cleanup, and terminate program execution with STATUS. */
33 void
34 attribute_hidden
35 __run_exit_handlers (int status, struct exit_function_list **listp,
36 bool run_list_atexit)
38 /* We do it this way to handle recursive calls to exit () made by
39 the functions registered with `atexit' and `on_exit'. We call
40 everyone on the list and use the status value in the last
41 exit (). */
42 while (*listp != NULL)
44 struct exit_function_list *cur = *listp;
46 while (cur->idx > 0)
48 const struct exit_function *const f =
49 &cur->fns[--cur->idx];
50 switch (f->flavor)
52 void (*atfct) (void);
53 void (*onfct) (int status, void *arg);
54 void (*cxafct) (void *arg, int status);
56 case ef_free:
57 case ef_us:
58 break;
59 case ef_on:
60 onfct = f->func.on.fn;
61 #ifdef PTR_DEMANGLE
62 PTR_DEMANGLE (onfct);
63 #endif
64 onfct (status, f->func.on.arg);
65 break;
66 case ef_at:
67 atfct = f->func.at;
68 #ifdef PTR_DEMANGLE
69 PTR_DEMANGLE (atfct);
70 #endif
71 atfct ();
72 break;
73 case ef_cxa:
74 cxafct = f->func.cxa.fn;
75 #ifdef PTR_DEMANGLE
76 PTR_DEMANGLE (cxafct);
77 #endif
78 cxafct (f->func.cxa.arg, status);
79 break;
83 *listp = cur->next;
84 if (*listp != NULL)
85 /* Don't free the last element in the chain, this is the statically
86 allocate element. */
87 free (cur);
90 if (run_list_atexit)
91 RUN_HOOK (__libc_atexit, ());
93 _exit (status);
97 void
98 exit (int status)
100 __run_exit_handlers (status, &__exit_funcs, true);
102 libc_hidden_def (exit)