OSDN Git Service

A large update from Manuel Novoa III <mnovoa3@bellsouth.net>.
[uclinux-h8/uClibc.git] / libc / stdlib / atexit.c
1 /* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
2  * This file is part of the Linux-8086 C library and is distributed
3  * under the GNU Library General Public License.
4  */
5
6 /*
7  * Manuel Novoa III       Dec 2000
8  *
9  * Modifications:
10  *   Made atexit handling conform to standards... i.e. no args.
11  *   Removed on_exit since it did not match gnu libc definition.
12  *   Combined atexit and __do_exit into one object file.
13  */
14
15 #include <errno.h>
16
17 /* ATEXIT.H */
18 #define MAXONEXIT 20                    /* AIUI Posix requires 10 */
19
20 typedef void (*vfuncp) (void);
21
22 extern vfuncp __cleanup;
23 extern void __do_exit();
24 extern void _exit __P((int __status)) __attribute__ ((__noreturn__));
25
26 extern vfuncp __atexit_table[MAXONEXIT];
27 extern int __atexit_count;
28
29 /* End ATEXIT.H */
30
31 #ifdef L_atexit
32 int atexit(vfuncp ptr)
33 {
34         if ((__atexit_count < 0) || (__atexit_count >= MAXONEXIT)) {
35                 errno = ENOMEM;
36                 return -1;
37         }
38         if (ptr) {
39                 __cleanup = __do_exit;
40                 __atexit_table[__atexit_count++] = ptr;
41         }
42         return 0;
43 }
44
45 vfuncp __atexit_table[MAXONEXIT];
46 int __atexit_count = 0;
47
48 void __do_exit(int rv)
49 {
50         int count = __atexit_count - 1;
51
52         __atexit_count = -1;            /* ensure no more will be added */
53         __cleanup = 0;                          /* Calling exit won't re-do this */
54
55         /* In reverse order */
56         for (; count >= 0; count--) {
57                 (*__atexit_table[count])();
58         }
59 }
60 #endif
61
62 #ifdef L_exit
63 void __stdio_close_all(void);   /* note: see _start.S - could be faked */
64
65 vfuncp __cleanup = 0;
66
67 void exit(int rv)
68 {
69         if (__cleanup)
70                 __cleanup();
71         __stdio_close_all();
72         _exit(rv);
73 }
74 #endif