aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/ios.cc
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@gcc.gnu.org>2003-04-28 17:15:03 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2003-04-28 17:15:03 +0000
commit2aacd7357ad4eded006166c5431b23cf998a381f (patch)
tree4a1cc92b2ffd9b17f90a5ca3efc07f400bdc081a /libstdc++-v3/src/ios.cc
parentff4cb2e75b5f471edc5c1fc46d4bdebac58b6c7a (diff)
downloadgcc-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.cc78
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;
}