From bbacb998c8f265fb6d51716eb707c73b07d9ccdf Mon Sep 17 00:00:00 2001
From: Paolo Carlini <pcarlini@unitus.it>
Date: Fri, 28 Mar 2003 19:28:47 +0100
Subject: [PATCH] re PR libstdc++/9533 (Can't read from tty with ifstream)

2003-03-28  Paolo Carlini  <pcarlini@unitus.it>
	    Nathan Myers  <ncm@cantrip.org>

	PR libstdc++/9533
	* include/bits/fstream.tcc (basic_filebuf<>::open): Don't
	call underflow().
	(basic_filebuf<>::showmanyc): Use the information provided
	by codecvt and __basic_file<>::showmanyc_helper to implement
	a non-trivial showmanyc.
	* config/io/basic_file_stdio.h
	(__basic_file<>::showmanyc_helper): New, declare.
	* config/io/basic_file_stdio.cc
	(__basic_file<>::showmanyc_helper): Define.
	(__basic_file<>::_M_open_mode): Don't set O_NONBLOCK.
	(__basic_file<char>::open): Don't call fcntl().
	* acinclude.m4 (GLIBCPP_CHECK_S_ISREG_OR_S_IFREG,
	GLIBCPP_CHECK_POLL): New macros.
	* configure.in: Call here.
	* acconfig.h: Add #undefs for the corresponding symbols.
	* aclocal.m4: Regenerate.
	* configure: Regenerate.
	* config.h.in: Regenerate.

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

From-SVN: r64978
---
 libstdc++-v3/ChangeLog                     |  23 ++
 libstdc++-v3/acconfig.h                    |   9 +
 libstdc++-v3/acinclude.m4                  |  39 ++++
 libstdc++-v3/aclocal.m4                    |  45 +++-
 libstdc++-v3/config.h.in                   |  15 ++
 libstdc++-v3/config/io/basic_file_stdio.cc |  68 +++++-
 libstdc++-v3/config/io/basic_file_stdio.h  |   3 +
 libstdc++-v3/configure                     | 231 +++++++++++++++++----
 libstdc++-v3/configure.in                  |   6 +
 libstdc++-v3/include/bits/fstream.tcc      |  21 +-
 10 files changed, 394 insertions(+), 66 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f5efdcbe0e02..c038ba07ee90 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,26 @@
+2003-03-28  Paolo Carlini  <pcarlini@unitus.it>
+            Nathan Myers  <ncm@cantrip.org>
+
+	PR libstdc++/9533
+	* include/bits/fstream.tcc (basic_filebuf<>::open): Don't
+	call underflow().
+	(basic_filebuf<>::showmanyc): Use the information provided
+	by codecvt and __basic_file<>::showmanyc_helper to implement
+	a non-trivial showmanyc.
+	* config/io/basic_file_stdio.h
+	(__basic_file<>::showmanyc_helper): New, declare.
+	* config/io/basic_file_stdio.cc
+	(__basic_file<>::showmanyc_helper): Define.
+	(__basic_file<>::_M_open_mode): Don't set O_NONBLOCK.
+	(__basic_file<char>::open): Don't call fcntl().
+	* acinclude.m4 (GLIBCPP_CHECK_S_ISREG_OR_S_IFREG,
+	GLIBCPP_CHECK_POLL): New macros.
+	* configure.in: Call here.
+	* acconfig.h: Add #undefs for the corresponding symbols.
+	* aclocal.m4: Regenerate.
+	* configure: Regenerate.
+	* config.h.in: Regenerate.
+
 2003-03-24  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* config/linker-map.gnu: Remove string export restrictions.
diff --git a/libstdc++-v3/acconfig.h b/libstdc++-v3/acconfig.h
index 4d18634889f1..91af8fa31aec 100644
--- a/libstdc++-v3/acconfig.h
+++ b/libstdc++-v3/acconfig.h
@@ -135,6 +135,15 @@
 // Define if the compiler/host combination has __builtin_sqrtl
 #undef HAVE___BUILTIN_SQRTL
 
+// Define if poll is available in <poll.h>.
+#undef HAVE_POLL
+
+// Define if S_ISREG (Posix) is available in <sys/stat.h>.
+#undef HAVE_S_ISREG
+
+// Define if S_IFREG is available in <sys/stat.h>.
+#undef HAVE_S_IFREG
+
 // Define if LC_MESSAGES is available in <locale.h>.
 #undef HAVE_LC_MESSAGES
 
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 920eb8a78354..4f72efaf8cda 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2106,6 +2106,45 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN])
 AC_DEFUN([AC_PROG_LD])
 ])
 
