summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fhandler_socket.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-05-13 16:07:50 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-05-13 16:07:50 +0000
commitd4ff931bf83181966dfd210013b1229e2b1e2c79 (patch)
tree54a5b235c6f15ab43046eb1748ab950fdeb594c3 /winsup/cygwin/fhandler_socket.cc
parent2915feb81e5178700d070324a9888e8fcf70a7d6 (diff)
downloadcygnal-d4ff931bf83181966dfd210013b1229e2b1e2c79.tar.gz
cygnal-d4ff931bf83181966dfd210013b1229e2b1e2c79.tar.bz2
cygnal-d4ff931bf83181966dfd210013b1229e2b1e2c79.zip
* fhandler_socket.cc (fhandler_socket::ioctl): Handle the different
ideas of u_long between Winsock and Cygwin applications on x86_64. Add long comment.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r--winsup/cygwin/fhandler_socket.cc23
1 files changed, 23 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 1fbabd88d..d4602be8a 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -2093,7 +2093,22 @@ 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, unsigned long):
+#endif
res = WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO,
*(int *) p ? ASYNC_MASK : 0);
syscall_printf ("Async I/O on socket %s",
@@ -2104,6 +2119,9 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
WSAEventSelect (get_socket (), wsock_evt, EVENT_MASK);
break;
case FIONREAD:
+#ifdef __x86_64__
+ case _IOR('f', 127, unsigned long):
+#endif
res = ioctlsocket (get_socket (), FIONREAD, (u_long *) p);
if (res == SOCKET_ERROR)
set_winsock_errno ();
@@ -2111,6 +2129,11 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
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",