From: Ivan Savinov <isavinov@gmail.com> Native WSASend() imposes no practical limit on the number of WSABUF elements for a stream socket, unlike Wine, which forwards the whole array to a single sendmsg() call. This currently fails once the array exceeds IOV_MAX (1024 elements on Linux). Signed-off-by: Ivan Savinov <isavinov@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> --- dlls/ws2_32/tests/sock.c | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index e67e50907b0..22f45e3bd4d 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -14616,6 +14616,55 @@ static void test_send_buffering(void) closesocket(client); } +static void test_send_many_buffers(void) +{ + char *send_data, *recv_data; + unsigned int i, count, recv_size; + SOCKET client, server; + WSABUF *bufs; + DWORD sent; + int ret; + + /* Native WSASend() imposes no practical limit on the number of WSABUF + * elements for a stream socket. Wine used to forward the whole array to + * a single sendmsg() call, which Linux rejects with EMSGSIZE once + * msg_iovlen exceeds IOV_MAX (1024 on Linux). */ + count = 2000; + send_data = malloc(count); + bufs = malloc(count * sizeof(*bufs)); + for (i = 0; i < count; ++i) + { + send_data[i] = i; + bufs[i].buf = &send_data[i]; + bufs[i].len = 1; + } + + tcp_socketpair(&client, &server); + + sent = 0xdeadbeef; + ret = WSASend(client, bufs, count, &sent, 0, NULL, NULL); + todo_wine + ok(!ret, "got %d, error %u.\n", ret, WSAGetLastError()); + if (!ret) + { + ok(sent == count, "got %lu.\n", sent); + + recv_data = calloc(1, count); + recv_size = 0; + while (recv_size < count + && (ret = recv(server, recv_data + recv_size, count - recv_size, 0)) > 0) + recv_size += ret; + ok(recv_size == count, "got %u, expected %u.\n", recv_size, count); + ok(!memcmp(recv_data, send_data, count), "data mismatch.\n"); + free(recv_data); + } + + closesocket(client); + closesocket(server); + free(bufs); + free(send_data); +} + static void test_valid_handle(void) { HANDLE duplicated, invalid; @@ -15035,6 +15084,7 @@ START_TEST( sock ) test_tcp_sendto_recvfrom(); test_broadcast(); test_send_buffering(); + test_send_many_buffers(); test_valid_handle(); test_afunix(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11316