+dnl
+dnl Check whether S_ISREG (Posix) or S_IFREG is available in <sys/stat.h>.
+dnl
+
+AC_DEFUN(GLIBCPP_CHECK_S_ISREG_OR_S_IFREG, [
+  AC_CACHE_VAL(glibcpp_cv_S_ISREG, [
+    AC_TRY_LINK([#include <sys/stat.h>],
+                [struct stat buffer; fstat(0, &buffer); S_ISREG(buffer.st_mode); ],
+                [glibcpp_cv_S_ISREG=yes],
+                [glibcpp_cv_S_ISREG=no])
+  ])
+  AC_CACHE_VAL(glibcpp_cv_S_IFREG, [
+    AC_TRY_LINK([#include <sys/stat.h>],
+                [struct stat buffer; fstat(0, &buffer); S_IFREG & buffer.st_mode; ],
+                [glibcpp_cv_S_IFREG=yes],
+                [glibcpp_cv_S_IFREG=no])
+  ])
+  if test x$glibcpp_cv_S_ISREG = xyes; then
+    AC_DEFINE(HAVE_S_ISREG)
+  elif test x$glibcpp_cv_S_IFREG = xyes; then
+    AC_DEFINE(HAVE_S_IFREG)
+  fi
+])
+
+dnl
+dnl Check whether poll is available in <poll.h>.
+dnl
+
+AC_DEFUN(GLIBCPP_CHECK_POLL, [
+  AC_CACHE_VAL(glibcpp_cv_POLL, [
+    AC_TRY_COMPILE([#include <poll.h>],
+                [struct pollfd pfd[1]; pfd[0].events = POLLIN; poll(pfd, 1, 0); ],
+                [glibcpp_cv_POLL=yes],
+                [glibcpp_cv_POLL=no])
+  ])
+  if test x$glibcpp_cv_POLL = xyes; then
+    AC_DEFINE(HAVE_POLL)
+  fi
+])
 
 # Check whether LC_MESSAGES is available in <locale.h>.
 # Ulrich Drepper <drepper@cygnus.com>, 1995.
diff --git a/libstdc++-v3/aclocal.m4 b/libstdc++-v3/aclocal.m4
index 93c0e40ad3ae..167212ce6755 100644
--- a/libstdc++-v3/aclocal.m4
+++ b/libstdc++-v3/aclocal.m4
@@ -1932,7 +1932,11 @@ if test x"$glibcpp_toolexecdir" = x"no"; then
     glibcpp_toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
     glibcpp_toolexeclibdir='$(libdir)'
   fi
-  glibcpp_toolexeclibdir=$glibcpp_toolexeclibdir/`$CC -print-multi-os-directory`
+  multi_os_directory=`$CC -print-multi-os-directory`
+  case $multi_os_directory in
+  .) ;; # Avoid trailing /.
+  *) glibcpp_toolexeclibdir=$glibcpp_toolexeclibdir/$multi_os_directory ;;
+  esac
 fi
 
 AC_MSG_CHECKING([for install location])
@@ -2114,6 +2118,45 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN])
 AC_DEFUN([AC_PROG_LD])
 ])
 
