Fix error handling when closesocket fails.
authorBruno Haible <bruno@clisp.org>
Sat, 11 Oct 2008 11:59:38 +0000 (13:59 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 11 Oct 2008 11:59:38 +0000 (13:59 +0200)
ChangeLog
lib/winsock.c

index 79dc6c7..fdfec9e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-11  Bruno Haible  <bruno@clisp.org>
+
+       * lib/winsock.c (_gl_close_fd_maybe_socket): If closesocket fails,
+       set errno and don't call _close.
+
 2008-10-10  Bruno Haible  <bruno@clisp.org>
 
        * lib/copy-acl.c (qcopy_acl) [CYGWIN]: Call chmod before setting the
index 2ca7813..8a3fb37 100644 (file)
 # 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)