This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

[RFC] 9533: fourth iteration


Hi again,

this is my current best proposal.
I don't think such kind of syntax:

AC_DEFINE(_GLIBCPP_S_ISREG_OR_S_IFREG(m), (S_IFREG & (m)))

can really be used. Therefore I deal separately with the two cases
(i.e., S_ISREG and S_IFREG).

About ioctl, I haven't been able to find an example of a modern
system having it in <ioctl.h>, not in <sys/ioctl.h> or <sys/filio.h>,
therefore I'm relying on the code which I stolen from libjava:
seems to work well there for a variety of different platforms.

Paolo.

//////////
diff -urN libstdc++-v3-orig/acconfig.h libstdc++-v3/acconfig.h
--- libstdc++-v3-orig/acconfig.h	2002-11-13 23:49:20.000000000 +0100
+++ libstdc++-v3/acconfig.h	2003-03-23 15:32:59.000000000 +0100
@@ -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 -urN libstdc++-v3-orig/acinclude.m4 libstdc++-v3/acinclude.m4
--- libstdc++-v3-orig/acinclude.m4	2003-03-12 22:34:22.000000000 +0100
+++ libstdc++-v3/acinclude.m4	2003-03-23 15:33:46.000000000 +0100
@@ -2106,6 +2106,45 @@
 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 at cygnus dot com>, 1995.
diff -urN libstdc++-v3-orig/config/io/basic_file_stdio.cc libstdc++-v3/config/io/basic_file_stdio.cc
--- libstdc++-v3-orig/config/io/basic_file_stdio.cc	2003-03-10 07:55:00.000000000 +0100
+++ libstdc++-v3/config/io/basic_file_stdio.cc	2003-03-23 15:34:34.000000000 +0100
@@ -36,6 +36,24 @@
 #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>
+#endif
+
 namespace std 
 {
   // Definitions for __basic_file<char>.
@@ -76,11 +94,7 @@
     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 +170,6 @@
 	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 +268,47 @@
   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   
+
+#ifdef _GLIBCPP_HAVE_S_ISREG
+    // Regular files.
+    struct stat __buffer;
+    int __ret = fstat(this->fd(), &__buffer);
+    if (!__ret && S_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);
+#elif _GLIBCPP_HAVE_S_IFREG
+    // Regular files.
+    struct stat __buffer;
+    int __ret = fstat(this->fd(), &__buffer);
+    if (!__ret && (S_IFREG & __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 -urN libstdc++-v3-orig/config/io/basic_file_stdio.h libstdc++-v3/config/io/basic_file_stdio.h
--- libstdc++-v3-orig/config/io/basic_file_stdio.h	2003-03-09 23:31:44.000000000 +0100
+++ libstdc++-v3/config/io/basic_file_stdio.h	2003-03-22 18:04:12.000000000 +0100
@@ -108,6 +108,9 @@
 
       int 
       sync();
+
+      streamsize
+      showmanyc_helper(bool __stdio);
     };
 }  // namespace std

diff -urN libstdc++-v3-orig/configure.in libstdc++-v3/configure.in
--- libstdc++-v3-orig/configure.in	2003-03-14 16:12:06.000000000 +0100
+++ libstdc++-v3/configure.in	2003-03-23 09:59:32.000000000 +0100
@@ -411,6 +411,12 @@
   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 -urN libstdc++-v3-orig/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
--- libstdc++-v3-orig/include/bits/fstream.tcc	2003-03-17 19:44:44.000000000 +0100
+++ libstdc++-v3/include/bits/fstream.tcc	2003-03-22 18:28:43.000000000 +0100
@@ -96,13 +96,6 @@
 	      // 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 @@
     {
       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;
     }

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