ref: 62f0e08bbf82d768a2ef87af44b67b5547558d2f
parent: 8f191a4cad7365c97247c822c482e1afda3f5b33
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed May 25 14:22:06 EDT 2022
libc: Don't use atexit() to flush streams __putc() was using atexit() to install a handler to flush all the output streams, but this could drive to wrong behavioud because we cannot guarantee that handlers installed before calling __putc() are not going to buffer anything to output streams.
--- a/src/libc/libc.h
+++ b/src/libc/libc.h
@@ -56,3 +56,4 @@
extern void (*_exitf[])(void);
extern unsigned _exitn;
+extern void (*_flushall)(void);
--- a/src/libc/stdio/__putc.c
+++ b/src/libc/stdio/__putc.c
@@ -13,8 +13,6 @@
int
__putc(int ch, FILE *fp)
{
- static int first = 1;
-
if (fp->flags & _IOERR)
return EOF;
@@ -29,15 +27,7 @@
if (fp->buf == NULL && _allocbuf(fp))
return EOF;
-
- if (first) {
- if (atexit(cleanup)) {
- fp->flags |= _IOERR;
- errno = ENOMEM;
- return EOF;
- }
- first = 0;
- }
+ _flushall = cleanup;
if (fp->flags & _IOLBF) {
if (fp->wp == fp->lp && _flsbuf(fp))
--- a/src/libc/stdlib/exit.c
+++ b/src/libc/stdlib/exit.c
@@ -1,11 +1,13 @@
#include <stdlib.h>
#include "../libc.h"
+#include "../syscall.h"
#undef exit
void (*_exitf[_ATEXIT_MAX])(void);
unsigned _exitn;
+void (*_flushall)(void);
void
exit(int status)
@@ -12,6 +14,7 @@
{
while (_exitn > 0)
(*_exitf[--_exitn])();
-
- _Exit(status);
+ if (_flushall)
+ (*_flushall)();
+ _exit(status);
}