1 /* Copyright (c) 2015 Freddie Chopin <freddie.chopin@gmail.com> */ 2 /* 3 * Static instance of _on_exit_args struct. 4 * 5 * When _REENT_SMALL is used, _atexit struct only contains a pointer to 6 * _on_exit_args struct, so this was always allocated with malloc() - even for 7 * the first 32 calls of atexit()-like functions, which are guaranteed to 8 * succeed, but could fail because of "out of memory" error. This is even worse 9 * when _ATEXIT_DYNAMIC_ALLOC is _NOT_ defined, in which case malloc() is not 10 * used by internals of atexit()-like functions. In such configuration all calls 11 * to the functions that need _on_exit_args struct (on_exit() and 12 * __cxa_atexit()) would fail. 13 * 14 * Thats why a static instance of _on_exit_args struct is provided for 15 * _REENT_SMALL configuration. This way the first 32 calls to atexit()-like 16 * functions don't need malloc() and will always succeed. 17 * 18 * Because this struct is not needed for "normal" atexit(), it is used as a weak 19 * reference in __register_exitproc(), but any use of on_exit() or 20 * __cxa_atexit() will force it to be linked. 21 */ 22 23 #include <stddef.h> 24 #include <stdlib.h> 25 #include <sys/lock.h> 26 #include "atexit.h" 27 28 #ifdef _REENT_SMALL 29 30 static struct _on_exit_args _on_exit_args_instance; 31 32 struct _on_exit_args * const __on_exit_args = &_on_exit_args_instance; 33 34 #endif /* def _REENT_SMALL */ 35