https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=233bde312546ee60346588803570221389fd89f2

commit 233bde312546ee60346588803570221389fd89f2
Author: Corinna Vinschen <cori...@vinschen.de>
Date:   Thu Feb 22 16:28:14 2018 +0100

    Cygwin: fhandler_socket: Move shutdown and close methods into derived 
classes
    
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler.h               |  8 +++-
 winsup/cygwin/fhandler_socket.cc       | 66 -------------------------
 winsup/cygwin/fhandler_socket_inet.cc  | 88 +++++++++++++++++++++++++++++-----
 winsup/cygwin/fhandler_socket_local.cc | 88 +++++++++++++++++++++++++++++-----
 4 files changed, 160 insertions(+), 90 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 4b1d8dd..51a4a46 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -580,6 +580,8 @@ class fhandler_socket: public fhandler_base
   virtual int connect (const struct sockaddr *name, int namelen) = 0;
   virtual int getsockname (struct sockaddr *name, int *namelen) = 0;
   virtual int getpeername (struct sockaddr *name, int *namelen) = 0;
+  virtual int shutdown (int how) = 0;
+  virtual int close () = 0;
   virtual int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
   virtual int setsockopt (int level, int optname, const void *optval,
                          __socklen_t optlen) = 0;
@@ -607,8 +609,6 @@ class fhandler_socket: public fhandler_base
     set_errno (ESPIPE);
     return -1;
   }
-  int shutdown (int how);
-  int close ();
   void hclose (HANDLE) {close ();}
   int dup (fhandler_base *child, int);
 
@@ -654,6 +654,8 @@ class fhandler_socket_inet: public fhandler_socket
   int connect (const struct sockaddr *name, int namelen);
   int getsockname (struct sockaddr *name, int *namelen);
   int getpeername (struct sockaddr *name, int *namelen);
+  int shutdown (int how);
+  int close ();
   int setsockopt (int level, int optname, const void *optval,
                  __socklen_t optlen);
   int getsockopt (int level, int optname, const void *optval,
@@ -739,6 +741,8 @@ class fhandler_socket_local: public fhandler_socket
   int connect (const struct sockaddr *name, int namelen);
   int getsockname (struct sockaddr *name, int *namelen);
   int getpeername (struct sockaddr *name, int *namelen);
+  int shutdown (int how);
+  int close ();
   int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
   int setsockopt (int level, int optname, const void *optval,
                  __socklen_t optlen);
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index aafc09c..98c4467 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -720,72 +720,6 @@ fhandler_socket::link (const char *newpath)
   return fhandler_base::link (newpath);
 }
 
-int
-fhandler_socket::shutdown (int how)
-{
-  int res = ::shutdown (get_socket (), how);
-
-  /* Linux allows to call shutdown for any socket, even if it's not connected.
-     This also disables to call accept on this socket, if shutdown has been
-     called with the SHUT_RD or SHUT_RDWR parameter.  In contrast, WinSock
-     only allows to call shutdown on a connected socket.  The accept function
-     is in no way affected.  So, what we do here is to fake success, and to
-     change the event settings so that an FD_CLOSE event is triggered for the
-     calling Cygwin function.  The evaluate_events method handles the call
-     from accept specially to generate a Linux-compatible behaviour. */
-  if (res && WSAGetLastError () != WSAENOTCONN)
-    set_winsock_errno ();
-  else
-    {
-      res = 0;
-      switch (how)
-       {
-       case SHUT_RD:
-         saw_shutdown_read (true);
-         wsock_events->events |= FD_CLOSE;
-         SetEvent (wsock_evt);
-         break;
-       case SHUT_WR:
-         saw_shutdown_write (true);
-         break;
-       case SHUT_RDWR:
-         saw_shutdown_read (true);
-         saw_shutdown_write (true);
-         wsock_events->events |= FD_CLOSE;
-         SetEvent (wsock_evt);
-         break;
-       }
-    }
-  return res;
-}
-
-int
-fhandler_socket::close ()
-{
-  int res = 0;
-
-  release_events ();
-  while ((res = ::closesocket (get_socket ())) != 0)
-    {
-      if (WSAGetLastError () != WSAEWOULDBLOCK)
-       {
-         set_winsock_errno ();
-         res = -1;
-         break;
-       }
-      if (cygwait (10) == WAIT_SIGNALED)
-       {
-         set_errno (EINTR);
-         res = -1;
-         break;
-       }
-      WSASetLastError (0);
-    }
-
-  debug_printf ("%d = fhandler_socket::close()", res);
-  return res;
-}
-
 /* Definitions of old ifreq stuff used prior to Cygwin 1.7.0. */
 #define OLD_SIOCGIFFLAGS    _IOW('s', 101, struct __old_ifreq)
 #define OLD_SIOCGIFADDR     _IOW('s', 102, struct __old_ifreq)
