From 24665754c84f0aca54d11a59744dd52de3123891 Mon Sep 17 00:00:00 2001 From: bkoz Date: Mon, 28 Apr 2003 17:15:03 +0000 Subject: [PATCH] 2003-04-28 Petur Runolfsson 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 * testsuite/27_io/objects/char/8.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66177 138bc75d-0d04-0410-961f-82ee72b054a4 --- libstdc++-v3/ChangeLog | 24 ++++++ libstdc++-v3/include/bits/ios_base.h | 4 +- libstdc++-v3/src/ios.cc | 78 ++++++++++++++------ .../27_io/ios_base/sync_with_stdio/9523.cc | 51 +++++++++++++ libstdc++-v3/testsuite/27_io/objects/char/5.cc | 85 ++++++++++++++++++++++ libstdc++-v3/testsuite/27_io/objects/char/5268.cc | 1 + libstdc++-v3/testsuite/27_io/objects/char/6.cc | 50 +++++++++++++ libstdc++-v3/testsuite/27_io/objects/char/7.cc | 75 +++++++++++++++++++ libstdc++-v3/testsuite/27_io/objects/char/8.cc | 51 +++++++++++++ 9 files changed, 394 insertions(+), 25 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc create mode 100644 libstdc++-v3/testsuite/27_io/objects/char/5.cc create mode 100644 libstdc++-v3/testsuite/27_io/objects/char/6.cc create mode 100644 libstdc++-v3/testsuite/27_io/objects/char/7.cc create mode 100644 libstdc++-v3/testsuite/27_io/objects/char/8.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 597c68f300f..fa1adb1353a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,27 @@ +2003-04-28 Petur Runolfsson + + 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 + + * testsuite/27_io/objects/char/8.cc: New test. + 2003-04-28 Benjamin Kosnik * testsuite/22_locale/codecvt/unicode/char.cc: Remove bom usage. diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 0adea499836..618c903147a 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -453,10 +453,10 @@ namespace std ~Init(); static void - _S_ios_create(bool __sync); + _S_create_buffers(bool __sync); static void - _S_ios_destroy(); + _S_destroy_buffers(); // NB: Allows debugger applications use of the standard streams // from operator new. _S_ios_base_init must be incremented in diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 284c09e4c52..7ce3339ccb3 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(BUFSIZ); size_t __in_size = __sync ? 1 : static_cast(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(stdout, ios_base::out, __out_size); new (&buf_cin) stdio_filebuf(stdin, ios_base::in, __in_size); new (&buf_cerr) stdio_filebuf(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(stdout, ios_base::out, __out_size); new (&buf_wcin) stdio_filebuf(stdin, ios_base::in, __in_size); new (&buf_wcerr) stdio_filebuf(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; } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc new file mode 100644 index 00000000000..f0b3f83b825 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_base/sync_with_stdio/9523.cc @@ -0,0 +1,51 @@ +// 2003-04-26 Petur Runolfsson + +// Copyright (C) 2003 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.4.2.4 ios_base static members + +#include +#include + +// libstdc++/9523 +void test01() +{ + using namespace std; + + int index = ios_base::xalloc(); + + cin.iword(index) = 5; + cout.iword(index) = 6; + cerr.iword(index) = 7; + clog.iword(index) = 8; + + ios_base::sync_with_stdio(false); + + VERIFY( cin.iword(index) == 5 ); + VERIFY( cout.iword(index) == 6 ); + VERIFY( cerr.iword(index) == 7 ); + VERIFY( clog.iword(index) == 8 ); +} + +int main() +{ + test01(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/27_io/objects/char/5.cc b/libstdc++-v3/testsuite/27_io/objects/char/5.cc new file mode 100644 index 00000000000..aa15e936363 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/5.cc @@ -0,0 +1,85 @@ +// 2003-04-26 Petur Runolfsson + +// Copyright (C) 2003 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.3 Standard iostream objects + +// Check that standard streams can be used from constructors and +// destructors of static objects, provided that an instance of +// ios_base::Init has been constructed. + +void init_standard_streams(); +int use_standard_streams(); + +struct Strange +{ + int i; + + Strange() + { + init_standard_streams(); + i = use_standard_streams(); + } + + ~Strange() + { + use_standard_streams(); + init_standard_streams(); + } +}; + +static Strange static_ob; + +#include +#include + +void init_standard_streams() +{ + std::ios_base::Init init; +} + +int use_standard_streams() +{ + std::cout << "Hello, world!" << std::endl; + std::cerr << "World, hello!" << std::endl; + + int ret = std::ios_base::xalloc(); + std::cin.iword(ret) = ret + 1; + std::cout.iword(ret) = ret + 2; + std::cerr.iword(ret) = ret + 3; + std::clog.iword(ret) = ret + 4; + return ret; +} + +void test05() +{ + bool test = true; + int i = static_ob.i; + + VERIFY( std::cin.iword(i) == i + 1 ); + VERIFY( std::cout.iword(i) == i + 2 ); + VERIFY( std::cerr.iword(i) == i + 3 ); + VERIFY( std::clog.iword(i) == i + 4 ); +} + +int main() +{ + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/5268.cc b/libstdc++-v3/testsuite/27_io/objects/char/5268.cc index 36f9019dae7..53641725a0c 100644 --- a/libstdc++-v3/testsuite/27_io/objects/char/5268.cc +++ b/libstdc++-v3/testsuite/27_io/objects/char/5268.cc @@ -36,6 +36,7 @@ void test04() std::stringbuf b1; std::cout.rdbuf( &b1 ); std::cout << "hello\n"; + std::cout.rdbuf(NULL); } int main() diff --git a/libstdc++-v3/testsuite/27_io/objects/char/6.cc b/libstdc++-v3/testsuite/27_io/objects/char/6.cc new file mode 100644 index 00000000000..c7ecbc66417 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/6.cc @@ -0,0 +1,50 @@ +// 2003-04-26 Petur Runolfsson + +// Copyright (C) 2003 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.3 Standard iostream objects + +// ios_base::Init::~Init() calls cout.flush(), which may call +// cout.setstate(badbit), which may throw an exception. Check that +// the exception doesn't escape from the destructor. + +#include +#include + +class Badbuf : public std::streambuf +{ +protected: + virtual int sync() + { + return -1; + } +}; + +void test06() +{ + std::ios_base::Init init; + std::cout.rdbuf(new Badbuf); + std::cout.exceptions(std::ios_base::badbit); +} + +int main() +{ + test06(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/7.cc b/libstdc++-v3/testsuite/27_io/objects/char/7.cc new file mode 100644 index 00000000000..c6f353e0a55 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/7.cc @@ -0,0 +1,75 @@ +// 2003-04-26 Petur Runolfsson + +// Copyright (C) 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// 27.3 Standard iostream objects + +#include +#include +#include +#include +#include +#include +#include +#include + +// Check that cout.flush() is called when last ios_base::Init is destroyed. +void test07() +{ + using namespace std; + bool test = true; + + const char* name = "tmp_fifo4"; + + signal(SIGPIPE, SIG_IGN); + + unlink(name); + mkfifo(name, S_IRWXU); + + int child = fork(); + VERIFY( child != -1 ); + + if (child == 0) + { + filebuf fbout; + sleep(1); + fbout.open(name, ios_base::out); + cout.rdbuf(&fbout); + fbout.sputc('a'); + sleep(2); + // NB: fbout is *not* destroyed here! + exit(0); + } + + filebuf fbin; + fbin.open(name, ios_base::in); + sleep(2); + filebuf::int_type c = fbin.sbumpc(); + VERIFY( c != filebuf::traits_type::eof() ); + VERIFY( c == filebuf::traits_type::to_int_type('a') ); + + fbin.close(); +} + +int +main() +{ + test07(); + return 0; +} diff --git a/libstdc++-v3/testsuite/27_io/objects/char/8.cc b/libstdc++-v3/testsuite/27_io/objects/char/8.cc new file mode 100644 index 00000000000..28a06a10ad3 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/objects/char/8.cc @@ -0,0 +1,51 @@ +// 2003-04-28 Benjamin Kosnik + +// Copyright (C) 2003 Free Software Foundation +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + + // 27.3 - Standard iostream objects p 2 + +#include +#include + +void test02() +{ + bool test = true; + + // 27.3 - Standard iostream objects p 2 + // The objects are not destroyed during program execution. + void* p1 = &std::cout; + void* p2 = &std::cin; + void* p3 = &std::cerr; + void* p4 = &std::clog; + std::ios_base::sync_with_stdio(false); + void* p1s = &std::cout; + void* p2s = &std::cin; + void* p3s = &std::cerr; + void* p4s = &std::clog; + VERIFY( p1 == p1s ); + VERIFY( p2 == p2s ); + VERIFY( p3 == p3s ); + VERIFY( p4 == p4s ); +} + +int main(void) +{ + test02(); + return 0; +} -- 2.11.0