OSDN Git Service

Initial revision
[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  * This deals with both the atexit and on_exit function calls
8  * 
9  * Note calls installed with atexit are called with the same args as on_exit
10  * fuctions; the void* is given the NULL value.
11  * 
12  */
13
14 #include <errno.h>
15
16 /* ATEXIT.H */
17 #define MAXONEXIT 20            /* AIUI Posix requires 10 */
18
19 typedef void (*vfuncp) ();
20
21 extern vfuncp __cleanup;
22 extern void __do_exit();
23
24 extern struct exit_table
25 {
26    vfuncp called;
27    void *argument;
28 }
29 __on_exit_table[MAXONEXIT];
30
31 extern int __on_exit_count;
32
33 /* End ATEXIT.H */
34
35 #ifdef L_atexit
36 vfuncp __cleanup;
37
38 int
39 atexit(ptr)
40 vfuncp ptr;
41 {
42    if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
43    {
44       errno = ENOMEM;
45       return -1;
46    }
47    __cleanup = __do_exit;
48    if( ptr )
49    {
50       __on_exit_table[__on_exit_count].called = ptr;
51       __on_exit_table[__on_exit_count].argument = 0;
52       __on_exit_count++;
53    }
54    return 0;
55 }
56
57 #endif
58
59 #ifdef L_on_exit
60 int
61 on_exit(ptr, arg)
62 vfuncp ptr;
63 void *arg;
64 {
65    if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
66    {
67       errno = ENOMEM;
68       return -1;
69    }
70    __cleanup = __do_exit;
71    if( ptr )
72    {
73       __on_exit_table[__on_exit_count].called = ptr;
74       __on_exit_table[__on_exit_count].argument = arg;
75       __on_exit_count++;
76    }
77    return 0;
78 }
79
80 #endif
81
82 #ifdef L___do_exit
83
84 int   __on_exit_count = 0;
85 struct exit_table __on_exit_table[MAXONEXIT];
86
87 void
88 __do_exit(rv)
89 int   rv;
90 {
91    register int   count = __on_exit_count-1;
92    register vfuncp ptr;
93    __on_exit_count = -1;                /* ensure no more will be added */
94    __cleanup = 0;                       /* Calling exit won't re-do this */
95
96    /* In reverse order */
97    for (; count >= 0; count--)
98    {
99       ptr = __on_exit_table[count].called;
100       (*ptr) (rv, __on_exit_table[count].argument);
101    }
102 }
103
104 #endif
105
106 #ifdef L_exit
107
108 void
109 exit(rv)
110 int     rv;
111 {
112    if (__cleanup)
113       __cleanup();
114    _exit(rv);
115 }
116
117 #endif