Update NOTES.opensolaris with scheduling details
[kopensolaris-gnu/glibc.git] / stdlib / exit.c
1 /* Copyright (C) 1991,95,96,97,99,2001,2002,2005 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, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sysdep.h>
23 #include "exit.h"
24
25 #include "set-hooks.h"
26 DEFINE_HOOK (__libc_atexit, (void))
27
28
29 /* Call all functions registered with `atexit' and `on_exit',
30    in the reverse of the order in which they were registered
31    perform stdio cleanup, and terminate program execution with STATUS.  */
32 void
33 exit (int status)
34 {
35   /* We do it this way to handle recursive calls to exit () made by
36      the functions registered with `atexit' and `on_exit'. We call
37      everyone on the list and use the status value in the last
38      exit (). */
39   while (__exit_funcs != NULL)
40     {
41       struct exit_function_list *old;
42
43       while (__exit_funcs->idx > 0)
44         {
45           const struct exit_function *const f =
46             &__exit_funcs->fns[--__exit_funcs->idx];
47           switch (f->flavor)
48             {
49               void (*atfct) (void);
50               void (*onfct) (int status, void *arg);
51               void (*cxafct) (void *arg, int status);
52
53             case ef_free:
54             case ef_us:
55               break;
56             case ef_on:
57               onfct = f->func.on.fn;
58 #ifdef PTR_DEMANGLE
59               PTR_DEMANGLE (onfct);
60 #endif
61               onfct (status, f->func.on.arg);
62               break;
63             case ef_at:
64               atfct = f->func.at;
65 #ifdef PTR_DEMANGLE
66               PTR_DEMANGLE (atfct);
67 #endif
68               atfct ();
69               break;
70             case ef_cxa:
71               cxafct = f->func.cxa.fn;
72 #ifdef PTR_DEMANGLE
73               PTR_DEMANGLE (cxafct);
74 #endif
75               cxafct (f->func.cxa.arg, status);
76               break;
77             }
78         }
79
80       old = __exit_funcs;
81       __exit_funcs = __exit_funcs->next;
82       if (__exit_funcs != NULL)
83         /* Don't free the last element in the chain, this is the statically
84            allocate element.  */
85         free (old);
86     }
87
88   RUN_HOOK (__libc_atexit, ());
89
90   _exit (status);
91 }
92 libc_hidden_def (exit)