diff --git a/winsup/cygwin/fhandler_socket_inet.cc 
b/winsup/cygwin/fhandler_socket_inet.cc
index 0609197..d180841 100644
--- a/winsup/cygwin/fhandler_socket_inet.cc
+++ b/winsup/cygwin/fhandler_socket_inet.cc
@@ -88,6 +88,20 @@ get_inet_addr_inet (const struct sockaddr *in, int inlen,
     }
 }
 
+/* There's no DLL which exports the symbol WSARecvMsg.  One has to call
+   WSAIoctl as below to fetch the function pointer.  Why on earth did the
+   MS developers decide not to export a normal symbol for these extension
+   functions? */
+inline int
+get_ext_funcptr (SOCKET sock, void *funcptr)
+{
+  DWORD bret;
+  const GUID guid = WSAID_WSARECVMSG;
+  return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                  (void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
+                  &bret, NULL, NULL);
+}
+
 static int
 convert_ws1_ip_optname (int optname)
 {
@@ -383,18 +397,70 @@ fhandler_socket_inet::getpeername (struct sockaddr *name, 
int *namelen)
   return res;
 }
 
-/* There's no DLL which exports the symbol WSARecvMsg.  One has to call
-   WSAIoctl as below to fetch the function pointer.  Why on earth did the
-   MS developers decide not to export a normal symbol for these extension
-   functions? */
-inline int
-get_ext_funcptr (SOCKET sock, void *funcptr)
+int
+fhandler_socket_inet::shutdown (int how)
 {
-  DWORD bret;
-  const GUID guid = WSAID_WSARECVMSG;
-  return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
-                  (void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
-                  &bret, NULL, NULL);
+  int res = ::shutdown (get_socket (), how);
+
+  /* Linux allows to call shutdown for any socket, even if it's not connected.
+     This also disables to call accept on this socket, if shutdown has been
+     called with the SHUT_RD or SHUT_RDWR parameter.  In contrast, WinSock
+     only allows to call shutdown on a connected socket.  The accept function
+     is in no way affected.  So, what we do here is to fake success, and to
+     change the event settings so that an FD_CLOSE event is triggered for the
+     calling Cygwin function.  The evaluate_events method handles the call
+     from accept specially to generate a Linux-compatible behaviour. */
+  if (res && WSAGetLastError () != WSAENOTCONN)
+    set_winsock_errno ();
+  else
+    {
+      res = 0;
+      switch (how)
+       {
+       case SHUT_RD:
+         saw_shutdown_read (true);
+         wsock_events->events |= FD_CLOSE;
+         SetEvent (wsock_evt);
+         break;
+       case SHUT_WR:
+         saw_shutdown_write (true);
+         break;
+       case SHUT_RDWR:
+         saw_shutdown_read (true);
+         saw_shutdown_write (true);
+         wsock_events->events |= FD_CLOSE;
+         SetEvent (wsock_evt);
+         break;
+       }
+    }
+  return res;
+}
+
+int
+fhandler_socket_inet::close ()
+{
+  int res = 0;
+
+  release_events ();
+  while ((res = ::closesocket (get_socket ())) != 0)
+    {
+      if (WSAGetLastError () != WSAEWOULDBLOCK)
+       {
+         set_winsock_errno ();
+         res = -1;
+         break;
+       }
+      if (cygwait (10) == WAIT_SIGNALED)
+       {
+         set_errno (EINTR);
+         res = -1;
+         break;
+       }
+      WSASetLastError (0);
+    }
+
+  debug_printf ("%d = fhandler_socket::close()", res);
+  return res;
 }
 
 inline ssize_t
