changeset 10621:ddf94077f7f2

Fix error handling when closesocket fails.
author Bruno Haible <bruno@clisp.org>
date Sat, 11 Oct 2008 13:59:38 +0200
parents 43de0aaeccb6
children ac6f431cc95d
files ChangeLog lib/winsock.c
diffstat 2 files changed, 44 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)