]> sourceware.org Git - newlib-cygwin.git/commitdiff
Cygwin: fhandler_socket: Move shutdown and close methods into derived classes
authorCorinna Vinschen <corinna@vinschen.de>
Thu, 22 Feb 2018 15:28:14 +0000 (16:28 +0100)
committerCorinna Vinschen <corinna@vinschen.de>
Thu, 22 Feb 2018 15:28:14 +0000 (16:28 +0100)
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_socket_inet.cc
winsup/cygwin/fhandler_socket_local.cc

index 4b1d8ddafb8b7bc8d508c08c8928dd56edd11dad..51a4a46dac6aba02e361edb78bc0fd498e9eed9f 100644 (file)
@@ -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);
index aafc09c438fcafd0a5d928001cbefd7f6710a363..98c4467faaba47bd578f6727b05bc892af2c38f5 100644 (file)
@@ -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)
index 06091973f0af83155e5bc87a2b944f6c3cb5a584..d1808414ac27d1f320bbc9427ab9d3ebdc475cf8 100644 (file)
@@ -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
index c5e4bfb675d5dda470085b1972cc19f0feae8c54..4c8f3340b5e09d86378473f192aeae194400d30b 100644 (file)
@@ -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
This page took 0.045367 seconds and 5 git commands to generate.