From e521ffd1566656c2d65a9db4be9a3827e64d276c Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Thu, 2 Dec 2021 00:39:50 +0200 Subject: Kernel: Add support for the MSG_WAITALL sys$recvmsg flag --- Kernel/Net/IPv4Socket.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'Kernel/Net/IPv4Socket.cpp') diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 3cc09f3f26..1b0445d94a 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -391,15 +391,26 @@ ErrorOr IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKer dbgln_if(IPV4_SOCKET_DEBUG, "recvfrom: type={}, local_port={}", type(), local_port()); - ErrorOr nreceived = 0; - if (buffer_mode() == BufferMode::Bytes) - nreceived = receive_byte_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length); - else - nreceived = receive_packet_buffered(description, buffer, buffer_length, flags, user_addr, user_addr_length, packet_timestamp); + ErrorOr total_nreceived = 0; + do { + auto offset_buffer = buffer.offset(total_nreceived.value()); + auto offset_buffer_length = buffer_length - total_nreceived.value(); + + ErrorOr nreceived = 0; + if (buffer_mode() == BufferMode::Bytes) + nreceived = receive_byte_buffered(description, offset_buffer, offset_buffer_length, flags, user_addr, user_addr_length); + else + nreceived = receive_packet_buffered(description, offset_buffer, offset_buffer_length, flags, user_addr, user_addr_length, packet_timestamp); + + if (nreceived.is_error()) + total_nreceived = nreceived; + else + total_nreceived.value() += nreceived.value(); + } while ((flags & MSG_WAITALL) && !total_nreceived.is_error() && total_nreceived.value() < buffer_length); - if (!nreceived.is_error()) - Thread::current()->did_ipv4_socket_read(nreceived.value()); - return nreceived; + if (!total_nreceived.is_error()) + Thread::current()->did_ipv4_socket_read(total_nreceived.value()); + return total_nreceived; } bool IPv4Socket::did_receive(const IPv4Address& source_address, u16 source_port, ReadonlyBytes packet, const Time& packet_timestamp) -- cgit v1.2.3