From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 84 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index bcccaef9bc6..32c2172f0db 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4761,6 +4761,89 @@ done: closesocket(server_socket); }
+/* Test what socket state is inherited from the listening socket by accept(). */ +static void test_accept_inheritance(void) +{ + struct sockaddr_in addr, destaddr; + SOCKET listener, server, client; + struct linger linger; + int ret, len, value; + unsigned int i; + + static const struct + { + int optname; + int optval; + int value; + } + int_tests[] = + { + {SOL_SOCKET, SO_REUSEADDR, 1}, + {SOL_SOCKET, SO_KEEPALIVE, 1}, + {SOL_SOCKET, SO_OOBINLINE, 1}, + {SOL_SOCKET, SO_SNDBUF, 0x123}, + {SOL_SOCKET, SO_RCVBUF, 0x123}, + {SOL_SOCKET, SO_SNDTIMEO, 0x123}, + {SOL_SOCKET, SO_RCVTIMEO, 0x123}, + {IPPROTO_TCP, TCP_NODELAY, 1}, + }; + + listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(listener != -1, "failed to create socket, error %u\n", WSAGetLastError()); + + for (i = 0; i < ARRAY_SIZE(int_tests); ++i) + { + ret = setsockopt(listener, int_tests[i].optname, int_tests[i].optval, + (char *)&int_tests[i].value, sizeof(int_tests[i].value)); + ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); + } + + linger.l_onoff = 1; + linger.l_linger = 555; + ret = setsockopt(listener, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger)); + ok(!ret, "got error %u\n", WSAGetLastError()); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + ret = bind(listener, (struct sockaddr *)&addr, sizeof(addr)); + ok(!ret, "failed to bind, error %u\n", WSAGetLastError()); + len = sizeof(destaddr); + ret = getsockname(listener, (struct sockaddr *)&destaddr, &len); + ok(!ret, "failed to get address, error %u\n", WSAGetLastError()); + + ret = listen(listener, 1); + ok(!ret, "failed to listen, error %u\n", WSAGetLastError()); + + client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + ok(client != -1, "failed to create socket, error %u\n", WSAGetLastError()); + ret = connect(client, (struct sockaddr *)&destaddr, sizeof(destaddr)); + ok(!ret, "failed to connect, error %u\n", WSAGetLastError()); + server = accept(listener, NULL, NULL); + ok(server != -1, "failed to accept, error %u\n", WSAGetLastError()); + + for (i = 0; i < ARRAY_SIZE(int_tests); ++i) + { + value = 0; + len = sizeof(value); + ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); + ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); + todo_wine_if (i == 0 || (i >= 3 && i <= 6)) + ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); + } + + len = sizeof(linger); + memset(&linger, 0, sizeof(linger)); + ret = getsockopt(server, SOL_SOCKET, SO_LINGER, (char *)&linger, &len); + ok(!ret, "got error %u\n", WSAGetLastError()); + ok(linger.l_onoff == 1, "got on/off %u\n", linger.l_onoff); + ok(linger.l_linger == 555, "got linger %u\n", linger.l_onoff); + + close(server); + close(client); + close(listener); +} + static void test_extendedSocketOptions(void) { WSADATA wsa; @@ -13607,6 +13690,7 @@ START_TEST( sock ) test_listen(); test_select(); test_accept(); + test_accept_inheritance(); test_getpeername(); test_getsockname();
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 2 +- server/sock.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 32c2172f0db..d8500144bd0 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4828,7 +4828,7 @@ static void test_accept_inheritance(void) len = sizeof(value); ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); - todo_wine_if (i == 0 || (i >= 3 && i <= 6)) + todo_wine_if (i >= 3 && i <= 6) ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); }
diff --git a/server/sock.c b/server/sock.c index c130821b7f4..8fe6086b8f6 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1988,16 +1988,19 @@ static struct sock *accept_socket( struct sock *sock ) }
/* newly created socket gets the same properties of the listening socket */ - acceptsock->state = SOCK_CONNECTED; - acceptsock->bound = 1; - acceptsock->nonblocking = sock->nonblocking; - acceptsock->mask = sock->mask; - acceptsock->proto = sock->proto; - acceptsock->type = sock->type; - acceptsock->family = sock->family; - acceptsock->window = sock->window; - acceptsock->message = sock->message; - acceptsock->connect_time = current_time; + acceptsock->state = SOCK_CONNECTED; + acceptsock->bound = 1; + acceptsock->nonblocking = sock->nonblocking; + acceptsock->mask = sock->mask; + acceptsock->proto = sock->proto; + acceptsock->type = sock->type; + acceptsock->family = sock->family; + acceptsock->window = sock->window; + acceptsock->message = sock->message; + acceptsock->reuseaddr = sock->reuseaddr; + acceptsock->exclusiveaddruse = sock->exclusiveaddruse; + acceptsock->connect_time = current_time; + if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event ); if (!(acceptsock->fd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj, get_fd_options( sock->fd ) )))
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 2 +- server/sock.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index d8500144bd0..974cf087778 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4828,7 +4828,7 @@ static void test_accept_inheritance(void) len = sizeof(value); ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); - todo_wine_if (i >= 3 && i <= 6) + todo_wine_if (i >= 4 && i <= 6) ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); }
diff --git a/server/sock.c b/server/sock.c index 8fe6086b8f6..e84b3c68017 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1999,6 +1999,7 @@ static struct sock *accept_socket( struct sock *sock ) acceptsock->message = sock->message; acceptsock->reuseaddr = sock->reuseaddr; acceptsock->exclusiveaddruse = sock->exclusiveaddruse; + acceptsock->sndbuf = sock->sndbuf; acceptsock->connect_time = current_time;
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
From: Zebediah Figura zfigura@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53911 --- dlls/ws2_32/tests/sock.c | 2 +- server/sock.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index 974cf087778..f32776de17f 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4828,7 +4828,7 @@ static void test_accept_inheritance(void) len = sizeof(value); ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); - todo_wine_if (i >= 4 && i <= 6) + todo_wine_if (i >= 5 && i <= 6) ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); }
diff --git a/server/sock.c b/server/sock.c index e84b3c68017..4a16180a960 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2000,6 +2000,7 @@ static struct sock *accept_socket( struct sock *sock ) acceptsock->reuseaddr = sock->reuseaddr; acceptsock->exclusiveaddruse = sock->exclusiveaddruse; acceptsock->sndbuf = sock->sndbuf; + acceptsock->rcvbuf = sock->rcvbuf; acceptsock->connect_time = current_time;
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 2 +- server/sock.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index f32776de17f..cb99ceb4b24 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4828,7 +4828,7 @@ static void test_accept_inheritance(void) len = sizeof(value); ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); - todo_wine_if (i >= 5 && i <= 6) + todo_wine_if (i == 6) ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); }
diff --git a/server/sock.c b/server/sock.c index 4a16180a960..a64ea8f7e56 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2001,6 +2001,7 @@ static struct sock *accept_socket( struct sock *sock ) acceptsock->exclusiveaddruse = sock->exclusiveaddruse; acceptsock->sndbuf = sock->sndbuf; acceptsock->rcvbuf = sock->rcvbuf; + acceptsock->sndtimeo = sock->sndtimeo; acceptsock->connect_time = current_time;
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/ws2_32/tests/sock.c | 3 +-- server/sock.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index cb99ceb4b24..6f2bcb73a06 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -4828,8 +4828,7 @@ static void test_accept_inheritance(void) len = sizeof(value); ret = getsockopt(server, int_tests[i].optname, int_tests[i].optval, (char *)&value, &len); ok(!ret, "test %u: got error %u\n", i, WSAGetLastError()); - todo_wine_if (i == 6) - ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); + ok(value == int_tests[i].value, "test %u: got value %#x\n", i, value); }
len = sizeof(linger); diff --git a/server/sock.c b/server/sock.c index a64ea8f7e56..a64cb22404e 100644 --- a/server/sock.c +++ b/server/sock.c @@ -2002,6 +2002,7 @@ static struct sock *accept_socket( struct sock *sock ) acceptsock->sndbuf = sock->sndbuf; acceptsock->rcvbuf = sock->rcvbuf; acceptsock->sndtimeo = sock->sndtimeo; + acceptsock->rcvtimeo = sock->rcvtimeo; acceptsock->connect_time = current_time;
if (sock->event) acceptsock->event = (struct event *)grab_object( sock->event );