bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] fflush: also replace fclose when fixing fflush


From: Eric Blake
Subject: [PATCH] fflush: also replace fclose when fixing fflush
Date: Mon, 2 May 2011 15:16:19 -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 <address@hidden>
---

I'm going ahead and pushing the previous test-fclose file and
this commit, as things now pass on glibc and FreeBSD (tested
both fclose in isolation with --avoid=fflush, to prove that the
test is weaker in that case, as well as the fflush module to
prove that the replacement fclose does indeed work when fflush
is replaced).

 ChangeLog                       |   10 ++++++++++
 doc/posix-functions/fclose.texi |   16 ++++++++++------
 lib/fclose.c                    |   10 ++++++++--
 m4/fflush.m4                    |    3 ++-
 modules/fflush                  |    2 ++
 tests/test-fclose.c             |    5 ++++-
 6 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c9575a1..708fc8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-05-02  Eric Blake  <address@hidden>

+       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.
diff --git a/doc/posix-functions/fclose.texi b/doc/posix-functions/fclose.texi
index fcaecb8..76c2129 100644
--- a/doc/posix-functions/fclose.texi
+++ b/doc/posix-functions/fclose.texi
@@ -4,9 +4,17 @@ fclose

 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}:
address@hidden
address@hidden
+On some platforms, this function fails to set the file position of a
+seekable input stream to byte after the last one actually read:
+glibc 2.13, FreeBSD.
address@hidden 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 @@ fclose
 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 byte after the last one actually read:
-glibc 2.13, FreeBSD.
address@hidden
 On Windows platforms (excluding Cygwin), this function does not set 
@code{errno}
 upon failure.
 @end itemize
diff --git a/lib/fclose.c b/lib/fclose.c
index c8c2fd8..bed561b 100644
--- a/lib/fclose.c
+++ b/lib/fclose.c
@@ -24,13 +24,19 @@

 #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 */
diff --git a/m4/fflush.m4 b/m4/fflush.m4
index f7645de..08b9f17 100644
--- a/m4/fflush.m4
+++ b/m4/fflush.m4
@@ -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
 ])

diff --git a/modules/fflush b/modules/fflush
index a8a151e..2d5839d 100644
--- a/modules/fflush
+++ b/modules/fflush
@@ -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:
diff --git a/tests/test-fclose.c b/tests/test-fclose.c
index a11eca9..d9b9406 100644
--- a/tests/test-fclose.c
+++ b/tests/test-fclose.c
@@ -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.  */
-- 
1.7.4.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]