diff options
author | Paolo Carlini <pcarlini@unitus.it> | 2003-02-04 23:42:32 +0100 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2003-02-04 22:42:32 +0000 |
commit | 52b62c0e1a86842d44946fe7fa91775b60af85d6 (patch) | |
tree | 65c44c2de016efc62e22b368ac2174dff478f580 | |
parent | 1efd0b97d6e5f1cf93928fdeb50534b7edba1dad (diff) | |
download | gcc-52b62c0e1a86842d44946fe7fa91775b60af85d6.zip gcc-52b62c0e1a86842d44946fe7fa91775b60af85d6.tar.gz gcc-52b62c0e1a86842d44946fe7fa91775b60af85d6.tar.bz2 |
PR libstdc++/9439, PR libstdc++/9425
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.
From-SVN: r62408
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/config/io/basic_file_stdio.cc | 14 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/fstream.tcc | 39 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc | 15 |
4 files changed, 62 insertions, 19 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index de954ff..1313e40 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +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. + 2003-02-04 Jerry Quinn <jlquinn@optonline.net> * include/std/std_ostream.h (ostream::_M_write): Declare. diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc index e378b66..961523b 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.cc +++ b/libstdc++-v3/config/io/basic_file_stdio.cc @@ -203,15 +203,21 @@ namespace std __basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way, ios_base::openmode /*__mode*/) { - fseek(_M_cfile, __off, __way); - return ftell(_M_cfile); + 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*/) { - fseek(_M_cfile, __pos, ios_base::beg); - return ftell(_M_cfile); + if (!fseek(_M_cfile, __pos, ios_base::beg)) + return ftell(_M_cfile); + else + // Fseek failed. + return -1L; } int diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index c5f9758..abc7310 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -215,19 +215,24 @@ namespace std { // 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)) + // 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) { - _M_pback_create(); - *this->_M_in_cur = __c; + if (!traits_type::eq(__c, *this->_M_in_cur)) + { + _M_pback_create(); + *this->_M_in_cur = __c; + } + __ret = __i; } - __ret = __i; - } - else - __ret = traits_type::not_eof(__i); + else + __ret = traits_type::not_eof(__i); + } } } _M_last_overflowed = false; @@ -439,7 +444,8 @@ namespace std //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(); } @@ -447,9 +453,12 @@ namespace std // 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; + 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 --git a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc index 75c2e1c..58a5650 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc @@ -570,6 +570,20 @@ void test08() 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(); @@ -582,5 +596,6 @@ main() test07(); test08(); + test09(); return 0; } |