diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2021-12-02 00:39:50 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-12-05 12:53:29 +0100 |
commit | e521ffd1566656c2d65a9db4be9a3827e64d276c (patch) | |
tree | 788989ebb4e82655215586510de20d68c3a14729 /Kernel/Net/IPv4Socket.cpp | |
parent | 5514d60d8dc5abd110bf16b516b55ec0e622a028 (diff) | |
download | serenity-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.cpp | 27 |
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) |