summaryrefslogtreecommitdiff
path: root/lib/fclose.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2011-05-02 15:00:50 -0600
committerEric Blake <eblake@redhat.com>2011-05-02 15:23:49 -0600
commitbcbcf0c59cec0e91db318eccdc564852bafa3c67 (patch)
tree90097b56044ba8fade5482dbae1eb17e8f7af5df /lib/fclose.c
parent1fc3525d1fd7dafbc946dab4c754c593f448c21c (diff)
downloadgnulib-bcbcf0c59cec0e91db318eccdc564852bafa3c67.tar.gz
fflush: also replace fclose when fixing fflush
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>
Diffstat (limited to 'lib/fclose.c')
-rw-r--r--lib/fclose.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/fclose.c b/lib/fclose.c
index c8c2fd8e4c..bed561bdb1 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 */