ws2_32: SO_OOBINLINE sockets must always return TRUE to SIOCATMARK request.

This commit is contained in:
Bruno Jesus 2011-09-13 08:07:00 -04:00 committed by Alexandre Julliard
parent 143a488508
commit fd7b94bcd2
2 changed files with 40 additions and 6 deletions

View File

@ -3099,21 +3099,38 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
break;
case WS_FIONREAD:
case WS_SIOCATMARK:
{
int cmd = code == WS_FIONREAD ? FIONREAD : SIOCATMARK;
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)
if (ioctl(fd, FIONREAD, out_buff ) == -1)
status = (errno == EBADF) ? WSAENOTSOCK : wsaErrno();
release_sock_fd( s, fd );
break;
}
case WS_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;
/* 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;
}
case WS_FIOASYNC:
WARN("Warning: WS1.1 shouldn't be using async I/O\n");
SetLastError(WSAEINVAL);

View File

@ -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");