bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

rpl_close of socket: set errno


From: Bruno Haible
Subject: rpl_close of socket: set errno
Date: Sat, 11 Oct 2008 13:59:24 +0200
User-agent: KMail/1.5.4

When closing of a socket fails, winsock.c currently does not set errno and
closes the handle despite returning -1. This fixes it.

Also, I'm adding a comment about why _free_osfhnd is not enough. For every
fd, the MSVCRT has two bits of information: the HANDLE called 'osfhnd', and
a field of flags, called 'osfile'. If you wanted to implement _close(fd)
yourself, you would have to not only call _free_osfhnd but also to clear
the 'osfile' field.

2008-10-11  Bruno Haible  <address@hidden>

        * lib/winsock.c (_gl_close_fd_maybe_socket): If closesocket fails,
        set errno and don't call _close.

*** lib/winsock.c.orig  2008-10-11 13:54:55.000000000 +0200
--- lib/winsock.c       2008-10-11 13:54:09.000000000 +0200
***************
*** 47,81 ****
  # 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)
  {
--- 47,52 ----
***************
*** 109,114 ****
--- 80,124 ----
      }
  }
  
+ 
+ /* 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)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]