PR libstdc++/9439, PR libstdc++/9425
authorPaolo Carlini <pcarlini@unitus.it>
Tue, 4 Feb 2003 22:42:32 +0000 (23:42 +0100)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 4 Feb 2003 22:42:32 +0000 (22:42 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/config/io/basic_file_stdio.cc
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/testsuite/27_io/filebuf_virtuals.cc

index de954ffbc1974278a5bc4b2da4516dc9e4e82794..1313e4028b4f3e0ddd0f23a50d792579c229c6b2 100644 (file)
@@ -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.       
index e378b6668a72c441e1f405ecf86361805eaf8ef5..961523b0dcd7f7e2ff898bf88bacc72c056bbf1c 100644 (file)
@@ -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 
index c5f9758da278966fc7e5df82e8ce616844e3b91f..abc7310e32d001f32bda0c38823d8cd97cca39e7 100644 (file)
@@ -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;      
index 75c2e1cac77c0354980b5cfe18116b24d88db0c0..58a565095835634811dfd2d1ecff6aaa13da6e22 100644 (file)
@@ -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;
 }