fflush: also replace fclose when fixing fflush
authorEric Blake <eblake@redhat.com>
Mon, 2 May 2011 21:00:50 +0000 (15:00 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 2 May 2011 21:23:49 +0000 (15:23 -0600)
This fixes the fclose failures detected in the previous patch,
but only when the GPL fflush module is also in use.  That is
because the need for behavior of resetting seekable input streams
is much less common, and the fix more complex.  The LGPLv2+ test
for fclose() in isolation is relaxed to pass if fflush is not
being replaced to cater to input streams.

* modules/fflush (Depends-on): Add fclose.
* m4/fflush.m4 (gl_FUNC_FFLUSH): Also replace fclose.
* lib/fclose.c (rpl_fclose): Don't cause spurious failures on
memstreams with no backing fd.
* doc/posix-functions/fclose.texi (fclose): Document the use of
fflush module to fix the bug.
* tests/test-fclose.c (main): Relax test when fclose is used in
isolation.

Signed-off-by: Eric Blake <eblake@redhat.com>
ChangeLog
doc/posix-functions/fclose.texi
lib/fclose.c
m4/fflush.m4
modules/fflush
tests/test-fclose.c

index c9575a1bada14f438a1eba900ef54e6f86b130e7..708fc8f161b2608af9c1d761c59a658251601ff1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-05-02  Eric Blake  <eblake@redhat.com>
 
+       fflush: also replace fclose when fixing fflush
+       * modules/fflush (Depends-on): Add fclose.
+       * m4/fflush.m4 (gl_FUNC_FFLUSH): Also replace fclose.
+       * lib/fclose.c (rpl_fclose): Don't cause spurious failures on
+       memstreams with no backing fd.
+       * doc/posix-functions/fclose.texi (fclose): Document the use of
+       fflush module to fix the bug.
+       * tests/test-fclose.c (main): Relax test when fclose is used in
+       isolation.
+
        fclose: add some tests
        * modules/fclose-tests: New test module.
        * tests/test-fclose.c: New file.
index ad3aca343e966826dd71046fb23e5c972c98562a..45aac4c7e9881d5c33f43f1228a58f44484541a5 100644 (file)
@@ -4,9 +4,17 @@
 
 POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/fclose.html}
 
-Gnulib module: fclose
+Gnulib module: fclose, fflush
 
-Portability problems fixed by Gnulib:
+Portability problems fixed by Gnulib module @code{fflush}:
+@itemize
+@item
+On some platforms, this function fails to set the file position of a
+seekable input stream to the byte after the last one actually read:
+glibc 2.13, FreeBSD.
+@end itemize
+
+Portability problems fixed by Gnulib module @code{fclose}:
 @itemize
 @item
 On Windows platforms (excluding Cygwin), @code{socket} and @code{accept}
@@ -17,10 +25,6 @@ followed by @code{fdopen} do not return streams that can be closed by
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-On some platforms, this function fails to set the file position of a
-seekable input stream to the byte after the last one actually read:
-glibc 2.13, FreeBSD.
-@item
 On Windows platforms (excluding Cygwin), this function does not set @code{errno}
 upon failure.
 @end itemize
index c8c2fd8e4c9ade15638a3947d0fb8f77ad5b603d..bed561bdb1d57400c9507635681a1e3869d52912 100644 (file)
 
 #include "freading.h"
 
-/* Override fclose() to call the overridden close().  */
+/* Override fclose() to call the overridden fflush() or close().  */
 
 int
 rpl_fclose (FILE *fp)
 #undef fclose
 {
   int saved_errno = 0;
+  int fd;
+
+  /* Don't change behavior on memstreams.  */
+  fd = fileno (fp);
+  if (fd < 0)
+    return fclose (fp);
 
   /* We only need to flush the file if it is not reading or if it is
      seekable.  This only guarantees the file position of input files
@@ -39,7 +45,7 @@ rpl_fclose (FILE *fp)
       && fflush (fp))
     saved_errno = errno;
 
-  if (close (fileno (fp)) < 0 && saved_errno == 0)
+  if (close (fd) < 0 && saved_errno == 0)
     saved_errno = errno;
 
   fclose (fp); /* will fail with errno = EBADF */
index f7645deff6d30d5ced48db5b26cb1920adeb76e7..08b9f17d302002d1930c556a8b16e274fc1ddbf7 100644 (file)
@@ -1,4 +1,4 @@
-# fflush.m4 serial 8
+# fflush.m4 serial 9
 
 # Copyright (C) 2007-2011 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -61,6 +61,7 @@ AC_DEFUN([gl_FUNC_FFLUSH],
     ])
   if test $gl_cv_func_fflush_stdin = no; then
     gl_REPLACE_FFLUSH
+    gl_REPLACE_FCLOSE
   fi
 ])
 
index a8a151e93ae7a6abb3d925b3e2ce35b8afc67329..2d5839db4c58c407037fc0187196abba921db05d 100644 (file)
@@ -7,6 +7,7 @@ lib/stdio-impl.h
 m4/fflush.m4
 
 Depends-on:
+fclose
 fpurge
 ftello
 freading
@@ -20,6 +21,7 @@ AC_REQUIRE([AC_FUNC_FSEEKO])
 
 configure.ac:
 gl_FUNC_FFLUSH
+gl_MODULE_INDICATOR([fflush])
 gl_STDIO_MODULE_INDICATOR([fflush])
 
 Makefile.am:
index a11eca96e39d29ddf7785d3921a06143786b69ef..d9b940619ba8035c0fa591007cfd6666f2821bd4 100644 (file)
@@ -62,7 +62,9 @@ main (int argc, char **argv)
   ASSERT (errno == EBADF);
   ASSERT (lseek (fd, 0, SEEK_CUR) == 2);
 
-  /* Likewise for an input stream.  */
+#if GNULIB_FFLUSH
+  /* Likewise for an input stream, but only when we know fflush works
+     on input streams.  */
   fd2 = dup (fd);
   ASSERT (0 <= fd2);
   f = fdopen (fd2, "r");
@@ -73,6 +75,7 @@ main (int argc, char **argv)
   ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
   ASSERT (errno == EBADF);
   ASSERT (lseek (fd, 0, SEEK_CUR) == 3);
+#endif
 
   /* Test that fclose() sets errno if someone else closes the stream
      fd behind the back of stdio.  */