From d4ff931bf83181966dfd210013b1229e2b1e2c79 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 13 May 2014 16:07:50 +0000 Subject: * fhandler_socket.cc (fhandler_socket::ioctl): Handle the different ideas of u_long between Winsock and Cygwin applications on x86_64. Add long comment. --- winsup/cygwin/fhandler_socket.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'winsup/cygwin/fhandler_socket.cc') 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", -- cgit v1.2.3