+2011-05-11 Bruno Haible <bruno@clisp.org>
+
+ fclose: Fix possible link error.
+ * lib/fclose.c (rpl_fclose): Invoke _gl_unregister_fd, not
+ unregister_shadow_fd. Improve comments.
+ * lib/sockets.c (close_fd_maybe_socket): Add comments. Reported by
+ Eric Blake.
+
2011-05-11 Jim Meyering <meyering@redhat.com>
maint.mk: improve "can not" detection and generalize rule name
&& fflush (fp))
saved_errno = errno;
+ /* fclose() calls close(), but we need to also invoke all hooks that our
+ overridden close() function invokes. See lib/close.c. */
#if WINDOWS_SOCKETS
- /* There is a minor race where some other thread could open fd
- between our close and fopen, but it is no worse than the race in
- close_fd_maybe_socket. */
+ /* 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;
}
#else /* !WINDOWS_SOCKETS */
- /* No race here. */
- result = fclose (fp);
+ /* Call fclose() and invoke all hooks of the overridden close(). */
# if REPLACE_FCHDIR
- if (result == 0)
- unregister_shadow_fd (fd);
+ /* 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 */
return result;
gl_close_fn primary,
int fd)
{
+ /* Note about multithread-safety: There is a race condition where, between
+ our calls to closesocket() and the primary close(), some other thread
+ could make system calls that allocate precisely the same HANDLE value
+ as sock; then the primary close() would call CloseHandle() on it. */
SOCKET sock;
WSANETWORKEVENTS ev;