This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

stdio synching and startup code (was Re: segfaults after loading shared libstdc++)



I'm merging two topics with this one message, because they are starting
to become more and more related.



On Tue, Jan 09, 2001 at 04:23:05AM +0300, Artem Khodush wrote:
> 
> But later in the  ios_base::Init::Init() (file src/ios.cc), that single filebuf 
> is destroyed four times:

That is a little bit odd.

I like your idea of explicitly closing things up just once, but

> +   extern filebuf __cfileinit;
> + #ifdef _GLIBCPP_USE_WCHAR_T
> +   extern wfilebuf __wfileinit;
> + #endif

is not how we want to do it, I believe.  The __cfileinit object is meant
to be local to stdstreams.cc; referencing it by its name from another file
increases coupling unnecessarily.

However, we can get to that same filebuf using member functions, and then
close it up -- *once*, not four times :-) -- using its dtor.  The revision
below uses an "__old" pointer.

I had used a similar method in messing with sync_with_stdio(),
which is in the same file.  The patch below is a modification of
Artem Khodush's patch to Init() along with my patch to s_w_s().
The testsuite is still happy, plus the example code I used
in http://gcc.gnu.org/ml/libstdc++/2000-12/msg00264.html (the
hello-filesystem-world bit) now does the right thing.

Comments?  Artem, does this variation still fix your apache code?




