diff options
author | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-04-28 17:15:03 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-04-28 17:15:03 +0000 |
commit | 2aacd7357ad4eded006166c5431b23cf998a381f (patch) | |
tree | 4a1cc92b2ffd9b17f90a5ca3efc07f400bdc081a /libstdc++-v3/src/ios.cc | |
parent | ff4cb2e75b5f471edc5c1fc46d4bdebac58b6c7a (diff) | |
download | gcc-2aacd7357ad4eded006166c5431b23cf998a381f.zip gcc-2aacd7357ad4eded006166c5431b23cf998a381f.tar.gz gcc-2aacd7357ad4eded006166c5431b23cf998a381f.tar.bz2 |
[multiple changes]
2003-04-28 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/9523
* include/bits/ios_base.h (Init::_S_ios_create,
Init::_S_ios_destroy): Remove declarations.
(Init::_S_create_buffers,
Init::_S_destroy_buffers): Declare
* src/ios.cc (Init::_S_ios_create): Remove
(Init::_S_create_buffers): Create buffers and add to streams.
(Init::_S_ios_destroy): Rename to...
(Init::_S_destroy_buffers): this.
(Init::Init): Only construct streams once.
(Init::~Init): Flush streams, don't destroy them.
(ios_base::sync_with_stdio): Don't destroy streams, only buffers.
* testsuite/27_io/ios_base/sync_with_stdio/9523.cc: New test.
* testsuite/27_io/objects/char/5.cc: New test.
* testsuite/27_io/objects/char/5268.cc: Avoid undefined behavior.
* testsuite/27_io/objects/char/6.cc: New test.
* testsuite/27_io/objects/char/7.cc: New test.
2003-04-28 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/27_io/objects/char/8.cc: New test.
From-SVN: r66177
Diffstat (limited to 'libstdc++-v3/src/ios.cc')
-rw-r--r-- | libstdc++-v3/src/ios.cc | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 284c09e..7ce3339 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -154,39 +154,34 @@ namespace std { return _M_name; } void - ios_base::Init::_S_ios_create(bool __sync) + ios_base::Init::_S_create_buffers(bool __sync) { size_t __out_size = __sync ? 0 : static_cast<size_t>(BUFSIZ); size_t __in_size = __sync ? 1 : static_cast<size_t>(BUFSIZ); - // NB: The file globals.cc creates the four standard files - // with NULL buffers. At this point, we swap out the dummy NULL - // [io]stream objects and buffers with the real deal. + // Create stream buffers for the standard streams and use those + // buffers without destroying and recreating the streams. new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size); new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size); new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size); - new (&cout) ostream(&buf_cout); - new (&cin) istream(&buf_cin); - new (&cerr) ostream(&buf_cerr); - new (&clog) ostream(&buf_cerr); - cin.tie(&cout); - cerr.flags(ios_base::unitbuf); + cout.rdbuf(&buf_cout); + cin.rdbuf(&buf_cin); + cerr.rdbuf(&buf_cerr); + clog.rdbuf(&buf_cerr); #ifdef _GLIBCPP_USE_WCHAR_T new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size); new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size); new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size); - new (&wcout) wostream(&buf_wcout); - new (&wcin) wistream(&buf_wcin); - new (&wcerr) wostream(&buf_wcerr); - new (&wclog) wostream(&buf_wcerr); - wcin.tie(&wcout); - wcerr.flags(ios_base::unitbuf); + wcout.rdbuf(&buf_wcout); + wcin.rdbuf(&buf_wcin); + wcerr.rdbuf(&buf_wcerr); + wclog.rdbuf(&buf_wcerr); #endif } void - ios_base::Init::_S_ios_destroy() + ios_base::Init::_S_destroy_buffers() { // Explicitly call dtors to free any memory that is dynamically // allocated by filebuf ctor or member functions, but don't @@ -208,15 +203,52 @@ namespace std { // Standard streams default to synced with "C" operations. ios_base::Init::_S_synced_with_stdio = true; - _S_ios_create(ios_base::Init::_S_synced_with_stdio); + + // The standard streams are constructed once only and never destroyed. + // The stream buffers are set in _S_create_buffers below. + new (&cout) ostream(NULL); + new (&cin) istream(NULL); + new (&cerr) ostream(NULL); + new (&clog) ostream(NULL); + cin.tie(&cout); + cerr.flags(ios_base::unitbuf); + +#ifdef _GLIBCPP_USE_WCHAR_T + new (&wcout) wostream(NULL); + new (&wcin) wistream(NULL); + new (&wcerr) wostream(NULL); + new (&wclog) wostream(NULL); + wcin.tie(&wcout); + wcerr.flags(ios_base::unitbuf); +#endif + + _S_create_buffers(ios_base::Init::_S_synced_with_stdio); + _S_ios_base_init = 1; } ++_S_ios_base_init; } ios_base::Init::~Init() { - if (--_S_ios_base_init == 0) - _S_ios_destroy(); + if (--_S_ios_base_init == 1) + { + // Catch any exceptions thrown by basic_ostream::flush() + try + { + // Flush standard output streams as required by 27.4.2.1.6 + cout.flush(); + cerr.flush(); + clog.flush(); + +#ifdef _GLIBCPP_USE_WCHAR_T + wcout.flush(); + wcerr.flush(); + wclog.flush(); +#endif + } + catch (...) + { } + } } // 27.4.2.5 ios_base storage functions @@ -355,9 +387,9 @@ namespace std // currently synchronized. if (!__sync && __ret) { - ios_base::Init::_S_synced_with_stdio = false; - ios_base::Init::_S_ios_destroy(); - ios_base::Init::_S_ios_create(ios_base::Init::_S_synced_with_stdio); + ios_base::Init::_S_synced_with_stdio = __sync; + ios_base::Init::_S_destroy_buffers(); + ios_base::Init::_S_create_buffers(__sync); } return __ret; } |