1 // Iostreams base classes -*- C++ -*- 2 3 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // 26 // ISO C++ 14882: 27.4 Iostreams base classes 27 // 28 29 #include <ios> 30 #include <ostream> 31 #include <istream> 32 #include <fstream> 33 #include <ext/stdio_filebuf.h> 34 #include <ext/stdio_sync_filebuf.h> 35 36 namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden) 37 { 38 using namespace __gnu_cxx; 39 40 // Extern declarations for global objects in src/c++98/globals.cc. 41 extern stdio_sync_filebuf<char> buf_cout_sync; 42 extern stdio_sync_filebuf<char> buf_cin_sync; 43 extern stdio_sync_filebuf<char> buf_cerr_sync; 44 45 extern stdio_filebuf<char> buf_cout; 46 extern stdio_filebuf<char> buf_cin; 47 extern stdio_filebuf<char> buf_cerr; 48 49 #ifdef _GLIBCXX_USE_WCHAR_T 50 extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; 51 extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; 52 extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; 53 54 extern stdio_filebuf<wchar_t> buf_wcout; 55 extern stdio_filebuf<wchar_t> buf_wcin; 56 extern stdio_filebuf<wchar_t> buf_wcerr; 57 #endif 58 } // namespace __gnu_internal 59 60 namespace std _GLIBCXX_VISIBILITY(default) 61 { 62 _GLIBCXX_BEGIN_NAMESPACE_VERSION 63 64 using namespace __gnu_internal; 65 66 extern istream cin; 67 extern ostream cout; 68 extern ostream cerr; 69 extern ostream clog; 70 71 #ifdef _GLIBCXX_USE_WCHAR_T 72 extern wistream wcin; 73 extern wostream wcout; 74 extern wostream wcerr; 75 extern wostream wclog; 76 #endif 77 Init()78 ios_base::Init::Init() 79 { 80 if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0) 81 { 82 // Standard streams default to synced with "C" operations. 83 _S_synced_with_stdio = true; 84 85 new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); 86 new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); 87 new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); 88 89 // The standard streams are constructed once only and never 90 // destroyed. 91 new (&cout) ostream(&buf_cout_sync); 92 new (&cin) istream(&buf_cin_sync); 93 new (&cerr) ostream(&buf_cerr_sync); 94 new (&clog) ostream(&buf_cerr_sync); 95 cin.tie(&cout); 96 cerr.setf(ios_base::unitbuf); 97 // _GLIBCXX_RESOLVE_LIB_DEFECTS 98 // 455. cerr::tie() and wcerr::tie() are overspecified. 99 cerr.tie(&cout); 100 101 #ifdef _GLIBCXX_USE_WCHAR_T 102 new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); 103 new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); 104 new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); 105 106 new (&wcout) wostream(&buf_wcout_sync); 107 new (&wcin) wistream(&buf_wcin_sync); 108 new (&wcerr) wostream(&buf_wcerr_sync); 109 new (&wclog) wostream(&buf_wcerr_sync); 110 wcin.tie(&wcout); 111 wcerr.setf(ios_base::unitbuf); 112 wcerr.tie(&wcout); 113 #endif 114 115 // NB: Have to set refcount above one, so that standard 116 // streams are not re-initialized with uses of ios_base::Init 117 // besides <iostream> static object, ie just using <ios> with 118 // ios_base::Init objects. 119 __gnu_cxx::__atomic_add_dispatch(&_S_refcount, 1); 120 } 121 } 122 ~Init()123 ios_base::Init::~Init() 124 { 125 // Be race-detector-friendly. For more info see bits/c++config. 126 _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount); 127 if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2) 128 { 129 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount); 130 // Catch any exceptions thrown by basic_ostream::flush() 131 __try 132 { 133 // Flush standard output streams as required by 27.4.2.1.6 134 cout.flush(); 135 cerr.flush(); 136 clog.flush(); 137 138 #ifdef _GLIBCXX_USE_WCHAR_T 139 wcout.flush(); 140 wcerr.flush(); 141 wclog.flush(); 142 #endif 143 } 144 __catch(...) 145 { } 146 } 147 } 148 149 bool sync_with_stdio(bool __sync)150 ios_base::sync_with_stdio(bool __sync) 151 { 152 // _GLIBCXX_RESOLVE_LIB_DEFECTS 153 // 49. Underspecification of ios_base::sync_with_stdio 154 bool __ret = ios_base::Init::_S_synced_with_stdio; 155 156 // Turn off sync with C FILE* for cin, cout, cerr, clog iff 157 // currently synchronized. 158 if (!__sync && __ret) 159 { 160 // Make sure the standard streams are constructed. 161 ios_base::Init __init; 162 163 ios_base::Init::_S_synced_with_stdio = __sync; 164 165 // Explicitly call dtors to free any memory that is 166 // dynamically allocated by filebuf ctor or member functions, 167 // but don't deallocate all memory by calling operator delete. 168 buf_cout_sync.~stdio_sync_filebuf<char>(); 169 buf_cin_sync.~stdio_sync_filebuf<char>(); 170 buf_cerr_sync.~stdio_sync_filebuf<char>(); 171 172 #ifdef _GLIBCXX_USE_WCHAR_T 173 buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); 174 buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); 175 buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); 176 #endif 177 178 // Create stream buffers for the standard streams and use 179 // those buffers without destroying and recreating the 180 // streams. 181 new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); 182 new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); 183 new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); 184 cout.rdbuf(&buf_cout); 185 cin.rdbuf(&buf_cin); 186 cerr.rdbuf(&buf_cerr); 187 clog.rdbuf(&buf_cerr); 188 189 #ifdef _GLIBCXX_USE_WCHAR_T 190 new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); 191 new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); 192 new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); 193 wcout.rdbuf(&buf_wcout); 194 wcin.rdbuf(&buf_wcin); 195 wcerr.rdbuf(&buf_wcerr); 196 wclog.rdbuf(&buf_wcerr); 197 #endif 198 } 199 return __ret; 200 } 201 202 _GLIBCXX_END_NAMESPACE_VERSION 203 } // namespace 204