From f8b25818e0b2f409eec22057c722ebe52d31e4e0 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 11 Oct 2008 13:59:38 +0200 Subject: [PATCH] Fix error handling when closesocket fails. --- ChangeLog | 5 +++++ lib/winsock.c | 68 ++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79dc6c735..fdfec9eea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-10-11 Bruno Haible + + * lib/winsock.c (_gl_close_fd_maybe_socket): If closesocket fails, + set errno and don't call _close. + 2008-10-10 Bruno Haible * lib/copy-acl.c (qcopy_acl) [CYGWIN]: Call chmod before setting the diff --git a/lib/winsock.c b/lib/winsock.c index 2ca781363..8a3fb3785 100644 --- a/lib/winsock.c +++ b/lib/winsock.c @@ -47,35 +47,6 @@ # define SOCKET_TO_FD(fh) (_open_osfhandle ((long) (fh), O_RDWR | O_BINARY)) -/* Hook for gnulib module close. */ - -#if HAVE__GL_CLOSE_FD_MAYBE_SOCKET -int -_gl_close_fd_maybe_socket (int fd) -{ - SOCKET sock = FD_TO_SOCKET (fd); - WSANETWORKEVENTS ev; - - ev.lNetworkEvents = 0xDEADBEEF; - WSAEnumNetworkEvents (sock, NULL, &ev); - if (ev.lNetworkEvents != 0xDEADBEEF) - { - /* FIXME: other applications, like squid, use an undocumented - _free_osfhnd free function. Instead, here we just close twice - the file descriptor. I could not get the former to work - (pb, Sep 22 2008). */ - int r = closesocket (sock); - _close (fd); - return r; - } - else - return _close (fd); -} -#endif - - -/* Wrappers for WinSock functions. */ - static inline void set_winsock_errno (void) { @@ -109,6 +80,45 @@ set_winsock_errno (void) } } + +/* Hook for gnulib module close. */ + +#if HAVE__GL_CLOSE_FD_MAYBE_SOCKET +int +_gl_close_fd_maybe_socket (int fd) +{ + SOCKET sock = FD_TO_SOCKET (fd); + WSANETWORKEVENTS ev; + + ev.lNetworkEvents = 0xDEADBEEF; + WSAEnumNetworkEvents (sock, NULL, &ev); + if (ev.lNetworkEvents != 0xDEADBEEF) + { + /* FIXME: other applications, like squid, use an undocumented + _free_osfhnd free function. But this is not enough: The 'osfile' + flags for fd also needs to be cleared, but it is hard to access it. + Instead, here we just close twice the file descriptor. */ + if (closesocket (sock)) + { + set_winsock_errno (); + return -1; + } + else + { + /* This call frees the file descriptor and does a + CloseHandle ((HANDLE) _get_osfhandle (fd)), which fails. */ + _close (fd); + return 0; + } + } + else + return _close (fd); +} +#endif + + +/* Wrappers for WinSock functions. */ + #if GNULIB_SOCKET int rpl_socket (int domain, int type, int protocol) -- 2.11.0