Instead of using "::__overflow" using "__fwritable" and handle
flushing empty writebuf in constructor.
---
This removes unconditional flushing in _File constructor, and
replace it with writeability check only. The flush is performed
conditionally in _File_sink constructor, only if the _M_writebuf
is empty. Otherwise it wil lbe done on first overflow.

I looked into testing configure and testing that, just done edits
that looked like what I should do.

 libstdc++-v3/acinclude.m4      |  7 ++++---
 libstdc++-v3/include/std/print | 22 +++++++++++++++-------
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 1774e81d617..0dd9375a278 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -5824,10 +5824,11 @@ AC_LANG_SAVE
           using f2_type = size_t (*)(FILE*) noexcept;
          }
          ],[
-         f1_type f1 = &::__flbf;
-         f2_type f2 = &::__fbufsize;
+         f1_type twriteable = &::__fwriteable;
+         f1_type tblk = &::__flbf; 
+         f2_type pbufsize = &::__fbufsize;
          FILE* f = ::fopen("", "");
-         int i = ::__overflow(f, EOF);
+         bool writeable = ::__fwriteable(f);
          bool line_buffered = ::__flbf(f);
          size_t bufsz = ::__fbufsize(f);
          char*& pptr = f->_IO_write_ptr;
diff --git a/libstdc++-v3/include/std/print b/libstdc++-v3/include/std/print
index 668eee366bd..4ffc18e780c 100644
--- a/libstdc++-v3/include/std/print
+++ b/libstdc++-v3/include/std/print
@@ -57,6 +57,7 @@ namespace __format
 {
 #if _GLIBCXX_USE_STDIO_LOCKING && _GLIBCXX_USE_GLIBC_STDIO_EXT
   // These are defined in <stdio_ext.h> but we don't want to include that.
+  extern "C" int __fwritable(FILE*) noexcept;
   extern "C" int __flbf(FILE*) noexcept;
   extern "C" size_t __fbufsize(FILE*) noexcept;
 
@@ -70,12 +71,11 @@ namespace __format
       _File(FILE* __f) : _M_file(__f)
       {
        ::flockfile(__f);
-       // Ensure stream is in write mode and allocate buffer if needed:
-       if (::__overflow(__f, EOF) == EOF)
+       // Ensure stream is in write mode
+        if (!__fwritable(__f))
          {
-           const int __err = errno;
            ::funlockfile(__f);
-           __throw_system_error(__err);
+           __throw_system_error(EACCES);
          }
       }
 
@@ -144,9 +144,17 @@ namespace __format
     _File_sink(FILE* __f, bool __add_newline)
     : _M_file(__f), _M_add_newline(__add_newline)
     {
-      if (!_M_file._M_unbuffered())
-       // Write directly to the FILE's output buffer.
-       this->_M_reset(_M_file._M_write_buf());
+      if (_M_file._M_unbuffered())
+       return;
+
+      std::span<char> __writebuf = _M_file._M_write_buf();
+      if (__writebuf.empty())
+       {
+         _M_file._M_flush();
+         __writebuf = _M_file._M_write_buf();
+       }
+      // Write directly to the FILE's output buffer.
+      this->_M_reset(__writebuf);
     }
 
     ~_File_sink() noexcept(false)
-- 
2.49.0

Reply via email to