# <rdar://problem/4497649> sync_with_stdio(false) causes cin input to be truncated early --- gcc-4.0.0/libstdc++-v3/include/bits/fstream.tcc 2005-04-08 13:34:30.000000000 -0400 +++ libstdc++-v3/include/bits/fstream.tcc 2006-04-18 13:49:03.000000000 -0400 @@ -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;