Index: ios.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.9
diff -c -3 -p -r1.9 ios.cc
*** ios.cc	2001/01/06 02:44:11	1.9
--- ios.cc	2001/01/10 04:04:51
*************** namespace std 
*** 126,147 ****
      if (++_S_ios_base_init == 1)
        {
  	// NB: std_iostream.h creates the four standard files with
! 	// default buffers. At this point, we swap out the default
! 	// buffers for the properly-constructed ones, and dispose of
! 	// the default buffers.
  	streambuf* __old;
!        	_M_cout = new filebuf(1, "stdout", ios_base::out);
  	_M_cin = new filebuf(0, "stdin", ios_base::in);
  	_M_cerr = new filebuf(2, "stderr", ios_base::out);
  	__old = cout.rdbuf(_M_cout);
! 	__old->~streambuf();
! 	__old = cin.rdbuf(_M_cin);
! 	__old->~streambuf();
  	cin.tie(&cout);
! 	__old = cerr.rdbuf(_M_cerr);
! 	__old->~streambuf();
  	cerr.flags(ios_base::unitbuf);
! 	__old = clog.rdbuf(_M_cerr);
  	__old->~streambuf();
  #ifdef _GLIBCPP_USE_WCHAR_T
  	wstreambuf* __wold;
--- 126,144 ----
      if (++_S_ios_base_init == 1)
        {
  	// NB: std_iostream.h creates the four standard files with
! 	// one default buffer (__cfileinit).  At this point, we swap
! 	// out the default buffer for the properly-constructed ones,
! 	// and close the default buffer.
  	streambuf* __old;
! 	_M_cout = new filebuf(1, "stdout", ios_base::out);
  	_M_cin = new filebuf(0, "stdin", ios_base::in);
  	_M_cerr = new filebuf(2, "stderr", ios_base::out);
  	__old = cout.rdbuf(_M_cout);
! 	cin.rdbuf(_M_cin);
  	cin.tie(&cout);
! 	cerr.rdbuf(_M_cerr);
  	cerr.flags(ios_base::unitbuf);
! 	clog.rdbuf(_M_cerr);
  	__old->~streambuf();
  #ifdef _GLIBCPP_USE_WCHAR_T
  	wstreambuf* __wold;
*************** namespace std 
*** 149,162 ****
  	_M_wcin = new wfilebuf(0, "stdin", ios_base::in);
  	_M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
  	__wold = wcout.rdbuf(_M_wcout);
! 	__wold->~wstreambuf();
! 	__wold = wcin.rdbuf(_M_wcin);
! 	__wold->~wstreambuf();
  	wcin.tie(&wcout);
! 	__wold = wcerr.rdbuf(_M_wcerr);
! 	__wold->~wstreambuf();
  	wcerr.flags(ios_base::unitbuf);
! 	__wold = wclog.rdbuf(_M_wcerr);
  	__wold->~wstreambuf();
  #endif
  	_M_synced_with_stdio = true;
--- 146,156 ----
  	_M_wcin = new wfilebuf(0, "stdin", ios_base::in);
  	_M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
  	__wold = wcout.rdbuf(_M_wcout);
! 	wcin.rdbuf(_M_wcin);
  	wcin.tie(&wcout);
! 	wcerr.rdbuf(_M_wcerr);
  	wcerr.flags(ios_base::unitbuf);
! 	wclog.rdbuf(_M_wcerr);
  	__wold->~wstreambuf();
  #endif
  	_M_synced_with_stdio = true;
*************** namespace std 
*** 322,356 ****
      if (!__sync && __ret)
        {
  	// Need to dispose of the buffers created at initialization.
! 	__ioinit._M_cout->~filebuf();
! 	__ioinit._M_cin->~filebuf();
! 	__ioinit._M_cerr->~filebuf();
! 	__ioinit._M_cout = new filebuf();
! 	__ioinit._M_cin = new filebuf();
! 	__ioinit._M_cerr = new filebuf();
! 	__ioinit._M_cout->open("stdout", ios_base::out);
! 	__ioinit._M_cin->open("stdin", ios_base::in);
! 	__ioinit._M_cerr->open("stderr", ios_base::out);
! 	cout.rdbuf(__ioinit._M_cout);
! 	cin.rdbuf(__ioinit._M_cin);
! 	cerr.rdbuf(__ioinit._M_cerr);
  	cerr.flags(ios_base::unitbuf);
! 	clog.rdbuf(__ioinit._M_cerr);
  #ifdef _GLIBCPP_USE_WCHAR_T
! 	__ioinit._M_wcout->~wfilebuf();
! 	__ioinit._M_wcin->~wfilebuf();
! 	__ioinit._M_wcerr->~wfilebuf();
! 	__ioinit._M_wcout = new wfilebuf();
! 	__ioinit._M_wcin = new wfilebuf();
! 	__ioinit._M_wcerr = new wfilebuf();
! 	__ioinit._M_wcout->open("wstdout", ios_base::out);
! 	__ioinit._M_wcin->open("wstdin", ios_base::in);
! 	__ioinit._M_wcerr->open("wstderr", ios_base::out);
! 	wcout.rdbuf(__ioinit._M_wcout);
! 	wcin.rdbuf(__ioinit._M_wcin);
! 	wcerr.rdbuf(__ioinit._M_wcerr);
  	wcerr.flags(ios_base::unitbuf);
! 	wclog.rdbuf(__ioinit._M_wcerr);
  #endif
  	__ioinit._M_synced_with_stdio = false;
        }
--- 316,339 ----
      if (!__sync && __ret)
        {
  	// Need to dispose of the buffers created at initialization.
! 	// Build new (ergo non-synchronized) buffers, switch pointers.
! 	__ioinit._M_cout = new filebuf(1, "stdout", ios_base::out);
! 	__ioinit._M_cin = new filebuf(0, "stdin", ios_base::in);
! 	__ioinit._M_cerr = new filebuf(2, "stderr", ios_base::out);
! 	delete cout.rdbuf(__ioinit._M_cout);
! 	delete cin.rdbuf(__ioinit._M_cin);
! 	delete cerr.rdbuf(__ioinit._M_cerr);
  	cerr.flags(ios_base::unitbuf);
! 	delete clog.rdbuf(__ioinit._M_cerr);
  #ifdef _GLIBCPP_USE_WCHAR_T
! 	__ioinit._M_wcout = new wfilebuf(1, "wstdout", ios_base::out);
! 	__ioinit._M_wcin = new wfilebuf(0, "wstdin", ios_base::in);
! 	__ioinit._M_werrt = new wfilebuf(2, "wstderr", ios_base::out);
! 	delete wcout.rdbuf(__ioinit._M_wcout);
! 	delete wcin.rdbuf(__ioinit._M_wcin);
! 	delete wcerr.rdbuf(__ioinit._M_wcerr);
  	wcerr.flags(ios_base::unitbuf);
! 	delete wclog.rdbuf(__ioinit._M_wcerr);
  #endif
  	__ioinit._M_synced_with_stdio = false;
        }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]