This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] libstdc++/21286


Hi,

I have committed the below to mainline and 4_0, fixing a 4.0/4.1 Regression.

Tested x86-linux.

Paolo.

////////////////
2005-04-30  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.
diff -urN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
--- libstdc++-v3-orig/include/bits/fstream.tcc	2005-04-08 19:31:30.000000000 +0200
+++ libstdc++-v3/include/bits/fstream.tcc	2005-04-30 00:19:31.000000000 +0200
@@ -531,15 +531,8 @@
        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 @@
 	       __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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]