Handle allow-header correctly.
[kopensolaris-gnu/glibc.git] / stdlib / exit.c
1 /* Copyright (C) 1991,1995,1996,1997,1999,2001 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 Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    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    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include "exit.h"
23
24 #ifdef HAVE_GNU_LD
25 #include "set-hooks.h"
26 DEFINE_HOOK (__libc_atexit, (void))
27 #endif
28
29
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 exit (int status)
35 {
36   /* We do it this way to handle recursive calls to exit () made by
37      the functions registered with `atexit' and `on_exit'. We call
38      everyone on the list and use the status value in the last
39      exit (). */
40   while (__exit_funcs != NULL)
41     {
42       struct exit_function_list *old;
43
44       while (__exit_funcs->idx > 0)
45         {
46           const struct exit_function *const f =
47             &__exit_funcs->fns[--__exit_funcs->idx];
48           switch (f->flavor)
49             {
50             case ef_free:
51             case ef_us:
52               break;
53             case ef_on:
54               (*f->func.on.fn) (status, f->func.on.arg);
55               break;
56             case ef_at:
57               (*f->func.at) ();
58               break;
59             case ef_cxa:
60               (*f->func.cxa.fn) (f->func.cxa.arg, status);
61               break;
62             }
63         }
64
65       old = __exit_funcs;
66       __exit_funcs = __exit_funcs->next;
67       if (__exit_funcs != NULL)
68         /* Don't free the last element in the chain, this is the statically
69            allocate element.  */
70         free (old);
71     }
72
73 #ifdef  HAVE_GNU_LD
74   RUN_HOOK (__libc_atexit, ());
75 #else
76   {
77     extern void _cleanup (void);
78     _cleanup ();
79   }
80 #endif
81
82   _exit (status);
83 }