diff --git a/winsup/cygwin/fhandler_socket_local.cc 
b/winsup/cygwin/fhandler_socket_local.cc
index c5e4bfb..4c8f334 100644
--- a/winsup/cygwin/fhandler_socket_local.cc
+++ b/winsup/cygwin/fhandler_socket_local.cc
@@ -206,6 +206,20 @@ get_inet_addr_local (const struct sockaddr *in, int inlen,
   return SOCKET_ERROR;
 }
 
+/* There's no DLL which exports the symbol WSARecvMsg.  One has to call
+   WSAIoctl as below to fetch the function pointer.  Why on earth did the
+   MS developers decide not to export a normal symbol for these extension
+   functions? */
+inline int
+get_ext_funcptr (SOCKET sock, void *funcptr)
+{
+  DWORD bret;
+  const GUID guid = WSAID_WSARECVMSG;
+  return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
+                  (void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
+                  &bret, NULL, NULL);
+}
+
 fhandler_socket_local::fhandler_socket_local () :
   fhandler_socket (),
   sun_path (NULL),
@@ -1030,18 +1044,70 @@ fhandler_socket_local::getpeername (struct sockaddr 
*name, int *namelen)
   return res;
 }
 
-/* There's no DLL which exports the symbol WSARecvMsg.  One has to call
-   WSAIoctl as below to fetch the function pointer.  Why on earth did the
-   MS developers decide not to export a normal symbol for these extension
-   functions? */
-inline int
-get_ext_funcptr (SOCKET sock, void *funcptr)
+int
+fhandler_socket_local::shutdown (int how)
 {
-  DWORD bret;
-  const GUID guid = WSAID_WSARECVMSG;
-  return WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
-                  (void *) &guid, sizeof (GUID), funcptr, sizeof (void *),
-                  &bret, NULL, NULL);
+  int res = ::shutdown (get_socket (), how);
+
+  /* Linux allows to call shutdown for any socket, even if it's not connected.
+     This also disables to call accept on this socket, if shutdown has been
+     called with the SHUT_RD or SHUT_RDWR parameter.  In contrast, WinSock
+     only allows to call shutdown on a connected socket.  The accept function
+     is in no way affected.  So, what we do here is to fake success, and to
+     change the event settings so that an FD_CLOSE event is triggered for the
+     calling Cygwin function.  The evaluate_events method handles the call
+     from accept specially to generate a Linux-compatible behaviour. */
+  if (res && WSAGetLastError () != WSAENOTCONN)
+    set_winsock_errno ();
+  else
+    {
+      res = 0;
+      switch (how)
+       {
+       case SHUT_RD:
+         saw_shutdown_read (true);
+         wsock_events->events |= FD_CLOSE;
+         SetEvent (wsock_evt);
+         break;
+       case SHUT_WR:
+         saw_shutdown_write (true);
+         break;
+       case SHUT_RDWR:
+         saw_shutdown_read (true);
+         saw_shutdown_write (true);
+         wsock_events->events |= FD_CLOSE;
+         SetEvent (wsock_evt);
+         break;
+       }
+    }
+  return res;
+}
+
+int
+fhandler_socket_local::close ()
+{
+  int res = 0;
+
+  release_events ();
+  while ((res = ::closesocket (get_socket ())) != 0)
+    {
+      if (WSAGetLastError () != WSAEWOULDBLOCK)
+       {
+         set_winsock_errno ();
+         res = -1;
+         break;
+       }
+      if (cygwait (10) == WAIT_SIGNALED)
+       {
+         set_errno (EINTR);
+         res = -1;
+         break;
+       }
+      WSASetLastError (0);
+    }
+
+  debug_printf ("%d = fhandler_socket::close()", res);
+  return res;
 }
 
 inline ssize_t

Reply via email to