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: Add derived ioctl methods


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

commit 79598f94f75d9423a382ec108291619ff45f2912
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Feb 22 16:30:08 2018 +0100

    Cygwin: fhandler_socket: Add derived ioctl methods
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler.h               |  2 +
 winsup/cygwin/fhandler_socket.cc       | 51 +------------------------
 winsup/cygwin/fhandler_socket_inet.cc  | 68 ++++++++++++++++++++++++++++++++++
 winsup/cygwin/fhandler_socket_local.cc | 57 ++++++++++++++++++++++++++++
 4 files changed, 128 insertions(+), 50 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 51a4a46..18de57c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -670,6 +670,7 @@ class fhandler_socket_inet: public fhandler_socket
   ssize_t sendmsg (const struct msghdr *msg, int flags);
   ssize_t __stdcall write (const void *ptr, size_t len);
   ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
+  int ioctl (unsigned int cmd, void *);
 
   /* from here on: CLONING */
   fhandler_socket_inet (void *) {}
@@ -758,6 +759,7 @@ class fhandler_socket_local: public fhandler_socket
   ssize_t sendmsg (const struct msghdr *msg, int flags);
   ssize_t __stdcall write (const void *ptr, size_t len);
   ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
+  int ioctl (unsigned int cmd, void *);
 
   int __reg2 fstat (struct stat *buf);
   int __reg2 fstatvfs (struct statvfs *buf);
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 98c4467..dfcb8d4 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -895,57 +895,8 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
 	  }
 	break;
       }
-    /* From this point on we handle only ioctl commands which are understood by
-       Winsock.  However, we have a problem, which is, the different size of
-       u_long in Windows and 64 bit Cygwin.  This affects the definitions of
-       FIOASYNC, etc, because they are defined in terms of sizeof(u_long).
-       So we have to use case labels which are independent of the sizeof
-       u_long.  Since we're redefining u_long at the start of this file to
-       matching Winsock's idea of u_long, we can use the real definitions in
-       calls to Windows.  In theory we also have to make sure to convert the
-       different ideas of u_long between the application and Winsock, but
-       fortunately, the parameters defined as u_long pointers are on Linux
-       and BSD systems defined as int pointer, so the applications will
-       use a type of the expected size.  Hopefully. */
-    case FIOASYNC:
-#ifdef __x86_64__
-    case _IOW('f', 125, u_long):
-#endif
-      res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
-	      *(int *) p ? ASYNC_MASK : 0);
-      syscall_printf ("Async I/O on socket %s",
-	      *(int *) p ? "started" : "cancelled");
-      async_io (*(int *) p != 0);
-      /* If async_io is switched off, revert the event handling. */
-      if (*(int *) p == 0)
-	WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
-      break;
-    case FIONREAD:
-#ifdef __x86_64__
-    case _IOR('f', 127, u_long):
-#endif
-      /* Make sure to use the Winsock definition of FIONREAD. */
-      res = ::ioctlsocket (get_socket (), _IOR('f', 127, u_long), (u_long *) p);
-      if (res == SOCKET_ERROR)
-	set_winsock_errno ();
-      break;
     default:
-      /* Sockets are always non-blocking internally.  So we just note the
-	 state here. */
-#ifdef __x86_64__
-      /* Convert the different idea of u_long in the definition of cmd. */
-      if (((cmd >> 16) & IOCPARM_MASK) == sizeof (unsigned long))
-      	cmd = (cmd & ~(IOCPARM_MASK << 16)) | (sizeof (u_long) << 16);
-#endif
-      if (cmd == FIONBIO)
-	{
-	  syscall_printf ("socket is now %sblocking",
-			    *(int *) p ? "non" : "");
-	  set_nonblocking (*(int *) p);
-	  res = 0;
-	}
-      else
-	res = ::ioctlsocket (get_socket (), cmd, (u_long *) p);
+      res = fhandler_base::ioctl (cmd, p);
       break;
     }
   syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc
index d180841..d5fe393 100644
--- a/winsup/cygwin/fhandler_socket_inet.cc
+++ b/winsup/cygwin/fhandler_socket_inet.cc
@@ -1217,3 +1217,71 @@ fhandler_socket_inet::getsockopt (int level, int optname, const void *optval,
 
   return ret;
 }
