136ac495dSmrg // Iostreams base classes -*- C++ -*- 236ac495dSmrg 3*8feb0f0bSmrg // Copyright (C) 1997-2020 Free Software Foundation, Inc. 436ac495dSmrg // 536ac495dSmrg // This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg // software; you can redistribute it and/or modify it under the 736ac495dSmrg // terms of the GNU General Public License as published by the 836ac495dSmrg // Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg // any later version. 1036ac495dSmrg 1136ac495dSmrg // This library is distributed in the hope that it will be useful, 1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg // GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg // 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg // You should have received a copy of the GNU General Public License and 2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program; 2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2336ac495dSmrg // <http://www.gnu.org/licenses/>. 2436ac495dSmrg 2536ac495dSmrg // 2636ac495dSmrg // ISO C++ 14882: 27.4 Iostreams base classes 2736ac495dSmrg // 2836ac495dSmrg 2936ac495dSmrg #include <ios> 3036ac495dSmrg #include <ostream> 3136ac495dSmrg #include <istream> 3236ac495dSmrg #include <fstream> 3336ac495dSmrg #include <ext/stdio_filebuf.h> 3436ac495dSmrg #include <ext/stdio_sync_filebuf.h> 3536ac495dSmrg 3636ac495dSmrg namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden) 3736ac495dSmrg { 3836ac495dSmrg using namespace __gnu_cxx; 3936ac495dSmrg 4036ac495dSmrg // Extern declarations for global objects in src/c++98/globals.cc. 4136ac495dSmrg extern stdio_sync_filebuf<char> buf_cout_sync; 4236ac495dSmrg extern stdio_sync_filebuf<char> buf_cin_sync; 4336ac495dSmrg extern stdio_sync_filebuf<char> buf_cerr_sync; 4436ac495dSmrg 4536ac495dSmrg extern stdio_filebuf<char> buf_cout; 4636ac495dSmrg extern stdio_filebuf<char> buf_cin; 4736ac495dSmrg extern stdio_filebuf<char> buf_cerr; 4836ac495dSmrg 4936ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 5036ac495dSmrg extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; 5136ac495dSmrg extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; 5236ac495dSmrg extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; 5336ac495dSmrg 5436ac495dSmrg extern stdio_filebuf<wchar_t> buf_wcout; 5536ac495dSmrg extern stdio_filebuf<wchar_t> buf_wcin; 5636ac495dSmrg extern stdio_filebuf<wchar_t> buf_wcerr; 5736ac495dSmrg #endif 5836ac495dSmrg } // namespace __gnu_internal 5936ac495dSmrg 6036ac495dSmrg namespace std _GLIBCXX_VISIBILITY(default) 6136ac495dSmrg { 6236ac495dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 6336ac495dSmrg 6436ac495dSmrg using namespace __gnu_internal; 6536ac495dSmrg 6636ac495dSmrg extern istream cin; 6736ac495dSmrg extern ostream cout; 6836ac495dSmrg extern ostream cerr; 6936ac495dSmrg extern ostream clog; 7036ac495dSmrg 7136ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 7236ac495dSmrg extern wistream wcin; 7336ac495dSmrg extern wostream wcout; 7436ac495dSmrg extern wostream wcerr; 7536ac495dSmrg extern wostream wclog; 7636ac495dSmrg #endif 7736ac495dSmrg Init()7836ac495dSmrg ios_base::Init::Init() 7936ac495dSmrg { 8036ac495dSmrg if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0) 8136ac495dSmrg { 8236ac495dSmrg // Standard streams default to synced with "C" operations. 8336ac495dSmrg _S_synced_with_stdio = true; 8436ac495dSmrg 8536ac495dSmrg new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); 8636ac495dSmrg new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); 8736ac495dSmrg new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); 8836ac495dSmrg 8936ac495dSmrg // The standard streams are constructed once only and never 9036ac495dSmrg // destroyed. 9136ac495dSmrg new (&cout) ostream(&buf_cout_sync); 9236ac495dSmrg new (&cin) istream(&buf_cin_sync); 9336ac495dSmrg new (&cerr) ostream(&buf_cerr_sync); 9436ac495dSmrg new (&clog) ostream(&buf_cerr_sync); 9536ac495dSmrg cin.tie(&cout); 9636ac495dSmrg cerr.setf(ios_base::unitbuf); 9736ac495dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 9836ac495dSmrg // 455. cerr::tie() and wcerr::tie() are overspecified. 9936ac495dSmrg cerr.tie(&cout); 10036ac495dSmrg 10136ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 10236ac495dSmrg new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); 10336ac495dSmrg new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); 10436ac495dSmrg new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); 10536ac495dSmrg 10636ac495dSmrg new (&wcout) wostream(&buf_wcout_sync); 10736ac495dSmrg new (&wcin) wistream(&buf_wcin_sync); 10836ac495dSmrg new (&wcerr) wostream(&buf_wcerr_sync); 10936ac495dSmrg new (&wclog) wostream(&buf_wcerr_sync); 11036ac495dSmrg wcin.tie(&wcout); 11136ac495dSmrg wcerr.setf(ios_base::unitbuf); 11236ac495dSmrg wcerr.tie(&wcout); 11336ac495dSmrg #endif 11436ac495dSmrg 11536ac495dSmrg // NB: Have to set refcount above one, so that standard 11636ac495dSmrg // streams are not re-initialized with uses of ios_base::Init 11736ac495dSmrg // besides <iostream> static object, ie just using <ios> with 11836ac495dSmrg // ios_base::Init objects. 11936ac495dSmrg __gnu_cxx::__atomic_add_dispatch(&_S_refcount, 1); 12036ac495dSmrg } 12136ac495dSmrg } 12236ac495dSmrg ~Init()12336ac495dSmrg ios_base::Init::~Init() 12436ac495dSmrg { 12536ac495dSmrg // Be race-detector-friendly. For more info see bits/c++config. 12636ac495dSmrg _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount); 12736ac495dSmrg if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2) 12836ac495dSmrg { 12936ac495dSmrg _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount); 13036ac495dSmrg // Catch any exceptions thrown by basic_ostream::flush() 13136ac495dSmrg __try 13236ac495dSmrg { 13336ac495dSmrg // Flush standard output streams as required by 27.4.2.1.6 13436ac495dSmrg cout.flush(); 13536ac495dSmrg cerr.flush(); 13636ac495dSmrg clog.flush(); 13736ac495dSmrg 13836ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 13936ac495dSmrg wcout.flush(); 14036ac495dSmrg wcerr.flush(); 14136ac495dSmrg wclog.flush(); 14236ac495dSmrg #endif 14336ac495dSmrg } 14436ac495dSmrg __catch(...) 14536ac495dSmrg { } 14636ac495dSmrg } 14736ac495dSmrg } 14836ac495dSmrg 14936ac495dSmrg bool sync_with_stdio(bool __sync)15036ac495dSmrg ios_base::sync_with_stdio(bool __sync) 15136ac495dSmrg { 15236ac495dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 15336ac495dSmrg // 49. Underspecification of ios_base::sync_with_stdio 15436ac495dSmrg bool __ret = ios_base::Init::_S_synced_with_stdio; 15536ac495dSmrg 15636ac495dSmrg // Turn off sync with C FILE* for cin, cout, cerr, clog iff 15736ac495dSmrg // currently synchronized. 15836ac495dSmrg if (!__sync && __ret) 15936ac495dSmrg { 16036ac495dSmrg // Make sure the standard streams are constructed. 16136ac495dSmrg ios_base::Init __init; 16236ac495dSmrg 16336ac495dSmrg ios_base::Init::_S_synced_with_stdio = __sync; 16436ac495dSmrg 16536ac495dSmrg // Explicitly call dtors to free any memory that is 16636ac495dSmrg // dynamically allocated by filebuf ctor or member functions, 16736ac495dSmrg // but don't deallocate all memory by calling operator delete. 16836ac495dSmrg buf_cout_sync.~stdio_sync_filebuf<char>(); 16936ac495dSmrg buf_cin_sync.~stdio_sync_filebuf<char>(); 17036ac495dSmrg buf_cerr_sync.~stdio_sync_filebuf<char>(); 17136ac495dSmrg 17236ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 17336ac495dSmrg buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); 17436ac495dSmrg buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); 17536ac495dSmrg buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); 17636ac495dSmrg #endif 17736ac495dSmrg 17836ac495dSmrg // Create stream buffers for the standard streams and use 17936ac495dSmrg // those buffers without destroying and recreating the 18036ac495dSmrg // streams. 18136ac495dSmrg new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); 18236ac495dSmrg new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); 18336ac495dSmrg new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); 18436ac495dSmrg cout.rdbuf(&buf_cout); 18536ac495dSmrg cin.rdbuf(&buf_cin); 18636ac495dSmrg cerr.rdbuf(&buf_cerr); 18736ac495dSmrg clog.rdbuf(&buf_cerr); 18836ac495dSmrg 18936ac495dSmrg #ifdef _GLIBCXX_USE_WCHAR_T 19036ac495dSmrg new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); 19136ac495dSmrg new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); 19236ac495dSmrg new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); 19336ac495dSmrg wcout.rdbuf(&buf_wcout); 19436ac495dSmrg wcin.rdbuf(&buf_wcin); 19536ac495dSmrg wcerr.rdbuf(&buf_wcerr); 19636ac495dSmrg wclog.rdbuf(&buf_wcerr); 19736ac495dSmrg #endif 19836ac495dSmrg } 19936ac495dSmrg return __ret; 20036ac495dSmrg } 20136ac495dSmrg 20236ac495dSmrg _GLIBCXX_END_NAMESPACE_VERSION 20336ac495dSmrg } // namespace 204