summaryrefslogtreecommitdiff
path: root/Kernel/Net/IPv4Socket.cpp
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-12-02 00:39:50 +0200
committerAndreas Kling <kling@serenityos.org>2021-12-05 12:53:29 +0100
commite521ffd1566656c2d65a9db4be9a3827e64d276c (patch)
tree788989ebb4e82655215586510de20d68c3a14729 /Kernel/Net/IPv4Socket.cpp
parent5514d60d8dc5abd110bf16b516b55ec0e622a028 (diff)
downloadserenity-e521ffd1566656c2d65a9db4be9a3827e64d276c.zip
Kernel: Add support for the MSG_WAITALL sys$recvmsg flag
Diffstat (limited to 'Kernel/Net/IPv4Socket.cpp')
-rw-r--r--Kernel/Net/IPv4Socket.cpp27
1 files changed, 19 insertions, 8 deletions
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<size_t> IPv4Socket::recvfrom(OpenFileDescription& description, UserOrKer
dbgln_if(IPV4_SOCKET_DEBUG, "recvfrom: type={}, local_port={}", type(), local_port());
- ErrorOr<size_t> 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<size_t> total_nreceived = 0;
+ do {
+ auto offset_buffer = buffer.offset(total_nreceived.value());
+ auto offset_buffer_length = buffer_length - total_nreceived.value();
+
+ ErrorOr<size_t> 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)