+dnl
+dnl Check whether S_ISREG (Posix) or S_IFREG is available in <sys/stat.h>.
+dnl
+
+AC_DEFUN(GLIBCPP_CHECK_S_ISREG_OR_S_IFREG, [
+  AC_CACHE_VAL(glibcpp_cv_S_ISREG, [
+    AC_TRY_LINK([#include <sys/stat.h>],
+                [struct stat buffer; fstat(0, &buffer); S_ISREG(buffer.st_mode); ],
+                [glibcpp_cv_S_ISREG=yes],
+                [glibcpp_cv_S_ISREG=no])
+  ])
+  AC_CACHE_VAL(glibcpp_cv_S_IFREG, [
+    AC_TRY_LINK([#include <sys/stat.h>],
+                [struct stat buffer; fstat(0, &buffer); S_IFREG & buffer.st_mode; ],
+                [glibcpp_cv_S_IFREG=yes],
+                [glibcpp_cv_S_IFREG=no])
+  ])
+  if test x$glibcpp_cv_S_ISREG = xyes; then
+    AC_DEFINE(HAVE_S_ISREG)
+  elif test x$glibcpp_cv_S_IFREG = xyes; then
+    AC_DEFINE(HAVE_S_IFREG)
+  fi
+])
+
+dnl
+dnl Check whether poll is available in <poll.h>.
+dnl
+
+AC_DEFUN(GLIBCPP_CHECK_POLL, [
+  AC_CACHE_VAL(glibcpp_cv_POLL, [
+    AC_TRY_COMPILE([#include <poll.h>],
+                [struct pollfd pfd[1]; pfd[0].events = POLLIN; poll(pfd, 1, 0); ],
+                [glibcpp_cv_POLL=yes],
+                [glibcpp_cv_POLL=no])
+  ])
+  if test x$glibcpp_cv_POLL = xyes; then
+    AC_DEFINE(HAVE_POLL)
+  fi
+])
 
 # Check whether LC_MESSAGES is available in <locale.h>.
 # Ulrich Drepper <drepper@cygnus.com>, 1995.
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index aab9b2441012..f0b34c82a17a 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -113,6 +113,15 @@
 // Define if the compiler/host combination has __builtin_sqrtl
 #undef HAVE___BUILTIN_SQRTL
 
+// Define if poll is available in <poll.h>.
+#undef HAVE_POLL
+
+// Define if S_ISREG (Posix) is available in <sys/stat.h>.
+#undef HAVE_S_ISREG
+
+// Define if S_IFREG is available in <sys/stat.h>.
+#undef HAVE_S_IFREG
+
 // Define if LC_MESSAGES is available in <locale.h>.
 #undef HAVE_LC_MESSAGES
 
@@ -740,6 +749,12 @@
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
+/* Define if you have the <sys/filio.h> header file.  */
+#undef HAVE_SYS_FILIO_H
+
+/* Define if you have the <sys/ioctl.h> header file.  */
+#undef HAVE_SYS_IOCTL_H
+
 /* Define if you have the <sys/isa_defs.h> header file.  */
 #undef HAVE_SYS_ISA_DEFS_H
 
diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc
index 7f4c909e5740..b2287b24f7f8 100644
--- a/libstdc++-v3/config/io/basic_file_stdio.cc
+++ b/libstdc++-v3/config/io/basic_file_stdio.cc
@@ -36,6 +36,29 @@
 #include <unistd.h>
 #include <errno.h>
 
+#ifdef _GLIBCPP_HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+
+// Pick up FIONREAD on Solaris 2.5.
+#ifdef _GLIBCPP_HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#ifdef _GLIBCPP_HAVE_POLL
+#include <poll.h>
+#endif
+
+#if defined(_GLIBCPP_HAVE_S_ISREG) || defined(_GLIBCPP_HAVE_S_IFREG)
+# include <sys/stat.h>
+# ifdef _GLIBCPP_HAVE_S_ISREG
+#  define _GLIBCPP_ISREG(x) S_ISREG(x)
+# else
+#  define _GLIBCPP_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+# endif
+#endif
+
 namespace std 
 {
   // Definitions for __basic_file<char>.
@@ -76,11 +99,7 @@ namespace std
     if (__testi && !__testo && !__testt && !__testa)
       {
 	strcpy(__c_mode, "r");
-#if defined (O_NONBLOCK)
-	__p_mode |=  O_RDONLY | O_NONBLOCK;
-#else
 	__p_mode |=  O_RDONLY;
-#endif
       }
     if (__testi && __testo && !__testt && !__testa)
       {
@@ -156,13 +175,6 @@ namespace std
 	if ((_M_cfile = fopen(__name, __c_mode)))
 	  {
 	    _M_cfile_created = true;
-
-#if defined (F_SETFL) && defined (O_NONBLOCK)
-	    // Set input to nonblocking for fifos.
-	    if (__mode & ios_base::in)
-	      fcntl(this->fd(), F_SETFL, O_NONBLOCK);
-#endif
-
 	    __ret = this;
 	  }
       }
@@ -261,4 +273,38 @@ namespace std
   int 
   __basic_file<char>::sync() 
   { return fflush(_M_cfile); }
+
+  streamsize
+  __basic_file<char>::showmanyc_helper(bool __stdio)
+  {
+#ifdef FIONREAD
+    // Pipes and sockets.    
+    int __num = 0;
+    int __r = ioctl(this->fd(), FIONREAD, &__num);
+    if (!__r && __num >= 0)
+      return __num; 
+#endif    
+
+#ifdef _GLIBCPP_HAVE_POLL
+    // Cheap test.
+    struct pollfd __pfd[1];
+    __pfd[0].fd = this->fd();
+    __pfd[0].events = POLLIN;
+    if (poll(__pfd, 1, 0) <= 0)
+      return 0;
+#endif   
+
+#if defined(_GLIBCPP_HAVE_S_ISREG) || defined(_GLIBCPP_HAVE_S_IFREG)
+    // Regular files.
+    struct stat __buffer;
+    int __ret = fstat(this->fd(), &__buffer);
+    if (!__ret && _GLIBCPP_ISREG(__buffer.st_mode))
+      if (__stdio)
+	return __buffer.st_size - ftell(_M_cfile);
+      else
+	return __buffer.st_size - lseek(this->fd(), 0, ios_base::cur);
+#endif
+    return 0;
+  }
+
 }  // namespace std
diff --git a/libstdc++-v3/config/io/basic_file_stdio.h b/libstdc++-v3/config/io/basic_file_stdio.h
index b01e4a5db10f..b6a05697612a 100644
--- a/libstdc++-v3/config/io/basic_file_stdio.h
+++ b/libstdc++-v3/config/io/basic_file_stdio.h
@@ -108,6 +108,9 @@ namespace std
 
       int 
       sync();
+
+      streamsize
+      showmanyc_helper(bool __stdio);
     };
 }  // namespace std
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 05385ca9dcf4..c4722cfadb65 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -22739,20 +22739,159 @@ done
 
   CXXFLAGS="$ac_save_CXXFLAGS"
 
+
+  # For showmanyc_helper().
+  for ac_hdr in sys/ioctl.h sys/filio.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:22749: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 22754 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:22759: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+  
+  if eval "test \"`echo '$''{'glibcpp_cv_POLL'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 22791 "configure"
+#include "confdefs.h"
+#include <poll.h>
+int main() {
+struct pollfd pfd[1]; pfd[0].events = POLLIN; poll(pfd, 1, 0); 
+; return 0; }
+EOF
+if { (eval echo configure:22798: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  glibcpp_cv_POLL=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  glibcpp_cv_POLL=no
+fi
+rm -f conftest*
+  
+fi
+
+  if test x$glibcpp_cv_POLL = xyes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_POLL 1
+EOF
+
+  fi
+
+  
+  if eval "test \"`echo '$''{'glibcpp_cv_S_ISREG'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 22824 "configure"
+#include "confdefs.h"
+#include <sys/stat.h>
+int main() {
+struct stat buffer; fstat(0, &buffer); S_ISREG(buffer.st_mode); 
+; return 0; }
+EOF
+if { (eval echo configure:22831: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  glibcpp_cv_S_ISREG=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  glibcpp_cv_S_ISREG=no
+fi
+rm -f conftest*
+  
+fi
+
+  if eval "test \"`echo '$''{'glibcpp_cv_S_IFREG'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 22849 "configure"
+#include "confdefs.h"
+#include <sys/stat.h>
+int main() {
+struct stat buffer; fstat(0, &buffer); S_IFREG & buffer.st_mode; 
+; return 0; }
+EOF
+if { (eval echo configure:22856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  glibcpp_cv_S_IFREG=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  glibcpp_cv_S_IFREG=no
+fi
+rm -f conftest*
+  
+fi
+
+  if test x$glibcpp_cv_S_ISREG = xyes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_S_ISREG 1
+EOF
+
+  elif test x$glibcpp_cv_S_IFREG = xyes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_S_IFREG 1
+EOF
+
+  fi
+
+
   
   ac_safe=`echo "locale.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for locale.h""... $ac_c" 1>&6
-echo "configure:22746: checking for locale.h" >&5
+echo "configure:22885: checking for locale.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 22751 "configure"
+#line 22890 "configure"
 #include "confdefs.h"
 #include <locale.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:22756: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:22895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -22770,19 +22909,19 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   
     echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:22774: checking for LC_MESSAGES" >&5
+echo "configure:22913: checking for LC_MESSAGES" >&5
 if eval "test \"`echo '$''{'ac_cv_val_LC_MESSAGES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 22779 "configure"
+#line 22918 "configure"
 #include "confdefs.h"
 #include <locale.h>
 int main() {
 return LC_MESSAGES
 ; return 0; }
 EOF
-if { (eval echo configure:22786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:22925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_val_LC_MESSAGES=yes
 else
@@ -22809,7 +22948,7 @@ fi
 
 
   cat > conftest.$ac_ext <<EOF
-#line 22813 "configure"
+#line 22952 "configure"
 #include "confdefs.h"
 
   #include <setjmp.h>
@@ -22818,7 +22957,7 @@ int main() {
 sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);
 ; return 0; }
 EOF
-if { (eval echo configure:22822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:22961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_SIGSETJMP 1
@@ -22835,17 +22974,17 @@ rm -f conftest*
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:22839: checking for $ac_hdr" >&5
+echo "configure:22978: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 22844 "configure"
+#line 22983 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:22849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:22988: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -22874,12 +23013,12 @@ done
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:22878: checking for $ac_func" >&5
+echo "configure:23017: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 22883 "configure"
+#line 23022 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -22902,7 +23041,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:22906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:23045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -22927,7 +23066,7 @@ fi
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:22931: checking for working mmap" >&5
+echo "configure:23070: checking for working mmap" >&5
 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -22935,7 +23074,7 @@ else
   ac_cv_func_mmap_fixed_mapped=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 22939 "configure"
+#line 23078 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -23075,7 +23214,7 @@ main()
 }
 
 EOF
-if { (eval echo configure:23079: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:23218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -23106,17 +23245,17 @@ fi
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:23110: checking for $ac_hdr" >&5
+echo "configure:23249: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 23115 "configure"
+#line 23254 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:23120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:23259: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -23149,7 +23288,7 @@ done
     # Can't do these in a loop, else the resulting syntax is wrong.
     
   cat > conftest.$ac_ext <<EOF
-#line 23153 "configure"
+#line 23292 "configure"
 #include "confdefs.h"
 #include <unistd.h>
                   #include <sys/time.h>
@@ -23159,7 +23298,7 @@ int main() {
  int f = RLIMIT_DATA ; 
 ; return 0; }
 EOF
-if { (eval echo configure:23163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23302: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   glibcpp_mresult=1
 else
@@ -23176,7 +23315,7 @@ EOF
 
     
   cat > conftest.$ac_ext <<EOF
-#line 23180 "configure"
+#line 23319 "configure"
 #include "confdefs.h"
 #include <unistd.h>
                   #include <sys/time.h>
@@ -23186,7 +23325,7 @@ int main() {
  int f = RLIMIT_RSS ; 
 ; return 0; }
 EOF
-if { (eval echo configure:23190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23329: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   glibcpp_mresult=1
 else
@@ -23203,7 +23342,7 @@ EOF
 
     
   cat > conftest.$ac_ext <<EOF
-#line 23207 "configure"
+#line 23346 "configure"
 #include "confdefs.h"
 #include <unistd.h>
                   #include <sys/time.h>
@@ -23213,7 +23352,7 @@ int main() {
  int f = RLIMIT_VMEM ; 
 ; return 0; }
 EOF
-if { (eval echo configure:23217: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23356: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   glibcpp_mresult=1
 else
@@ -23230,7 +23369,7 @@ EOF
 
     
   cat > conftest.$ac_ext <<EOF
-#line 23234 "configure"
+#line 23373 "configure"
 #include "confdefs.h"
 #include <unistd.h>
                   #include <sys/time.h>
@@ -23240,7 +23379,7 @@ int main() {
  int f = RLIMIT_AS ; 
 ; return 0; }
 EOF
-if { (eval echo configure:23244: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23383: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   glibcpp_mresult=1
 else
@@ -23262,7 +23401,7 @@ EOF
 else
   
       cat > conftest.$ac_ext <<EOF
-#line 23266 "configure"
+#line 23405 "configure"
 #include "confdefs.h"
 #include <unistd.h>
                   #include <sys/time.h>
@@ -23272,7 +23411,7 @@ int main() {
  struct rlimit r; setrlimit(0, &r);
 ; return 0; }
 EOF
-if { (eval echo configure:23276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23415: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_setrlimit=yes
 else
@@ -23288,7 +23427,7 @@ fi
   fi
 
   echo $ac_n "checking for testsuite memory limit support""... $ac_c" 1>&6
-echo "configure:23292: checking for testsuite memory limit support" >&5
+echo "configure:23431: checking for testsuite memory limit support" >&5
   if test $setrlimit_have_headers = yes && test $ac_setrlimit = yes; then
     ac_mem_limits=yes
     cat >> confdefs.h <<\EOF
@@ -23304,7 +23443,7 @@ EOF
   # Look for setenv, so that extended locale tests can be performed.
   
   echo $ac_n "checking for setenv declaration""... $ac_c" 1>&6
-echo "configure:23308: checking for setenv declaration" >&5
+echo "configure:23447: checking for setenv declaration" >&5
   if test x${glibcpp_cv_func_setenv_use+set} != xset; then
     if eval "test \"`echo '$''{'glibcpp_cv_func_setenv_use'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -23319,14 +23458,14 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes
 cross_compiling=$ac_cv_prog_cxx_cross
 
       cat > conftest.$ac_ext <<EOF
-#line 23323 "configure"
+#line 23462 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 int main() {
  setenv(0, 0, 0);
 ; return 0; }
 EOF
-if { (eval echo configure:23330: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:23469: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   glibcpp_cv_func_setenv_use=yes
 else
@@ -23352,12 +23491,12 @@ fi
     for ac_func in setenv
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:23356: checking for $ac_func" >&5
+echo "configure:23495: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 23361 "configure"
+#line 23500 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -23380,7 +23519,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:23384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:23523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -23457,18 +23596,18 @@ fi
 # Check to see if libgcc_s exists, indicating that shared libgcc is possible.
 if test $enable_symvers != no; then
   echo $ac_n "checking for shared libgcc""... $ac_c" 1>&6
-echo "configure:23461: checking for shared libgcc" >&5
+echo "configure:23600: checking for shared libgcc" >&5
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=' -lgcc_s'
   cat > conftest.$ac_ext <<EOF
-#line 23465 "configure"
+#line 23604 "configure"
 #include "confdefs.h"
 
 int main() {
 return 0
 ; return 0; }
 EOF
-if { (eval echo configure:23472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:23611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   glibcpp_shared_libgcc=yes
 else
@@ -23503,14 +23642,14 @@ if test $enable_symvers = yes ; then
       echo 'FOO { global: f[a-z]o; local: *; };' > conftest.map
       
       cat > conftest.$ac_ext <<EOF
-#line 23507 "configure"
+#line 23646 "configure"
 #include "confdefs.h"
 int foo;
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:23514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:23653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   enable_symvers=gnu
 else
@@ -23556,7 +23695,7 @@ else
   GLIBCPP_BUILD_VERSIONED_SHLIB_FALSE=
 fi
 echo $ac_n "checking versioning on shared library symbols""... $ac_c" 1>&6
-echo "configure:23560: checking versioning on shared library symbols" >&5
+echo "configure:23699: checking versioning on shared library symbols" >&5
 echo "$ac_t""$enable_symvers" 1>&6
 
 
@@ -23643,7 +23782,7 @@ glibcpp_prefixdir=${prefix}
 
 # Process the option --with-gxx-include-dir=<path to include-files directory>
 echo $ac_n "checking for --with-gxx-include-dir""... $ac_c" 1>&6
-echo "configure:23647: checking for --with-gxx-include-dir" >&5
+echo "configure:23786: checking for --with-gxx-include-dir" >&5
 # Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
 if test "${with_gxx_include_dir+set}" = set; then
   withval="$with_gxx_include_dir"
@@ -23667,7 +23806,7 @@ echo "$ac_t""$gxx_include_dir" 1>&6
 
 # Process the option "--enable-version-specific-runtime-libs"
 echo $ac_n "checking for --enable-version-specific-runtime-libs""... $ac_c" 1>&6
-echo "configure:23671: checking for --enable-version-specific-runtime-libs" >&5
+echo "configure:23810: checking for --enable-version-specific-runtime-libs" >&5
 # Check whether --enable-version-specific-runtime-libs or --disable-version-specific-runtime-libs was given.
 if test "${enable_version_specific_runtime_libs+set}" = set; then
   enableval="$enable_version_specific_runtime_libs"
@@ -23718,7 +23857,7 @@ if test x"$glibcpp_toolexecdir" = x"no"; then
 fi
 
 echo $ac_n "checking for install location""... $ac_c" 1>&6
-echo "configure:23722: checking for install location" >&5
+echo "configure:23861: checking for install location" >&5
 echo "$ac_t""$gxx_include_dir" 1>&6
 
 
diff --git a/libstdc++-v3/configure.in b/libstdc++-v3/configure.in
index 279c9f46c632..b9da74a2c403 100644
--- a/libstdc++-v3/configure.in
+++ b/libstdc++-v3/configure.in
@@ -411,6 +411,12 @@ else
   GLIBCPP_CHECK_COMPLEX_MATH_SUPPORT
   GLIBCPP_CHECK_WCHAR_T_SUPPORT
   GLIBCPP_CHECK_STDLIB_SUPPORT
+
+  # For showmanyc_helper().
+  AC_CHECK_HEADERS(sys/ioctl.h sys/filio.h)
+  GLIBCPP_CHECK_POLL
+  GLIBCPP_CHECK_S_ISREG_OR_S_IFREG
+
   AC_LC_MESSAGES
 
   AC_TRY_COMPILE([
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index d854d0b883af..b5529de35ef3 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -96,13 +96,6 @@ namespace std
 	      // Setup initial position of buffer.
 	      _M_set_indeterminate();
 
-	      // Set input buffer to something real.
-	      // NB: Must open in non-blocking way to do this, or must
-	      // set the initial position in a different manner than
-	      // using underflow.
- 	      if (__mode & ios_base::in && _M_buf_allocated)
- 		this->underflow();
-
 	      if ((__mode & ios_base::ate)
 		  && this->seekoff(0, ios_base::end, __mode) < 0)
 		{
@@ -164,9 +157,21 @@ namespace std
     {
       streamsize __ret = -1;
       bool __testin = this->_M_mode & ios_base::in;
+      const locale __loc = this->getloc();
+      const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
+      // Sync with stdio.
+      bool __sync = this->_M_buf_size == 1;
 
       if (__testin && this->is_open())
-	__ret = this->_M_in_end - this->_M_in_cur;
+	{
+	  __ret = this->_M_in_end - this->_M_in_cur;
+
+	  // For a stateful encoding (-1) the pending sequence might be just
+	  // shift and unshift prefixes with no actual character.
+	  if (__cvt.encoding() >= 0)
+	    __ret += _M_file.showmanyc_helper(__sync) / __cvt.max_length();
+	}
+
       _M_last_overflowed = false;	
       return __ret;
     }
-- 
GitLab