1// Iostreams base classes -*- C++ -*- 2 3// Copyright (C) 1997-2022 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 36namespace __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 60namespace 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 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 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 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