changeset 8717:3afefd650c3a

On BSD implementations, when we call lseek(), we must also update or disable the stream's file descriptor position cache.
author Bruno Haible <bruno@clisp.org>
date Thu, 26 Apr 2007 09:25:05 +0000
parents 43a9fb438a48
children c541fe12ef9e
files ChangeLog lib/fflush.c lib/fseeko.c tests/test-fflush.c
diffstat 4 files changed, 49 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-04-26  Bruno Haible  <bruno@clisp.org>
+
+	* tests/test-fflush.c (main): Also check the ftell result after
+	fflush and fseek/fseeko.
+	* lib/fflush.c (rpl_fflush): For BSD implementations, update the
+	file descriptor position cache in the stream.
+	* lib/fseeko.c (rpl_fseeko): Likewise.
+
 2007-04-26  Bruno Haible  <bruno@clisp.org>
 
 	* modules/fflush-tests (Depends-on): Add fseeko.
--- a/lib/fflush.c
+++ b/lib/fflush.c
@@ -58,7 +58,14 @@
      semantics of fpurge are now appropriate to clear the buffer.  To
      avoid losing data, the lseek is also necessary.  */
   result = fpurge (stream);
-  if (result == 0 && lseek (fileno (stream), pos, SEEK_SET) == -1)
+  if (result != 0)
+    return result;
+  pos = lseek (fileno (stream), pos, SEEK_SET);
+  if (pos == -1)
     return EOF;
-  return result;
+#if defined __sferror               /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
+  stream->_offset = pos;
+  stream->_flags |= __SOFF;
+#endif
+  return 0;
 }
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -66,7 +66,24 @@
 #else
   #error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib."
 #endif
-    return (lseek (fileno (fp), offset, whence) == (off_t)(-1) ? -1 : 0);
+    {
+      off_t pos = lseek (fileno (fp), offset, whence);
+      if (pos == -1)
+	{
+#if defined __sferror               /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
+	  fp->_flags &= ~__SOFF;
+#endif
+	  return -1;
+	}
+      else
+	{
+#if defined __sferror               /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */
+	  fp->_offset = pos;
+	  fp->_flags |= __SOFF;
+#endif
+	  return 0;
+	}
+    }
   else
     return fseeko (fp, offset, whence);
 }
--- a/tests/test-fflush.c
+++ b/tests/test-fflush.c
@@ -74,6 +74,13 @@
       unlink ("test-fflush.txt");
       return 1;
     }
+  if (ftell (f) != 5)
+    {
+      fputs ("ftell result is wrong after fseek.\n", stderr);
+      fclose (f);
+      unlink ("test-fflush.txt");
+      return 1;
+    }
   /* Check that file reading resumes at correct location.  */
   if (fgetc (f) != '6')
     {
@@ -106,6 +113,13 @@
       unlink ("test-fflush.txt");
       return 1;
     }
+  if (ftell (f) != 6)
+    {
+      fputs ("ftell result is wrong after fseek.\n", stderr);
+      fclose (f);
+      unlink ("test-fflush.txt");
+      return 1;
+    }
   /* Check that file reading resumes at correct location.  */
   if (fgetc (f) != '7')
     {