Cygwin: fhandler_socket: Add derived ioctl methods
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
233bde3125
commit
79598f94f7
|
@ -670,6 +670,7 @@ class fhandler_socket_inet: public fhandler_socket
|
||||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||||
|
int ioctl (unsigned int cmd, void *);
|
||||||
|
|
||||||
/* from here on: CLONING */
|
/* from here on: CLONING */
|
||||||
fhandler_socket_inet (void *) {}
|
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 sendmsg (const struct msghdr *msg, int flags);
|
||||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||||
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
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 fstat (struct stat *buf);
|
||||||
int __reg2 fstatvfs (struct statvfs *buf);
|
int __reg2 fstatvfs (struct statvfs *buf);
|
||||||
|
|
|
@ -895,57 +895,8 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
/* Sockets are always non-blocking internally. So we just note the
|
res = fhandler_base::ioctl (cmd, p);
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
|
syscall_printf ("%d = ioctl_socket(%x, %p)", res, cmd, p);
|
||||||
|
|
|
@ -1217,3 +1217,71 @@ fhandler_socket_inet::getsockopt (int level, int optname, const void *optval,
|
||||||
|
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1907,3 +1907,60 @@ fhandler_socket_local::getsockopt (int level, int optname, const void *optval,
|
||||||
|
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue