This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


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

Patch: FIONREAD / PR 3


I'm committing the appended patch.  It fixes PR #3.  It changes the
POSIX implementation of available() to use lseek/fstat when FIONREAD
fails.

1999-09-03  Tom Tromey  <tromey@cygnus.com>

	* configure: Rebuilt.
	* configure.in: Check for fstat function.
	* java/io/natFileDescriptorPosix.cc (available): Use fstat() if
	FIONREAD fails.

Tom

Index: configure.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/configure.in,v
retrieving revision 1.27
diff -u -r1.27 configure.in
--- configure.in	1999/09/02 06:26:58	1.27
+++ configure.in	1999/09/03 07:37:19
@@ -302,7 +302,7 @@
       GCJ=
    fi
 else
-   AC_CHECK_FUNCS(strerror ioctl select open fsync sleep)
+   AC_CHECK_FUNCS(strerror ioctl select fstat open fsync sleep)
    AC_CHECK_FUNCS(ctime_r ctime, break)
    AC_CHECK_FUNCS(gmtime_r localtime_r readdir_r getpwuid_r)
    AC_CHECK_FUNCS(access stat mkdir rename rmdir unlink realpath)
Index: java/io/natFileDescriptorPosix.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/natFileDescriptorPosix.cc,v
retrieving revision 1.2
diff -u -r1.2 natFileDescriptorPosix.cc
--- natFileDescriptorPosix.cc	1999/08/03 00:32:14	1.2
+++ natFileDescriptorPosix.cc	1999/09/03 07:37:19
@@ -234,18 +234,59 @@
 jint
 java::io::FileDescriptor::available (void)
 {
+#if defined (FIONREAD) || defined (HAVE_SELECT) || defined (HAVE_FSTAT)
+  long num = 0;
+  int r = 0;
+  bool num_set = false;
+
 #if defined (FIONREAD)
-  long num;
-  int r = ::ioctl (fd, FIONREAD, &num);
-  if (r == -1)
-    JvThrow (new IOException (JvNewStringLatin1 (strerror (errno))));
-  return (jint) num;
+  r = ::ioctl (fd, FIONREAD, &num);
+  if (r == -1 && errno == ENOTTY)
+    {
+      // If the ioctl doesn't work, we don't care.
+      r = 0;
+      num = 0;
+    }
+  else
+    num_set = true;
 #elif defined (HAVE_SELECT)
-  int r = -1;
   if (fd < 0)
-    errno = EBADF;
-  else
     {
+      errno = EBADF;
+      r = -1;
+    }
+#endif
+
+  if (r == -1)
+    {
+    posix_error:
+      JvThrow (new IOException (JvNewStringLatin1 (strerror (errno))));
+    }
+
+  // If we didn't get anything, and we have fstat, then see if see if
+  // we're reading a regular file.  On many systems, FIONREAD does not
+  // work on regular files; select() likewise returns a useless
+  // result.  This is run incorrectly when FIONREAD does work on
+  // regular files and we are at the end of the file.  However, this
+  // case probably isn't very important.
+#if defined (HAVE_FSTAT)
+  if (! num_set)
+    {
+      struct stat sb;
+      off_t where;
+      if (fstat (fd, &sb) != -1
+	  && S_ISREG (sb.st_mode)
+	  && (where = lseek (fd, SEEK_CUR, 0)) != (off_t) -1)
+	{
+	  num = (long) (sb.st_size - where);
+	  num_set = true;
+	}
+    }
+#endif /* HAVE_FSTAT */
+
+#if defined (HAVE_SELECT)
+  if (! num_set)
+    {
       fd_set rd;
       FD_ZERO (&rd);
       FD_SET (fd, &rd);
@@ -253,10 +294,13 @@
       tv.tv_sec = 0;
       tv.tv_usec = 0;
       r = ::select (fd + 1, &rd, NULL, NULL, &tv);
+      if (r == -1)
+	goto posix_error;
+      num = r == 0 ? 0 : 1;
     }
-  if (r == -1)
-    JvThrow (new IOException (JvNewStringLatin1 (strerror (errno))));
-  return r == 0 ? 0 : 1;
+#endif /* HAVE_SELECT */
+
+  return (jint) num;
 #else
   JvThrow (new IOException (JvNewStringLatin1 ("unimplemented")));
 #endif

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