Module: wine Branch: master Commit: fd7b94bcd2b5d8ee48f329ec3705da9ef3fcf5ce URL: http://source.winehq.org/git/wine.git/?a=commit;h=fd7b94bcd2b5d8ee48f329ec37...
Author: Bruno Jesus 00cpxxx@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");