diff options
-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 de954ffbc19..1313e4028b4 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 e378b6668a7..961523b0dcd 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 c5f9758da27..abc7310e32d 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 75c2e1cac77..58a56509583 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; } |