reactos/sdk/lib/crt/stdlib/atexit.c

98 lines
2.2 KiB
C

/* taken from wine exit.c */
#include <precomp.h>
_onexit_t *atexit_table = NULL;
int atexit_table_size = 0;
int atexit_registered = 0; /* Points to free slot */
/* INTERNAL: call atexit functions */
void __call_atexit(void)
{
/* Note: should only be called with the exit lock held */
TRACE("%d atext functions to call\n", atexit_registered);
/* Last registered gets executed first */
while (atexit_registered > 0)
{
atexit_registered--;
TRACE("next is %p\n",atexit_table[atexit_registered]);
if (atexit_table[atexit_registered])
(*atexit_table[atexit_registered])();
TRACE("returned\n");
}
}
/*********************************************************************
* __dllonexit (MSVCRT.@)
*/
_onexit_t CDECL __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
{
_onexit_t *tmp;
size_t len;
TRACE("(%p,%p,%p)\n", func, start, end);
if (!start || !*start || !end || !*end)
{
FIXME("bad table\n");
return NULL;
}
len = (*end - *start);
TRACE("table start %p-%p, %d entries\n", *start, *end, len);
if (++len <= 0)
return NULL;
tmp = realloc(*start, len * sizeof(_onexit_t));
if (!tmp)
return NULL;
*start = tmp;
*end = tmp + len;
tmp[len - 1] = func;
TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
return func;
}
/*********************************************************************
* _onexit (MSVCRT.@)
*/
_onexit_t CDECL _onexit(_onexit_t func)
{
TRACE("(%p)\n",func);
if (!func)
return NULL;
LOCK_EXIT;
if (atexit_registered > atexit_table_size - 1)
{
_onexit_t *newtable;
TRACE("expanding table\n");
newtable = calloc(atexit_table_size + 32, sizeof(void *));
if (!newtable)
{
TRACE("failed!\n");
UNLOCK_EXIT;
return NULL;
}
memcpy (newtable, atexit_table, atexit_table_size);
atexit_table_size += 32;
free (atexit_table);
atexit_table = newtable;
}
atexit_table[atexit_registered] = func;
atexit_registered++;
UNLOCK_EXIT;
return func;
}
/*********************************************************************
* atexit (MSVCRT.@)
*/
int CDECL atexit(void (*func)(void))
{
TRACE("(%p)\n", func);
return _onexit((_onexit_t)func) == (_onexit_t)func ? 0 : -1;
}