summaryrefslogtreecommitdiff
path: root/lib/fclose.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2011-06-16 18:22:50 +0200
committerAndy Wingo <wingo@pobox.com>2011-06-16 19:47:25 +0200
commit3d458a81c64e4696157b23c7c4c4c150aa4a93b8 (patch)
tree1478fb3a9faaf203f517a8776f54d00884efdef6 /lib/fclose.c
parent0b77014f0c7d53b8bdbc7059c92f526560e1cacd (diff)
downloadguile-3d458a81c64e4696157b23c7c4c4c150aa4a93b8.tar.gz
gnulib update
Added pipe2 and open modules, to get O_CLOEXEC. * libguile/Makefile.am (guile_filter_doc_snarfage$(EXEEXT)): Add gnulib here, in the native build case, for rpl_fflush if needed. foo
Diffstat (limited to 'lib/fclose.c')
-rw-r--r--lib/fclose.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/lib/fclose.c b/lib/fclose.c
index 805449a20..a4a519f7c 100644
--- a/lib/fclose.c
+++ b/lib/fclose.c
@@ -22,26 +22,63 @@
#include <errno.h>
#include <unistd.h>
-/* Override fclose() to call the overridden close(). */
+#include "freading.h"
+
+/* Override fclose() to call the overridden fflush() or close(). */
int
rpl_fclose (FILE *fp)
#undef fclose
{
int saved_errno = 0;
+ int fd;
+ int result = 0;
+
+ /* Don't change behavior on memstreams. */
+ fd = fileno (fp);
+ if (fd < 0)
+ return fclose (fp);
- if (fflush (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
+ if the fflush module is also in use. */
+ if ((!freading (fp) || lseek (fileno (fp), 0, SEEK_CUR) != -1)
+ && fflush (fp))
saved_errno = errno;
- if (close (fileno (fp)) < 0 && saved_errno == 0)
+ /* fclose() calls close(), but we need to also invoke all hooks that our
+ overridden close() function invokes. See lib/close.c. */
+#if WINDOWS_SOCKETS
+ /* Call the overridden close(), then the original fclose().
+ Note about multithread-safety: There is a race condition where some
+ other thread could open fd between our close and fclose. */
+ if (close (fd) < 0 && saved_errno == 0)
saved_errno = errno;
- fclose (fp); /* will fail with errno = EBADF */
+ fclose (fp); /* will fail with errno = EBADF, if we did not lose a race */
+
+#else /* !WINDOWS_SOCKETS */
+ /* Call fclose() and invoke all hooks of the overridden close(). */
+
+# if REPLACE_FCHDIR
+ /* Note about multithread-safety: There is a race condition here as well.
+ Some other thread could open fd between our calls to fclose and
+ _gl_unregister_fd. */
+ result = fclose (fp);
+ if (result == 0)
+ _gl_unregister_fd (fd);
+# else
+ /* No race condition here. */
+ result = fclose (fp);
+# endif
+
+#endif /* !WINDOWS_SOCKETS */
if (saved_errno != 0)
{
errno = saved_errno;
- return EOF;
+ result = EOF;
}
- return 0;
+
+ return result;
}