xref: /reactos/sdk/lib/crt/stdlib/atexit.c (revision 41805926)
1 /* taken from wine exit.c */
2 #include <precomp.h>
3 
4 _onexit_t *atexit_table = NULL;
5 int atexit_table_size = 0;
6 int atexit_registered = 0; /* Points to free slot */
7 
8 /* INTERNAL: call atexit functions */
9 void __call_atexit(void)
10 {
11   /* Note: should only be called with the exit lock held */
12   TRACE("%d atext functions to call\n", atexit_registered);
13   /* Last registered gets executed first */
14   while (atexit_registered > 0)
15   {
16     atexit_registered--;
17     TRACE("next is %p\n",atexit_table[atexit_registered]);
18     if (atexit_table[atexit_registered])
19       (*atexit_table[atexit_registered])();
20     TRACE("returned\n");
21   }
22 }
23 
24 /*********************************************************************
25  *		__dllonexit (MSVCRT.@)
26  */
27 _onexit_t CDECL __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
28 {
29    _onexit_t *tmp;
30    size_t len;
31 
32   TRACE("(%p,%p,%p)\n", func, start, end);
33 
34   if (!start || !*start || !end || !*end)
35   {
36    FIXME("bad table\n");
37    return NULL;
38   }
39 
40   len = (*end - *start);
41 
42   TRACE("table start %p-%p, %d entries\n", *start, *end, len);
43 
44   if (++len <= 0)
45     return NULL;
46 
47   tmp = realloc(*start, len * sizeof(_onexit_t));
48   if (!tmp)
49     return NULL;
50   *start = tmp;
51   *end = tmp + len;
52   tmp[len - 1] = func;
53   TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
54   return func;
55 }
56 
57 /*********************************************************************
58  *		_onexit (MSVCRT.@)
59  */
60 _onexit_t CDECL _onexit(_onexit_t func)
61 {
62   TRACE("(%p)\n",func);
63 
64   if (!func)
65     return NULL;
66 
67   LOCK_EXIT;
68   if (atexit_registered > atexit_table_size - 1)
69   {
70     _onexit_t *newtable;
71     TRACE("expanding table\n");
72     newtable = calloc(atexit_table_size + 32, sizeof(_onexit_t));
73     if (!newtable)
74     {
75       TRACE("failed!\n");
76       UNLOCK_EXIT;
77       return NULL;
78     }
79     memcpy (newtable, atexit_table, atexit_table_size*sizeof(_onexit_t));
80     atexit_table_size += 32;
81     free (atexit_table);
82     atexit_table = newtable;
83   }
84   atexit_table[atexit_registered] = func;
85   atexit_registered++;
86   UNLOCK_EXIT;
87   return func;
88 }
89 
90 /*********************************************************************
91  *		atexit (MSVCRT.@)
92  */
93 int CDECL atexit(void (*func)(void))
94 {
95   TRACE("(%p)\n", func);
96   return _onexit((_onexit_t)func) == (_onexit_t)func ? 0 : -1;
97 }
98 
99