ref: e60ffe8d64ff9670fdf5ac0efb7fd64ff08af8bc
parent: 020a6282c06e9f61517d8a37495d888ec7527808
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Mar 7 15:56:46 EST 2017
[libc] Fix exit() and atexit() Functions registered with atexit() must be called in reverse order. This implementation also protects against calling exit() from an atexit() handler.
--- a/libc/include/errno.h
+++ b/libc/include/errno.h
@@ -5,6 +5,7 @@
#define EDOM 1
#define EILSEQ 2
#define ERANGE 3
+#define ENOMEN 4
extern int errno;
--- a/libc/src/atexit.c
+++ b/libc/src/atexit.c
@@ -1,19 +1,19 @@
/* See LICENSE file for copyright and license details. */
#include <stdlib.h>
+#include <errno.h>
#undef atexit
-extern void (*_atexitf[_ATEXIT_MAX])(void);
+extern void (*_exitf[_ATEXIT_MAX])(void);
+extern unsigned _exitn;
int
atexit(void (*fun)(void))
{
- void (**bp)(void);
-
- for (bp = _atexitf; bp < &_atexitf[_ATEXIT_MAX] && *bp; ++bp)
- /* nothing */;
- if (bp == &_atexitf[_ATEXIT_MAX])
- return 0;
- *bp = fun;
- return 1;
+ if (_exitn == _ATEXIT_MAX) {
+ errno = ENOMEN;
+ return -1;
+ }
+ _exitf[_exitn++] = fun;
+ return 0;
}
--- a/libc/src/exit.c
+++ b/libc/src/exit.c
@@ -3,19 +3,13 @@
#include <stdlib.h>
#undef exit
-void (*_atexitf[_ATEXIT_MAX])(void);
+void (*_exitf[_ATEXIT_MAX])(void);
+unsigned _exitn;
void
exit(int status)
{
- void (**bp)(void);
- int i;
-
- for (i = _ATEXIT_MAX-1; i >= 0; --i) {
- if (bp = _atexit[i]) {
- *_atexit[i] = NULL;
- (*bp)();
- }
- }
+ while (_exitn > 0)
+ (*_exitf[--exitn])();
_Exit(status);
}