This is the mail archive of the
libstdc++@sourceware.cygnus.com
mailing list for the libstdc++ project.
Changes to basic_filebuf::sync and testsuite
- To: libstdc++ at sourceware dot cygnus dot com
- Subject: Changes to basic_filebuf::sync and testsuite
- From: scott snyder <snyder at fnal dot gov>
- Date: Mon, 15 Nov 1999 22:39:45 -0600
hi -
I noticed the following in the changelog:
1999-11-11 Benjamin Kosnik <bkoz@gnu.org>
* bits/std_fstream.h: Revert. Disable call to _M_file->sync as
killing 27_io/filebuf.cc tests. . . need another solution.
I tried to investigate why this was failing.
It looks like the problem is due to a separate bug in the libio/libstdc++
interaction which is provoked by the change.
[For the record, i'm testing this on a redhat 6.0 linux system,
which uses glibc 2.1.1.]
The failure in filebuf.cc occurs here:
pt_2 = fb_03.pubseekoff(2, std::ios_base::cur, std::ios_base::in|std::ios_base::out);
off_2 = pt_2._M_position();
test &= (off_2 == (off_1 + 2 + 1 + 1));
off_1 is 2; before the call we've seeked two chars further than off_1;
so pt_2 should return 6, but instead, it returns 2.
If i step through what's happening, i find myself in _IO_new_file_seekoff
in fileops.c of libio. This code chooses to take the `dumb' path
(branching to the label of the same name), in which it ends up simply
calling basic_file::sys_seek. (I think that it chooses this path due
to the addition of the sync call in basic_filebuf::sync, but i haven't
checked that.) The call is here:
result = _IO_SYSSEEK (fp, offset, dir);
The problem is that `offset' is declared as a _IO_off64_t, which is an
8-byte integer. Meanwhile, the function which gets called in bits/basic_file.h
is declared as:
virtual __c_streampos
sys_seek(streamoff __off, ios_base::seekdir __way);
Here, `streamoff' is a 4-byte integer. Guess calling functions through
libio's jump tables doesn't enforce type safety...
So, _IO_new_file_seekoff is trying to call sys_seek with arguments
__off==2 and __way==1 (seek_cur). But due to the type mismatch,
__way in sys_seek ends up being the high 4 bytes of __off, which
is 0, or seek_set. So the seek goes to absolute position 2, rather then
relative position 2, as intended.
Following is an attempt at a fix. With these changes, i don't see
any changes in the testsuite results, and my test of flush ordering
executes correctly. However, i have not tested this on any other platforms.
thanks,
sss
1999-11-15 Scott Snyder <snyder@fnal.gov>
* bits/basic_file.h: Type of __off parm should be __c_streampos, to
match how libio is calling us.
* src/basic_file.cc (sys_seek): Likewise.
* bits/std_fstream.h (basic_filebuf::sync): Restore sync call.
Index: bits/basic_file.h
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/basic_file.h,v
retrieving revision 1.15
diff -u -p -r1.15 basic_file.h
--- basic_file.h 1999/06/25 03:55:23 1.15
+++ basic_file.h 1999/11/16 04:01:45
@@ -169,7 +169,7 @@ namespace std {
// does no mucking around with or setting of the pointers or flags
// in __c_file_type.
virtual __c_streampos
- sys_seek(streamoff __off, ios_base::seekdir __way);
+ sys_seek(__c_streampos __off, ios_base::seekdir __way);
virtual int
sys_close();
Index: bits/std_fstream.h
===================================================================
RCS file: /cvs/libstdc++/libstdc++/bits/std_fstream.h,v
retrieving revision 1.61
diff -u -p -r1.61 std_fstream.h
--- std_fstream.h 1999/11/12 08:06:48 1.61
+++ std_fstream.h 1999/11/16 04:01:45
@@ -170,7 +170,7 @@ namespace std {
// flushed. Back up, so overflow doesn't append extra characters.
this->_M_really_overflow();
}
- // _M_file->sync();
+ _M_file->sync();
_M_last_overflowed = false;
return 0;
}
Index: src/basic_file.cc
===================================================================
RCS file: /cvs/libstdc++/libstdc++/src/basic_file.cc,v
retrieving revision 1.20
diff -u -p -r1.20 basic_file.cc
--- basic_file.cc 1999/10/18 18:57:13 1.20
+++ basic_file.cc 1999/11/16 04:01:45
@@ -224,7 +224,7 @@ namespace std {
{ return _IO_file_write(this, __s, __n); }
__c_streampos
- __basic_file::sys_seek(streamoff __off, ios_base::seekdir __way)
+ __basic_file::sys_seek(__c_streampos __off, ios_base::seekdir __way)
{ return _IO_file_seek(this, __off, __way); }
int