re PR libstdc++/21286 (filebuf::xsgetn vs pipes)
authorPaolo Carlini <pcarlini@suse.de>
Sat, 30 Apr 2005 06:54:08 +0000 (06:54 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sat, 30 Apr 2005 06:54:08 +0000 (06:54 +0000)
2005-04-29  Paolo Carlini  <pcarlini@suse.de>
    Nathan Myers  <ncm@cantrip.org>

PR libstdc++/21286
* include/bits/fstream.tcc (basic_filebuf<>::xsgetn):
Loop on short reads; remove the work-around for
libstdc++/20806, not needed anymore.

Co-Authored-By: Nathan Myers <ncm@cantrip.org>
From-SVN: r99033

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc

index 164aee42cc610404f91909231758f2625e6abdf1..48f8a7d3f88df56780cd904cb909ac7da305cc3d 100644 (file)
@@ -1,3 +1,11 @@
+2005-04-29  Paolo Carlini  <pcarlini@suse.de>
+           Nathan Myers  <ncm@cantrip.org>
+
+       PR libstdc++/21286
+       * include/bits/fstream.tcc (basic_filebuf<>::xsgetn):
+       Loop on short reads; remove the work-around for
+       libstdc++/20806, not needed anymore.
+
 2005-04-29  Paolo Carlini  <pcarlini@suse.de>
 
        PR libstdc++/21238
index 6915ea9b23c0effc29cde557ca6deb9cc7de2b84..40bf428e2c1f726206fbdb47be9d003f077a0897 100644 (file)
@@ -531,15 +531,8 @@ namespace std
        const bool __testin = _M_mode & ios_base::in;
        const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
 
-#if _GLIBCXX_HAVE_DOS_BASED_FILESYSTEM
-       // About this workaround, see libstdc++/20806.
-       const bool __testbinary = _M_mode & ios_base::binary;
-       if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
-          && __testin && __testbinary && !_M_writing)
-#else
        if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
           && __testin && !_M_writing)
-#endif
         {
           // First, copy the chars already present in the buffer.
           const streamsize __avail = this->egptr() - this->gptr();
@@ -555,13 +548,28 @@ namespace std
               __n -= __avail;
             }
 
-          const streamsize __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
-                                                  __n);
-          if (__len == -1)
-            __throw_ios_failure(__N("basic_filebuf::xsgetn "
-                                    "error reading the file"));
-          __ret += __len;
-          if (__len == __n)
+          // Need to loop in case of short reads (relatively common
+          // with pipes).
+          streamsize __len;
+          for (;;)
+            {
+              __len = _M_file.xsgetn(reinterpret_cast<char*>(__s),
+                                     __n);
+              if (__len == -1)
+                __throw_ios_failure(__N("basic_filebuf::xsgetn "
+                                        "error reading the file"));
+              if (__len == 0)
+                break;
+
+              __n -= __len;
+              __ret += __len;
+              if (__n == 0)
+                break;
+
+              __s += __len;
+            }
+
+          if (__n == 0)
             {
               _M_set_buffer(0);
               _M_reading = true;