This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[RFC] Fixing the fstream problem
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: libstdc++ at gcc dot gnu dot org
- Cc: bkoz at redhat dot com
- Date: Sat, 26 Jan 2002 22:41:13 +0100
- Subject: [RFC] Fixing the fstream problem
Hi,
I have debugged this quite a bit and the problem seems to be that close() may
fail without a real reason. In my understanding the culprit is the following
line #185 of fstream.tcc (basic_filebuf::close()):
if (__testput
&& _M_really_overflow(traits_type::eof()) != traits_type::eof())
Whenever __testput is false the if body is not executed at all, whereas, before
the 8th of January, the various finalizing operations were all carried out, only
_M_really_overflow was not called.
Therefore, naturally, I have prepared the following patch, which however is
still *not* complete, since there is a regression in the assertion at line #355
of filebuf.cc: for some reason sungetc does not work perfectly anymore :-(
Thoughts?
Cheers,
Paolo.
//////////////
diff -urN libstdc++-v3-curr/include/bits/fstream.tcc
libstdc++-v3/include/bits/fstream.tcc
--- libstdc++-v3-curr/include/bits/fstream.tcc Tue Jan 8 20:57:00 2002
+++ libstdc++-v3/include/bits/fstream.tcc Sat Jan 26 22:27:36 2002
@@ -182,8 +182,8 @@
if (this->is_open())
{
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
- if (__testput
- && _M_really_overflow(traits_type::eof()) != traits_type::eof())
+ if (!__testput ||
+ _M_really_overflow(traits_type::eof()) != traits_type::eof())
{
// NB: Do this here so that re-opened filebufs will be cool...
_M_mode = ios_base::openmode(0);
diff -urN libstdc++-v3-curr/testsuite/27_io/filebuf_members.cc
libstdc++-v3/testsuite/27_io/filebuf_members.cc
--- libstdc++-v3-curr/testsuite/27_io/filebuf_members.cc Tue Jan 8 20:57:01
2002
+++ libstdc++-v3/testsuite/27_io/filebuf_members.cc Sat Jan 26 19:33:23 2002
@@ -154,6 +154,29 @@
exit(0);
}
+// Charles Leggett <CGLeggett@lbl.gov>
+int
+test_04()
+{
+ bool test = true;
+
+ std::fstream scratch_file;
+
+ scratch_file.open("SCRATCH", std::ios::out);
+ scratch_file.close();
+
+ scratch_file.open("SCRATCH", std::ios::in);
+ scratch_file.close();
+
+ VERIFY(scratch_file);
+
+#ifdef DEBUG_ASSERT
+ assert(test);
+#endif
+
+ return test;
+}
+
int
main()
{
@@ -161,5 +184,7 @@
test_02();
test_03();
+ test_04();
+
return 0;
}