From 69a557732a63d666a4578a329860b2bd6c966adc Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 11 May 2011 13:14:46 +0200 Subject: [PATCH] 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. --- ChangeLog | 8 ++++++++ lib/fclose.c | 23 ++++++++++++++++------- lib/sockets.c | 4 ++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbe24caef..c7dec5eef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2011-05-11 Bruno Haible + + 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 maint.mk: improve "can not" detection and generalize rule name diff --git a/lib/fclose.c b/lib/fclose.c index 018724b40..a8d68b4d8 100644 --- a/lib/fclose.c +++ b/lib/fclose.c @@ -46,10 +46,12 @@ rpl_fclose (FILE *fp) && 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; @@ -62,13 +64,20 @@ rpl_fclose (FILE *fp) } #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; diff --git a/lib/sockets.c b/lib/sockets.c index 42b8f9ea5..53cb66e46 100644 --- a/lib/sockets.c +++ b/lib/sockets.c @@ -37,6 +37,10 @@ close_fd_maybe_socket (const struct fd_hook *remaining_list, 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; -- 2.11.0