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