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