OSDN Git Service

Update to accomodate the header file changes
[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  * Dec 2000          Manuel Novoa III
8  *
9  *   Made atexit handling conform to standards... i.e. no args.
10  *   Removed on_exit since it did not match gnu libc definition.
11  *   Combined atexit and __do_exit into one object file.
12  *
13  * Feb 2000          Manuel Novoa III
14  *
15  *   Reworked file after addition of __uClibc_main.
16  *   Changed name of __do_exit to atexit_handler.
17  *   Changed name of __cleanup to __uClibc_cleanup.
18  *   Moved declaration of __uClibc_cleanup to __uClibc_main
19  *      where it is initialized with (possibly weak alias)
20  *      __stdio_close_all.
21  */
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <errno.h>
26
27 typedef void (*vfuncp) (void);
28 extern vfuncp __uClibc_cleanup;
29
30 #ifdef L_atexit
31 extern void __stdio_close_all(void);
32
33 static vfuncp __atexit_table[__UCLIBC_MAX_ATEXIT];
34 static int __atexit_count = 0;
35
36 static void atexit_handler(void)
37 {
38         int count;
39
40         /*
41          * Guard against more functions being added and againt being reinvoked.
42          */
43         __uClibc_cleanup = 0;
44
45         /* In reverse order */
46         for (count = __atexit_count ; count-- ; ) {
47                 (*__atexit_table[count])();
48         }
49         __stdio_close_all();
50 }
51
52 int atexit(vfuncp ptr)
53 {
54         if ((__uClibc_cleanup == 0) || (__atexit_count >= __UCLIBC_MAX_ATEXIT)) {
55                 __set_errno(ENOMEM);
56                 return -1;
57         }
58         if (ptr) {
59                 __uClibc_cleanup = atexit_handler;
60                 __atexit_table[__atexit_count++] = ptr;
61         }
62         return 0;
63 }
64 #endif
65
66 #ifdef L_exit
67 void exit(int rv)
68 {
69         if (__uClibc_cleanup) {         /* Not already executing __uClibc_cleanup. */
70                 __uClibc_cleanup();
71         }
72         _exit(rv);
73 }
74 #endif