148fb7bfaSmrg // Iostreams base classes -*- C++ -*- 248fb7bfaSmrg 3*b1e83836Smrg // Copyright (C) 1997-2022 Free Software Foundation, Inc. 448fb7bfaSmrg // 548fb7bfaSmrg // This file is part of the GNU ISO C++ Library. This library is free 648fb7bfaSmrg // software; you can redistribute it and/or modify it under the 748fb7bfaSmrg // terms of the GNU General Public License as published by the 848fb7bfaSmrg // Free Software Foundation; either version 3, or (at your option) 948fb7bfaSmrg // any later version. 1048fb7bfaSmrg 1148fb7bfaSmrg // This library is distributed in the hope that it will be useful, 1248fb7bfaSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1348fb7bfaSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1448fb7bfaSmrg // GNU General Public License for more details. 1548fb7bfaSmrg 1648fb7bfaSmrg // Under Section 7 of GPL version 3, you are granted additional 1748fb7bfaSmrg // permissions described in the GCC Runtime Library Exception, version 1848fb7bfaSmrg // 3.1, as published by the Free Software Foundation. 1948fb7bfaSmrg 2048fb7bfaSmrg // You should have received a copy of the GNU General Public License and 2148fb7bfaSmrg // a copy of the GCC Runtime Library Exception along with this program; 2248fb7bfaSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2348fb7bfaSmrg // <http://www.gnu.org/licenses/>. 2448fb7bfaSmrg 2548fb7bfaSmrg // 2648fb7bfaSmrg // ISO C++ 14882: 27.4 Iostreams base classes 2748fb7bfaSmrg // 2848fb7bfaSmrg 2948fb7bfaSmrg #include <ios> 3048fb7bfaSmrg #include <ostream> 3148fb7bfaSmrg #include <istream> 3248fb7bfaSmrg #include <fstream> 3348fb7bfaSmrg #include <ext/stdio_filebuf.h> 3448fb7bfaSmrg #include <ext/stdio_sync_filebuf.h> 3548fb7bfaSmrg 3648fb7bfaSmrg namespace __gnu_internal _GLIBCXX_VISIBILITY(hidden) 3748fb7bfaSmrg { 3848fb7bfaSmrg using namespace __gnu_cxx; 3948fb7bfaSmrg 405f4cdc7dSskrll // Extern declarations for global objects in src/c++98/globals.cc. 4148fb7bfaSmrg extern stdio_sync_filebuf<char> buf_cout_sync; 4248fb7bfaSmrg extern stdio_sync_filebuf<char> buf_cin_sync; 4348fb7bfaSmrg extern stdio_sync_filebuf<char> buf_cerr_sync; 4448fb7bfaSmrg 4548fb7bfaSmrg extern stdio_filebuf<char> buf_cout; 4648fb7bfaSmrg extern stdio_filebuf<char> buf_cin; 4748fb7bfaSmrg extern stdio_filebuf<char> buf_cerr; 4848fb7bfaSmrg 4948fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 5048fb7bfaSmrg extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; 5148fb7bfaSmrg extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; 5248fb7bfaSmrg extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; 5348fb7bfaSmrg 5448fb7bfaSmrg extern stdio_filebuf<wchar_t> buf_wcout; 5548fb7bfaSmrg extern stdio_filebuf<wchar_t> buf_wcin; 5648fb7bfaSmrg extern stdio_filebuf<wchar_t> buf_wcerr; 5748fb7bfaSmrg #endif 5848fb7bfaSmrg } // namespace __gnu_internal 5948fb7bfaSmrg 6048fb7bfaSmrg namespace std _GLIBCXX_VISIBILITY(default) 6148fb7bfaSmrg { 6248fb7bfaSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 6348fb7bfaSmrg 6448fb7bfaSmrg using namespace __gnu_internal; 6548fb7bfaSmrg 6648fb7bfaSmrg extern istream cin; 6748fb7bfaSmrg extern ostream cout; 6848fb7bfaSmrg extern ostream cerr; 6948fb7bfaSmrg extern ostream clog; 7048fb7bfaSmrg 7148fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 7248fb7bfaSmrg extern wistream wcin; 7348fb7bfaSmrg extern wostream wcout; 7448fb7bfaSmrg extern wostream wcerr; 7548fb7bfaSmrg extern wostream wclog; 7648fb7bfaSmrg #endif 7748fb7bfaSmrg Init()7848fb7bfaSmrg ios_base::Init::Init() 7948fb7bfaSmrg { 8048fb7bfaSmrg if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, 1) == 0) 8148fb7bfaSmrg { 8248fb7bfaSmrg // Standard streams default to synced with "C" operations. 8348fb7bfaSmrg _S_synced_with_stdio = true; 8448fb7bfaSmrg 8548fb7bfaSmrg new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); 8648fb7bfaSmrg new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); 8748fb7bfaSmrg new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); 8848fb7bfaSmrg 8948fb7bfaSmrg // The standard streams are constructed once only and never 9048fb7bfaSmrg // destroyed. 9148fb7bfaSmrg new (&cout) ostream(&buf_cout_sync); 9248fb7bfaSmrg new (&cin) istream(&buf_cin_sync); 9348fb7bfaSmrg new (&cerr) ostream(&buf_cerr_sync); 9448fb7bfaSmrg new (&clog) ostream(&buf_cerr_sync); 9548fb7bfaSmrg cin.tie(&cout); 9648fb7bfaSmrg cerr.setf(ios_base::unitbuf); 9748fb7bfaSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 9848fb7bfaSmrg // 455. cerr::tie() and wcerr::tie() are overspecified. 9948fb7bfaSmrg cerr.tie(&cout); 10048fb7bfaSmrg 10148fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 10248fb7bfaSmrg new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); 10348fb7bfaSmrg new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); 10448fb7bfaSmrg new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); 10548fb7bfaSmrg 10648fb7bfaSmrg new (&wcout) wostream(&buf_wcout_sync); 10748fb7bfaSmrg new (&wcin) wistream(&buf_wcin_sync); 10848fb7bfaSmrg new (&wcerr) wostream(&buf_wcerr_sync); 10948fb7bfaSmrg new (&wclog) wostream(&buf_wcerr_sync); 11048fb7bfaSmrg wcin.tie(&wcout); 11148fb7bfaSmrg wcerr.setf(ios_base::unitbuf); 11248fb7bfaSmrg wcerr.tie(&wcout); 11348fb7bfaSmrg #endif 11448fb7bfaSmrg 11548fb7bfaSmrg // NB: Have to set refcount above one, so that standard 11648fb7bfaSmrg // streams are not re-initialized with uses of ios_base::Init 11748fb7bfaSmrg // besides <iostream> static object, ie just using <ios> with 11848fb7bfaSmrg // ios_base::Init objects. 11948fb7bfaSmrg __gnu_cxx::__atomic_add_dispatch(&_S_refcount, 1); 12048fb7bfaSmrg } 12148fb7bfaSmrg } 12248fb7bfaSmrg ~Init()12348fb7bfaSmrg ios_base::Init::~Init() 12448fb7bfaSmrg { 12548fb7bfaSmrg // Be race-detector-friendly. For more info see bits/c++config. 12648fb7bfaSmrg _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount); 12748fb7bfaSmrg if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2) 12848fb7bfaSmrg { 12948fb7bfaSmrg _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount); 13048fb7bfaSmrg // Catch any exceptions thrown by basic_ostream::flush() 13148fb7bfaSmrg __try 13248fb7bfaSmrg { 13348fb7bfaSmrg // Flush standard output streams as required by 27.4.2.1.6 13448fb7bfaSmrg cout.flush(); 13548fb7bfaSmrg cerr.flush(); 13648fb7bfaSmrg clog.flush(); 13748fb7bfaSmrg 13848fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 13948fb7bfaSmrg wcout.flush(); 14048fb7bfaSmrg wcerr.flush(); 14148fb7bfaSmrg wclog.flush(); 14248fb7bfaSmrg #endif 14348fb7bfaSmrg } 14448fb7bfaSmrg __catch(...) 14548fb7bfaSmrg { } 14648fb7bfaSmrg } 14748fb7bfaSmrg } 14848fb7bfaSmrg 14948fb7bfaSmrg bool sync_with_stdio(bool __sync)15048fb7bfaSmrg ios_base::sync_with_stdio(bool __sync) 15148fb7bfaSmrg { 15248fb7bfaSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 15348fb7bfaSmrg // 49. Underspecification of ios_base::sync_with_stdio 15448fb7bfaSmrg bool __ret = ios_base::Init::_S_synced_with_stdio; 15548fb7bfaSmrg 15648fb7bfaSmrg // Turn off sync with C FILE* for cin, cout, cerr, clog iff 15748fb7bfaSmrg // currently synchronized. 15848fb7bfaSmrg if (!__sync && __ret) 15948fb7bfaSmrg { 16048fb7bfaSmrg // Make sure the standard streams are constructed. 16148fb7bfaSmrg ios_base::Init __init; 16248fb7bfaSmrg 16348fb7bfaSmrg ios_base::Init::_S_synced_with_stdio = __sync; 16448fb7bfaSmrg 16548fb7bfaSmrg // Explicitly call dtors to free any memory that is 16648fb7bfaSmrg // dynamically allocated by filebuf ctor or member functions, 16748fb7bfaSmrg // but don't deallocate all memory by calling operator delete. 16848fb7bfaSmrg buf_cout_sync.~stdio_sync_filebuf<char>(); 16948fb7bfaSmrg buf_cin_sync.~stdio_sync_filebuf<char>(); 17048fb7bfaSmrg buf_cerr_sync.~stdio_sync_filebuf<char>(); 17148fb7bfaSmrg 17248fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 17348fb7bfaSmrg buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); 17448fb7bfaSmrg buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); 17548fb7bfaSmrg buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); 17648fb7bfaSmrg #endif 17748fb7bfaSmrg 17848fb7bfaSmrg // Create stream buffers for the standard streams and use 17948fb7bfaSmrg // those buffers without destroying and recreating the 18048fb7bfaSmrg // streams. 18148fb7bfaSmrg new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); 18248fb7bfaSmrg new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); 18348fb7bfaSmrg new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); 18448fb7bfaSmrg cout.rdbuf(&buf_cout); 18548fb7bfaSmrg cin.rdbuf(&buf_cin); 18648fb7bfaSmrg cerr.rdbuf(&buf_cerr); 18748fb7bfaSmrg clog.rdbuf(&buf_cerr); 18848fb7bfaSmrg 18948fb7bfaSmrg #ifdef _GLIBCXX_USE_WCHAR_T 19048fb7bfaSmrg new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); 19148fb7bfaSmrg new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); 19248fb7bfaSmrg new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); 19348fb7bfaSmrg wcout.rdbuf(&buf_wcout); 19448fb7bfaSmrg wcin.rdbuf(&buf_wcin); 19548fb7bfaSmrg wcerr.rdbuf(&buf_wcerr); 19648fb7bfaSmrg wclog.rdbuf(&buf_wcerr); 19748fb7bfaSmrg #endif 19848fb7bfaSmrg } 19948fb7bfaSmrg return __ret; 20048fb7bfaSmrg } 20148fb7bfaSmrg 20248fb7bfaSmrg _GLIBCXX_END_NAMESPACE_VERSION 20348fb7bfaSmrg } // namespace 204