ios_init.cc revision 146897
1132720Skan// Iostreams base classes -*- C++ -*- 2132720Skan 3132720Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 4132720Skan// Free Software Foundation, Inc. 5132720Skan// 6132720Skan// This file is part of the GNU ISO C++ Library. This library is free 7132720Skan// software; you can redistribute it and/or modify it under the 8132720Skan// terms of the GNU General Public License as published by the 9132720Skan// Free Software Foundation; either version 2, or (at your option) 10132720Skan// any later version. 11132720Skan 12132720Skan// This library is distributed in the hope that it will be useful, 13132720Skan// but WITHOUT ANY WARRANTY; without even the implied warranty of 14132720Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15132720Skan// GNU General Public License for more details. 16132720Skan 17132720Skan// You should have received a copy of the GNU General Public License along 18132720Skan// with this library; see the file COPYING. If not, write to the Free 19132720Skan// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20132720Skan// USA. 21132720Skan 22132720Skan// As a special exception, you may use this file as part of a free software 23132720Skan// library without restriction. Specifically, if other files instantiate 24132720Skan// templates or use macros or inline functions from this file, or you compile 25132720Skan// this file and link it with other files to produce an executable, this 26132720Skan// file does not by itself cause the resulting executable to be covered by 27132720Skan// the GNU General Public License. This exception does not however 28132720Skan// invalidate any other reasons why the executable file might be covered by 29132720Skan// the GNU General Public License. 30132720Skan 31132720Skan// 32132720Skan// ISO C++ 14882: 27.4 Iostreams base classes 33132720Skan// 34132720Skan 35132720Skan#include <ios> 36132720Skan#include <ostream> 37132720Skan#include <istream> 38132720Skan#include <fstream> 39132720Skan#include <bits/atomicity.h> 40132720Skan#include <ext/stdio_filebuf.h> 41132720Skan#include <ext/stdio_sync_filebuf.h> 42132720Skan 43132720Skannamespace __gnu_internal 44132720Skan{ 45132720Skan using namespace __gnu_cxx; 46132720Skan 47132720Skan // Extern declarations for global objects in src/globals.cc. 48132720Skan extern stdio_sync_filebuf<char> buf_cout_sync; 49132720Skan extern stdio_sync_filebuf<char> buf_cin_sync; 50132720Skan extern stdio_sync_filebuf<char> buf_cerr_sync; 51132720Skan 52132720Skan extern stdio_filebuf<char> buf_cout; 53132720Skan extern stdio_filebuf<char> buf_cin; 54132720Skan extern stdio_filebuf<char> buf_cerr; 55132720Skan 56132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 57132720Skan extern stdio_sync_filebuf<wchar_t> buf_wcout_sync; 58132720Skan extern stdio_sync_filebuf<wchar_t> buf_wcin_sync; 59132720Skan extern stdio_sync_filebuf<wchar_t> buf_wcerr_sync; 60132720Skan 61132720Skan extern stdio_filebuf<wchar_t> buf_wcout; 62132720Skan extern stdio_filebuf<wchar_t> buf_wcin; 63132720Skan extern stdio_filebuf<wchar_t> buf_wcerr; 64132720Skan#endif 65132720Skan} // namespace __gnu_internal 66132720Skan 67132720Skannamespace std 68132720Skan{ 69132720Skan using namespace __gnu_internal; 70132720Skan 71132720Skan extern istream cin; 72132720Skan extern ostream cout; 73132720Skan extern ostream cerr; 74132720Skan extern ostream clog; 75132720Skan 76132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 77132720Skan extern wistream wcin; 78132720Skan extern wostream wcout; 79132720Skan extern wostream wcerr; 80132720Skan extern wostream wclog; 81132720Skan#endif 82132720Skan 83132720Skan ios_base::Init::Init() 84132720Skan { 85132720Skan if (__gnu_cxx::__exchange_and_add(&_S_refcount, 1) == 0) 86132720Skan { 87132720Skan // Standard streams default to synced with "C" operations. 88132720Skan _S_synced_with_stdio = true; 89132720Skan 90132720Skan new (&buf_cout_sync) stdio_sync_filebuf<char>(stdout); 91132720Skan new (&buf_cin_sync) stdio_sync_filebuf<char>(stdin); 92132720Skan new (&buf_cerr_sync) stdio_sync_filebuf<char>(stderr); 93132720Skan 94132720Skan // The standard streams are constructed once only and never 95132720Skan // destroyed. 96132720Skan new (&cout) ostream(&buf_cout_sync); 97132720Skan new (&cin) istream(&buf_cin_sync); 98132720Skan new (&cerr) ostream(&buf_cerr_sync); 99132720Skan new (&clog) ostream(&buf_cerr_sync); 100132720Skan cin.tie(&cout); 101132720Skan cerr.flags(ios_base::unitbuf); 102132720Skan 103132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 104132720Skan new (&buf_wcout_sync) stdio_sync_filebuf<wchar_t>(stdout); 105132720Skan new (&buf_wcin_sync) stdio_sync_filebuf<wchar_t>(stdin); 106132720Skan new (&buf_wcerr_sync) stdio_sync_filebuf<wchar_t>(stderr); 107132720Skan 108132720Skan new (&wcout) wostream(&buf_wcout_sync); 109132720Skan new (&wcin) wistream(&buf_wcin_sync); 110132720Skan new (&wcerr) wostream(&buf_wcerr_sync); 111132720Skan new (&wclog) wostream(&buf_wcerr_sync); 112132720Skan wcin.tie(&wcout); 113132720Skan wcerr.flags(ios_base::unitbuf); 114132720Skan#endif 115132720Skan 116132720Skan // NB: Have to set refcount above one, so that standard 117132720Skan // streams are not re-initialized with uses of ios_base::Init 118132720Skan // besides <iostream> static object, ie just using <ios> with 119132720Skan // ios_base::Init objects. 120132720Skan __gnu_cxx::__atomic_add(&_S_refcount, 1); 121132720Skan } 122132720Skan } 123132720Skan 124132720Skan ios_base::Init::~Init() 125132720Skan { 126132720Skan if (__gnu_cxx::__exchange_and_add(&_S_refcount, -1) == 2) 127132720Skan { 128132720Skan // Catch any exceptions thrown by basic_ostream::flush() 129132720Skan try 130132720Skan { 131132720Skan // Flush standard output streams as required by 27.4.2.1.6 132132720Skan cout.flush(); 133132720Skan cerr.flush(); 134132720Skan clog.flush(); 135132720Skan 136132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 137132720Skan wcout.flush(); 138132720Skan wcerr.flush(); 139132720Skan wclog.flush(); 140132720Skan#endif 141132720Skan } 142132720Skan catch (...) 143132720Skan { } 144132720Skan } 145132720Skan } 146132720Skan 147132720Skan bool 148132720Skan ios_base::sync_with_stdio(bool __sync) 149132720Skan { 150132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 151132720Skan // 49. Underspecification of ios_base::sync_with_stdio 152132720Skan bool __ret = ios_base::Init::_S_synced_with_stdio; 153132720Skan 154132720Skan // Turn off sync with C FILE* for cin, cout, cerr, clog iff 155132720Skan // currently synchronized. 156132720Skan if (!__sync && __ret) 157132720Skan { 158146897Skan // Make sure the standard streams are constructed. 159146897Skan ios_base::Init __init; 160146897Skan 161132720Skan ios_base::Init::_S_synced_with_stdio = __sync; 162132720Skan 163132720Skan // Explicitly call dtors to free any memory that is 164132720Skan // dynamically allocated by filebuf ctor or member functions, 165132720Skan // but don't deallocate all memory by calling operator delete. 166132720Skan buf_cout_sync.~stdio_sync_filebuf<char>(); 167132720Skan buf_cin_sync.~stdio_sync_filebuf<char>(); 168132720Skan buf_cerr_sync.~stdio_sync_filebuf<char>(); 169132720Skan 170132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 171132720Skan buf_wcout_sync.~stdio_sync_filebuf<wchar_t>(); 172132720Skan buf_wcin_sync.~stdio_sync_filebuf<wchar_t>(); 173132720Skan buf_wcerr_sync.~stdio_sync_filebuf<wchar_t>(); 174132720Skan#endif 175132720Skan 176132720Skan // Create stream buffers for the standard streams and use 177132720Skan // those buffers without destroying and recreating the 178132720Skan // streams. 179132720Skan new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out); 180132720Skan new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in); 181132720Skan new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out); 182132720Skan cout.rdbuf(&buf_cout); 183132720Skan cin.rdbuf(&buf_cin); 184132720Skan cerr.rdbuf(&buf_cerr); 185132720Skan clog.rdbuf(&buf_cerr); 186132720Skan 187132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 188132720Skan new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out); 189132720Skan new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in); 190132720Skan new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out); 191132720Skan wcout.rdbuf(&buf_wcout); 192132720Skan wcin.rdbuf(&buf_wcin); 193132720Skan wcerr.rdbuf(&buf_wcerr); 194132720Skan wclog.rdbuf(&buf_wcerr); 195132720Skan#endif 196132720Skan } 197132720Skan return __ret; 198132720Skan } 199132720Skan} // namespace std 200