This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix libstdc++/9439 and libstdc++/9425
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Cc: bkoz <bkoz at redhat dot com>
- Date: Tue, 04 Feb 2003 22:55:17 +0100
- Subject: [Patch] Fix libstdc++/9439 and libstdc++/9425
Hi,
so here it is. In fact, these changes _should_ be pretty
safe: basic_filebuf::seekoff is currently the _only_ user
of _M_file.seekoff return value and we always do the same
as before when _M_file.seekoff doesn't fail.
However, it may turn out to be useful elsewhere to start
checking _M_file.seekoff return value...
Tested x86-linux, as usual. Ok for trunk? 3_3 too?
Paolo.
///////////
2003-02-04 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/9439, PR libstdc++/9425
* config/io/basic_file_stdio.cc
(__basic_file<char>::seekoff, seekpos): Return -1L if
fseek fails.
* include/bits/fstream.tcc (basic_filebuf::seekoff):
Check _M_file.seekoff return value; always return
pos_type(off_type(-1)) in case of failure.
(basic_filebuf::pbackfail): Check this->seekoff return
value and return traits_type::eof() in case of failure.
* testsuite/27_io/filebuf_virtuals.cc (test09): Add.
diff -prN libstdc++-v3-orig/config/io/basic_file_stdio.cc libstdc++-v3/config/io/basic_file_stdio.cc
*** libstdc++-v3-orig/config/io/basic_file_stdio.cc Tue Dec 24 03:48:19 2002
--- libstdc++-v3/config/io/basic_file_stdio.cc Tue Feb 4 19:32:02 2003
*************** namespace std
*** 203,217 ****
__basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way,
ios_base::openmode /*__mode*/)
{
! fseek(_M_cfile, __off, __way);
! return ftell(_M_cfile);
}
streamoff
__basic_file<char>::seekpos(streamoff __pos, ios_base::openmode /*__mode*/)
{
! fseek(_M_cfile, __pos, ios_base::beg);
! return ftell(_M_cfile);
}
int
--- 203,223 ----
__basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way,
ios_base::openmode /*__mode*/)
{
! if (!fseek(_M_cfile, __off, __way))
! return ftell(_M_cfile);
! else
! // Fseek failed.
! return -1L;
}
streamoff
__basic_file<char>::seekpos(streamoff __pos, ios_base::openmode /*__mode*/)
{
! if (!fseek(_M_cfile, __pos, ios_base::beg))
! return ftell(_M_cfile);
! else
! // Fseek failed.
! return -1L;
}
int
diff -prN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
*** libstdc++-v3-orig/include/bits/fstream.tcc Mon Feb 3 21:20:42 2003
--- libstdc++-v3/include/bits/fstream.tcc Tue Feb 4 22:33:23 2003
*************** namespace std
*** 215,233 ****
{
// At the beginning of the buffer, need to make a
// putback position available.
! this->seekoff(-1, ios_base::cur);
! this->underflow();
! if (!__testeof)
! {
! if (!traits_type::eq(__c, *this->_M_in_cur))
{
! _M_pback_create();
! *this->_M_in_cur = __c;
}
! __ret = __i;
! }
! else
! __ret = traits_type::not_eof(__i);
}
}
_M_last_overflowed = false;
--- 215,238 ----
{
// At the beginning of the buffer, need to make a
// putback position available.
! // But the seek may fail (f.i., at the beginning of
! // a file, see libstdc++/9439) and in that case
! // we return traits_type::eof()
! if (this->seekoff(-1, ios_base::cur) >= 0)
! {
! this->underflow();
! if (!__testeof)
{
! if (!traits_type::eq(__c, *this->_M_in_cur))
! {
! _M_pback_create();
! *this->_M_in_cur = __c;
! }
! __ret = __i;
}
! else
! __ret = traits_type::not_eof(__i);
! }
}
}
_M_last_overflowed = false;
*************** namespace std
*** 439,445 ****
//in
else if (__testget && __way == ios_base::cur)
__computed_off += this->_M_in_cur - _M_filepos;
!
__ret = _M_file.seekoff(__computed_off, __way, __mode);
_M_set_indeterminate();
}
--- 444,451 ----
//in
else if (__testget && __way == ios_base::cur)
__computed_off += this->_M_in_cur - _M_filepos;
!
! // Return pos_type(off_type(-1)) in case of failure.
__ret = _M_file.seekoff(__computed_off, __way, __mode);
_M_set_indeterminate();
}
*************** namespace std
*** 447,455 ****
// state, ie _M_file._offset == -1
else
{
! __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
! __ret +=
! std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
}
}
_M_last_overflowed = false;
--- 453,464 ----
// state, ie _M_file._offset == -1
else
{
! pos_type __tmp =
! _M_file.seekoff(__off, ios_base::cur, __mode);
! if (__tmp >= 0)
! // Seek successful.
! __ret = __tmp +
! std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos;
}
}
_M_last_overflowed = false;
diff -prN libstdc++-v3-orig/testsuite/27_io/filebuf_virtuals.cc libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc
*** libstdc++-v3-orig/testsuite/27_io/filebuf_virtuals.cc Sun Feb 2 20:02:54 2003
--- libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc Tue Feb 4 21:04:38 2003
*************** void test08()
*** 570,575 ****
--- 570,589 ----
mb.sputbackc(0);
}
+ // libstdc++/9439, libstdc++/9425
+ void test09()
+ {
+ using namespace std;
+ bool test = true;
+
+ filebuf fbuf;
+ fbuf.open(name_01, ios_base::in);
+ filebuf::int_type r = fbuf.sputbackc('a');
+ fbuf.close();
+
+ VERIFY( r == filebuf::traits_type::eof() );
+ }
+
main()
{
test01();
*************** main()
*** 582,586 ****
--- 596,601 ----
test07();
test08();
+ test09();
return 0;
}