Bruno Jesus : ws2_32: SO_OOBINLINE sockets must always return TRUE to SIOCATMARK request.
Alexandre Julliard
julliard at winehq.org
Tue Sep 13 12:18:10 CDT 2011
Module: wine
Branch: master
Commit: fd7b94bcd2b5d8ee48f329ec3705da9ef3fcf5ce
URL: http://source.winehq.org/git/wine.git/?a=commit;h=fd7b94bcd2b5d8ee48f329ec3705da9ef3fcf5ce
Author: Bruno Jesus <00cpxxx at gmail.com>
Date: Tue Sep 13 08:07:00 2011 -0400
ws2_32: SO_OOBINLINE sockets must always return TRUE to SIOCATMARK request.
---
dlls/ws2_32/socket.c | 21 +++++++++++++++++++--
dlls/ws2_32/tests/sock.c | 23 ++++++++++++++++++++---
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index bfe34ce..b6d17ff 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3099,17 +3099,34 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
break;
case WS_FIONREAD:
+ {
+ if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff))
+ {
+ WSASetLastError(WSAEFAULT);
+ return SOCKET_ERROR;
+ }
+ if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR;
+ if (ioctl(fd, FIONREAD, out_buff ) == -1)
+ status = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
+ release_sock_fd( s, fd );
+ break;
+ }
+
case WS_SIOCATMARK:
{
- int cmd = code == WS_FIONREAD ? FIONREAD : SIOCATMARK;
+ unsigned int oob = 0, oobsize = sizeof(int), atmark = 0;
if (out_size != sizeof(WS_u_long) || IS_INTRESOURCE(out_buff))
{
WSASetLastError(WSAEFAULT);
return SOCKET_ERROR;
}
if ((fd = get_sock_fd( s, 0, NULL )) == -1) return SOCKET_ERROR;
- if (ioctl(fd, cmd, out_buff ) == -1)
+ /* SO_OOBINLINE sockets must always return TRUE to SIOCATMARK */
+ if ((getsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &oob, &oobsize ) == -1)
+ || (!oob && ioctl(fd, SIOCATMARK, &atmark ) == -1))
status = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
+ else
+ (*(WS_u_long *) out_buff) = oob | atmark;
release_sock_fd( s, fd );
break;
}
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 3766186..326b77d 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -2939,7 +2939,7 @@ static void test_ioctlsocket(void)
{
SOCKET sock;
struct tcp_keepalive kalive;
- int ret;
+ int ret, optval;
static const LONG cmds[] = {FIONBIO, FIONREAD, SIOCATMARK};
UINT i;
u_long arg = 0;
@@ -2965,8 +2965,25 @@ static void test_ioctlsocket(void)
* that normal(not urgent) data returns a non-zero value for SIOCATMARK. */
ret = ioctlsocket(sock, SIOCATMARK, &arg);
- if(ret != SOCKET_ERROR)
- todo_wine ok(arg, "expected a non-zero value\n");
+ ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
+ todo_wine ok(arg, "SIOCATMARK expected a non-zero value\n");
+
+ /* when SO_OOBINLINE is set SIOCATMARK must always return TRUE */
+ optval = 1;
+ ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
+ ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
+ arg = 0;
+ ret = ioctlsocket(sock, SIOCATMARK, &arg);
+ ok(ret != SOCKET_ERROR, "ioctlsocket failed unexpectedly\n");
+ ok(arg, "SIOCATMARK expected a non-zero value\n");
+
+ /* disable SO_OOBINLINE and get the same old bahavior */
+ optval = 0;
+ ret = setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (void *)&optval, sizeof(optval));
+ ok(ret != SOCKET_ERROR, "setsockopt failed unexpectedly\n");
+ arg = 0;
+ ret = ioctlsocket(sock, SIOCATMARK, &arg);
+ todo_wine ok(arg, "SIOCATMARK expected a non-zero value\n");
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &arg, 0, NULL, 0, &arg, NULL, NULL);
ok(ret == SOCKET_ERROR, "WSAIoctl succeeded unexpectedly\n");
More information about the wine-cvs
mailing list