# HG changeset patch # User Bruno Haible # Date 1223726378 -7200 # Node ID ddf94077f7f282efb760f78cf531fa472021f757 # Parent 43de0aaeccb6eefc0512209a9fd06725e5d60234 Fix error handling when closesocket fails. diff --git a/ChangeLog b/ChangeLog --- 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 --- 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 @@ } } + +/* 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)