This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Cygwin: fhandler_socket: Move shutdown and close methods into derived classes


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

commit 233bde312546ee60346588803570221389fd89f2
Author: Corinna Vinschen <corinna@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 <corinna@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]