On BSD implementations, when we call lseek(), we must also update or disable
authorBruno Haible <bruno@clisp.org>
Thu, 26 Apr 2007 09:25:05 +0000 (09:25 +0000)
committerBruno Haible <bruno@clisp.org>
Thu, 26 Apr 2007 09:25:05 +0000 (09:25 +0000)
the stream's file descriptor position cache.

ChangeLog
lib/fflush.c
lib/fseeko.c
tests/test-fflush.c

index ddc5038d2594b18f0ec37f826e4edda78fba1cee..ad0547e1888422f30fbc1d99174f45175278ae6f 100644 (file)
--- 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.
index 7481e669196fd9dddca4514a7ccb7a45f4d78e8c..aae6ac67a39fa746f67a8084b6fde675aa36ccfd 100755 (executable)
@@ -58,7 +58,14 @@ rpl_fflush (FILE *stream)
      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;
 }
index de44802b6f726efc02033f49e9359d6334b70535..e7a7f74952fd1542fa64022e280f9af2cc4d0368 100644 (file)
@@ -66,7 +66,24 @@ rpl_fseeko (FILE *fp, off_t offset, int whence)
 #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);
 }
index 79fa051263d7d8853451a26afd4268b4925b3309..88789f30ac1acbe110a67626c4e45ff79ac64d01 100755 (executable)
@@ -74,6 +74,13 @@ main (int argc, char *argv[])
       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 @@ main (int argc, char *argv[])
       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')
     {