shithub: scc

Download patch

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);
 }