Module: wine Branch: master Commit: 3fea3a5b1a6285787f182276fd806238fe9fc2cc URL: http://source.winehq.org/git/wine.git/?a=commit;h=3fea3a5b1a6285787f182276fd...
Author: Bruno Jesus 00cpxxx@gmail.com Date: Mon Jul 22 22:31:41 2013 -0300
ws2_32: Fix listen() implementation.
---
dlls/ws2_32/socket.c | 35 ++++++++++++++++++++++++----------- dlls/ws2_32/tests/sock.c | 15 +++++---------- 2 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 7ad118f..462f153 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -3695,23 +3695,36 @@ int WINAPI WS_ioctlsocket(SOCKET s, LONG cmd, WS_u_long *argp) */ int WINAPI WS_listen(SOCKET s, int backlog) { - int fd = get_sock_fd( s, FILE_READ_DATA, NULL ); + int fd = get_sock_fd( s, FILE_READ_DATA, NULL ), ret = SOCKET_ERROR;
TRACE("socket %04lx, backlog %d\n", s, backlog); if (fd != -1) { - if (listen(fd, backlog) == 0) - { - release_sock_fd( s, fd ); - _enable_event(SOCKET2HANDLE(s), FD_ACCEPT, - FD_WINE_LISTENING, - FD_CONNECT|FD_WINE_CONNECTED); - return 0; - } - SetLastError(wsaErrno()); + union generic_unix_sockaddr uaddr; + socklen_t uaddrlen = sizeof(uaddr); + + if (getsockname(fd, &uaddr.addr, &uaddrlen) != 0) + { + SetLastError(wsaErrno()); + } + else if (!is_sockaddr_bound(&uaddr.addr, uaddrlen)) + { + SetLastError(WSAEINVAL); + } + else if (listen(fd, backlog) == 0) + { + _enable_event(SOCKET2HANDLE(s), FD_ACCEPT, + FD_WINE_LISTENING, + FD_CONNECT|FD_WINE_CONNECTED); + ret = 0; + } + else + SetLastError(wsaErrno()); release_sock_fd( s, fd ); } - return SOCKET_ERROR; + else + SetLastError(WSAENOTSOCK); + return ret; }
/*********************************************************************** diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index bcf7abc..5a76a7a 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2372,13 +2372,11 @@ static void test_listen(void) SetLastError(0xdeadbeef); ok ((listen(0, 0) == SOCKET_ERROR), "listen did not fail\n"); ret = WSAGetLastError(); -todo_wine ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
SetLastError(0xdeadbeef); ok ((listen(0xdeadbeef, 0) == SOCKET_ERROR), "listen did not fail\n"); ret = WSAGetLastError(); -todo_wine ok (ret == WSAENOTSOCK, "expected 10038, received %d\n", ret);
/* tcp tests */ @@ -2388,7 +2386,6 @@ todo_wine fdB = socket(AF_INET, SOCK_STREAM, 0); ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
-todo_wine { SetLastError(0xdeadbeef); ok ((listen(fdA, -2) == SOCKET_ERROR), "listen did not fail\n"); ret = WSAGetLastError(); @@ -2409,27 +2406,27 @@ todo_wine { SetLastError(0xdeadbeef); ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n"); ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret); -} + ok (!listen(fdA, 0), "listen failed\n"); ok (!listen(fdA, SOMAXCONN), "double listen failed\n"); -todo_wine { + SetLastError(0xdeadbeef); ok ((listen(fdB, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n"); ret = WSAGetLastError(); ok (ret == WSAEINVAL, "expected 10022, received %d\n", ret); -} + ret = closesocket(fdB); ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret);
fdB = socket(AF_INET, SOCK_STREAM, 0); ok ((fdB != INVALID_SOCKET), "socket failed unexpectedly: %d\n", WSAGetLastError() );
-todo_wine { + SetLastError(0xdeadbeef); ok (bind(fdB, (struct sockaddr*) &address, sizeof(address)), "bind should have failed\n"); ret = WSAGetLastError(); ok (ret == WSAEADDRINUSE, "expected 10048, received %d\n", ret); -} + ret = closesocket(fdA); ok (ret == 0, "closesocket failed unexpectedly: %d\n", ret); ret = closesocket(fdB); @@ -2477,9 +2474,7 @@ static void test_select(void) ok ( !FD_ISSET(fdRead, &exceptfds), "FD should not be set\n"); ok ( !FD_ISSET(fdWrite, &exceptfds), "FD should not be set\n");
- todo_wine { ok ((listen(fdWrite, SOMAXCONN) == SOCKET_ERROR), "listen did not fail\n"); - } ret = closesocket(fdWrite); ok ( (ret == 0), "closesocket failed unexpectedly: %d\n", ret);