+
+int
+fhandler_socket_inet::ioctl (unsigned int cmd, void *p)
+{
+  int res;
+
+  switch (cmd)
+    {
+    /* Here we handle only ioctl commands which are understood by Winsock.
+       However, we have a problem, which is, the different size of u_long
+       in Windows and 64 bit Cygwin.  This affects the definitions of
+       FIOASYNC, etc, because they are defined in terms of sizeof(u_long).
+       So we have to use case labels which are independent of the sizeof
+       u_long.  Since we're redefining u_long at the start of this file to
+       matching Winsock's idea of u_long, we can use the real definitions in
+       calls to Windows.  In theory we also have to make sure to convert the
+       different ideas of u_long between the application and Winsock, but
+       fortunately, the parameters defined as u_long pointers are on Linux
+       and BSD systems defined as int pointer, so the applications will
+       use a type of the expected size.  Hopefully. */
+    case FIOASYNC:
+#ifdef __x86_64__
+    case _IOW('f', 125, u_long):
+#endif
+      res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
+	      *(int *) p ? ASYNC_MASK : 0);
+      syscall_printf ("Async I/O on socket %s",
+	      *(int *) p ? "started" : "cancelled");
+      async_io (*(int *) p != 0);
+      /* If async_io is switched off, revert the event handling. */
+      if (*(int *) p == 0)
+	WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
+      break;
+    case FIONREAD:
+#ifdef __x86_64__
+    case _IOR('f', 127, u_long):
+#endif
+      /* Make sure to use the Winsock definition of FIONREAD. */
+      res = ::ioctlsocket (get_socket (), _IOR('f', 127, u_long), (u_long *) p);
+      if (res == SOCKET_ERROR)
+	set_winsock_errno ();
+      break;
+    case FIONBIO:
+    case SIOCATMARK:
+      /* Sockets are always non-blocking internally.  So we just note the
+	 state here. */
+#ifdef __x86_64__
+      /* Convert the different idea of u_long in the definition of cmd. */
+      if (((cmd >> 16) & IOCPARM_MASK) == sizeof (unsigned long))
+	cmd = (cmd & ~(IOCPARM_MASK << 16)) | (sizeof (u_long) << 16);
+#endif
+      if (cmd == FIONBIO)
+	{
+	  syscall_printf ("socket is now %sblocking",
+			    *(int *) p ? "non" : "");
+	  set_nonblocking (*(int *) p);
+	  res = 0;
+	}
+      else
+	res = ::ioctlsocket (get_socket (), cmd, (u_long *) p);
+      break;
+    default:
+      res = fhandler_socket::ioctl (cmd, p);
+      break;
+    }
+  syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
+  return res;
+}
diff --git a/winsup/cygwin/fhandler_socket_local.cc b/winsup/cygwin/fhandler_socket_local.cc
index 4c8f334..bf34377 100644
--- a/winsup/cygwin/fhandler_socket_local.cc
+++ b/winsup/cygwin/fhandler_socket_local.cc
@@ -1907,3 +1907,60 @@ fhandler_socket_local::getsockopt (int level, int optname, const void *optval,
 
   return ret;
 }
+
+int
+fhandler_socket_local::ioctl (unsigned int cmd, void *p)
+{
+  int res;
+
+  switch (cmd)
+    {
+    /* FIXME: These have to be handled differently in future. */
+    case FIOASYNC:
+#ifdef __x86_64__
+    case _IOW('f', 125, u_long):
+#endif
+      res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
+	      *(int *) p ? ASYNC_MASK : 0);
+      syscall_printf ("Async I/O on socket %s",
+	      *(int *) p ? "started" : "cancelled");
+      async_io (*(int *) p != 0);
+      /* If async_io is switched off, revert the event handling. */
+      if (*(int *) p == 0)
+	WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
+      break;
+    case FIONREAD:
+#ifdef __x86_64__
+    case _IOR('f', 127, u_long):
+#endif
+      /* Make sure to use the Winsock definition of FIONREAD. */
+      res = ::ioctlsocket (get_socket (), _IOR('f', 127, u_long), (u_long *) p);
+      if (res == SOCKET_ERROR)
+	set_winsock_errno ();
+      break;
+    case FIONBIO:
+    case SIOCATMARK:
+      /* Sockets are always non-blocking internally.  So we just note the
+	 state here. */
+#ifdef __x86_64__
+      /* Convert the different idea of u_long in the definition of cmd. */
+      if (((cmd >> 16) & IOCPARM_MASK) == sizeof (unsigned long))
+	cmd = (cmd & ~(IOCPARM_MASK << 16)) | (sizeof (u_long) << 16);
+#endif
+      if (cmd == FIONBIO)
+	{
+	  syscall_printf ("socket is now %sblocking",
+			    *(int *) p ? "non" : "");
+	  set_nonblocking (*(int *) p);
+	  res = 0;
+	}
+      else
+	res = ::ioctlsocket (get_socket (), cmd, (u_long *) p);
+      break;
+    default:
+      res = fhandler_socket::ioctl (cmd, p);
+      break;
+    }
+  syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
+  return res;
+}


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