A couple problems with c_io_stdio.cc

scott snyder snyder@fnal.gov
Mon Nov 20 20:40:00 GMT 2000


hi -

The cstdio implementation of libstd++-v3 streams doesn't work
correctly when the output is redirected to a file.  Here's an example:

-------------------------------------------------------------------------
#include <iostream>

using std::cout;
using std::endl;

int main(int argc, char **argv) 
{
  cout << "Known expanders: \n" << endl;
  cout << "   ListFileExpander" << endl;
  cout << "Input wildcard"  << endl;

  return 0;
}
-------------------------------------------------------------------------

When i run this with the output going to the terminal, it appears
to work correctly:

$ ./h2
Known expanders: 

   ListFileExpander
Input wildcard


But with the output redirected to a file, this is what happens:

$ ./h2 > zz
$ cat zz
Known expanders: 

 Input wildcard
der


The problem here seems to be with the seek routines in c_io_stdio.cc.
It looks like they're supposed to return the file offset after the seek.
However, what they are actually returning is the return value from
fseek(), which is always 0 if the seek was successful.


Here's a quick patch for this:

2000-11-20  scott snyder  <snyder@fnal.gov>

	* config/c_io_stdio.cc (seekoff): Fix return value.
	(seekpos): Likewise.
	(sys_seek): Likewise.

Index: c_io_stdio.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/c_io_stdio.cc,v
retrieving revision 1.1
diff -u -p -r1.1 c_io_stdio.cc
--- c_io_stdio.cc	2000/11/01 21:36:48	1.1
+++ c_io_stdio.cc	2000/11/21 03:56:43
@@ -160,13 +160,13 @@ namespace std {
     streamoff
     __basic_file<_CharT>::seekoff(streamoff __off, ios_base::seekdir __way, 
 				  ios_base::openmode /*__mode*/)
-   { return fseek(_M_cfile, __off, __way); }
+   { fseek(_M_cfile, __off, __way); return ftell (_M_cfile); }
 
   template<typename _CharT>
     streamoff
     __basic_file<_CharT>::seekpos(streamoff __pos, 
 				  ios_base::openmode /*__mode*/)
-   { return fseek(_M_cfile, __pos, ios_base::beg); }
+   { fseek(_M_cfile, __pos, ios_base::beg); return ftell (_M_cfile); }
 
   template<typename _CharT>
     int 
@@ -225,7 +225,7 @@ namespace std {
   template<typename _CharT>
     streamoff
     __basic_file<_CharT>::sys_seek(streamoff __pos, ios_base::seekdir __way)
-   { return fseek(_M_cfile, __pos, __way); }
+   { fseek(_M_cfile, __pos, __way); return ftell (_M_cfile); }
   
   // NB: Unused.
   template<typename _CharT>



And here's another problem.  Consider this example:

-------------------------------------------------------------------------
#include <iostream>
#include <stdio.h>
main ()
{
  std::cout << "yo!" << std::endl;
  printf ("sad\n");
}
-------------------------------------------------------------------------

Again, when i send the output to the terminal, it seems to do the right
thing:

$ ./h
yo!
sad

But if i redirect the output to a file, the result of the printf()
is missing.

$ ./h > zz
$ cat zz
yo!
$


The problem here seems to be that when the __basic_file destructor
runs, it closes FD 2 before the C stdout FILE* gets flushed.

I put in this patch to work around this problem.
I don't really think it's correct, though.

2000-11-20  scott snyder  <snyder@fnal.gov>

	* config/c_io_stdio.cc (~__basic_file): Don't close the file here
	--- it may still be in use by stdio.

Index: c_io_stdio.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/c_io_stdio.cc,v
retrieving revision 1.1
diff -u -p -r1.1 c_io_stdio.cc
--- c_io_stdio.cc	2000/11/01 21:36:48	1.1
+++ c_io_stdio.cc	2000/11/21 04:14:23
@@ -51,7 +51,7 @@ namespace std {
       if (this->is_open())
 	{
 	  fflush(_M_cfile);
-	  this->close();
+	  //this->close();
 	}
     }
       


thanks,
sss


More information about the Libstdc++ mailing list