[PATCH v2 08/11] Add stdio_exit_handler()

Matthew Joyce <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
From: Matt Joyce <[email protected]>

Added a dedicated stdio exit handler to avoid using _GLOBAL_REENT
in exit().
---
 newlib/libc/include/sys/reent.h |  2 ++
 newlib/libc/stdio/findfp.c      | 11 ++++++++++-
 newlib/libc/stdlib/exit.c       |  5 +++--
 winsup/cygwin/signal.cc         |  5 +++--
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/newlib/libc/include/sys/reent.h b/newlib/libc/include/sys/reent.h
index 4b0d68610..067294dc7 100644
--- a/newlib/libc/include/sys/reent.h
+++ b/newlib/libc/include/sys/reent.h
@@ -837,6 +837,8 @@ extern struct _reent *_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
 
 extern struct _reent _impure_data __ATTRIBUTE_IMPURE_DATA__;
 
+extern void (*__stdio_exit_handler) (void);
+
 void _reclaim_reent (struct _reent *);
 
 /* #define _REENT_ONLY define this to get only reentrant routines */
diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c
index 5b0402ac1..719886e27 100644
--- a/newlib/libc/stdio/findfp.c
+++ b/newlib/libc/stdio/findfp.c
@@ -26,6 +26,8 @@
 #include <sys/lock.h>
 #include "local.h"
 
+void (*__stdio_exit_handler) (void);
+
 #if defined(_REENT_SMALL) && !defined(_REENT_GLOBAL_STDIO_STREAMS)
 const struct __sFILE_fake __sf_fake_stdin =
     {_NULL, 0, 0, 0, 0, {_NULL, 0}, 0, _NULL};
@@ -153,6 +155,12 @@ sfmoreglue (struct _reent *d, int n)
   return &g->glue;
 }
 
+static void
+stdio_exit_handler (void)
+{
+  (void) _fwalk_reent (_GLOBAL_REENT, CLEANUP_FILE);
+}
+
 /*
  * Find a free FILE for fopen et al.
  */
@@ -166,12 +174,13 @@ __sfp (struct _reent *d)
 
   _newlib_sfp_lock_start ();
 
-  if (_GLOBAL_REENT->__cleanup == NULL) {
+  if (__stdio_exit_handler == NULL) {
 #ifdef _REENT_GLOBAL_STDIO_STREAMS
     _GLOBAL_REENT->__sglue._niobs = 3;
     _GLOBAL_REENT->__sglue._iobs = &__sf[0];
 #endif
     __sinit (_GLOBAL_REENT);
+    __stdio_exit_handler = stdio_exit_handler;
   }
 
   for (g = &_GLOBAL_REENT->__sglue;; g = g->_next)
diff --git a/newlib/libc/stdlib/exit.c b/newlib/libc/stdlib/exit.c
index 3e618914e..9b7bd518b 100644
--- a/newlib/libc/stdlib/exit.c
+++ b/newlib/libc/stdlib/exit.c
@@ -59,7 +59,8 @@ exit (int code)
 #endif
     __call_exitprocs (code, NULL);
 
-  if (_GLOBAL_REENT->__cleanup)
-    (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
+  if (__stdio_exit_handler != NULL)
+    (*__stdio_exit_handler) ();
+
   _exit (code);
 }
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 9b6c2509d..f5f2efdc7 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -13,6 +13,7 @@ details. */
 #include <stdlib.h>
 #include <sys/cygwin.h>
 #include <sys/signalfd.h>
+#include <sys/reent.h> /* needed for __stdio_exit_handler declaration */
 #include "pinfo.h"
 #include "sigproc.h"
 #include "cygtls.h"
@@ -408,8 +409,8 @@ abort (void)
   _my_tls.call_signal_handler (); /* Call any signal handler */
 
   /* Flush all streams as per SUSv2.  */
-  if (_GLOBAL_REENT->__cleanup)
-    _GLOBAL_REENT->__cleanup (_GLOBAL_REENT);
+  if (__stdio_exit_handler != NULL)
+    (*__stdio_exit_handler) ();
   do_exit (SIGABRT);	/* signal handler didn't exit.  Goodbye. */
 }
 
-- 
2.31.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.