From d4ff931bf83181966dfd210013b1229e2b1e2c79 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 13 May 2014 16:07:50 +0000 Subject: [PATCH] * 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/ChangeLog | 6 ++++++ winsup/cygwin/fhandler_socket.cc | 23 +++++++++++++++++++++++ winsup/cygwin/uinfo.cc | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6fa59152a..e69d359b8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2014-05-13 Corinna Vinschen + + * fhandler_socket.cc (fhandler_socket::ioctl): Handle the different + ideas of u_long between Winsock and Cygwin applications on x86_64. + Add long comment. + 2014-05-09 Christopher Faylor * signal.cc (sigprocmask): Fix strace output to include "how". 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", diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index a3e06d29b..a69f02d38 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -1825,7 +1825,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) posix_name, sid.string (sidstr), uid); /* For non-users, create a passwd entry which doesn't allow interactive logon. Unless it's the SYSTEM account. This conveniently allows to - long interactively as SYSTEM for debugging purposes. */ + logon interactively as SYSTEM for debugging purposes. */ else if (acc_type != SidTypeUser && sid != well_known_system_sid) __small_swprintf (linebuf, L"%W:*:%u:%u:,%W:/:/sbin/nologin", posix_name, uid, gid, sid.string (sidstr));