From 7cbce1f47c4956bacac4de5b489d22b06ddf6d23 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Fri, 16 Feb 2024 10:06:59 +0100 Subject: [PATCH] libc: socket_fs_plugin handle MSG_PEEK reads In case the socket is non-blocking, a read with the MSG_PEEK flag set has to return -1 and EWOULDBLOCK/EAGAIN in case no data is availble and the socket is connected. Returning zero implies the socket is in non-connected state. Therefore, check the connection state in this situation and return accordingly. issue #5104 --- repos/libports/src/lib/libc/socket_fs_plugin.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/repos/libports/src/lib/libc/socket_fs_plugin.cc b/repos/libports/src/lib/libc/socket_fs_plugin.cc index a73125f439..f8e9a1d27a 100644 --- a/repos/libports/src/lib/libc/socket_fs_plugin.cc +++ b/repos/libports/src/lib/libc/socket_fs_plugin.cc @@ -839,13 +839,24 @@ static ssize_t do_recvfrom(File_descriptor *fd, size_t out_sum = 0; do { - size_t const result = read(data_fd, - (char *)buf + out_sum, - len - out_sum); + ssize_t const result = read(data_fd, + (char *)buf + out_sum, + len - out_sum); + if (result <= 0) { /* eof & error */ if (out_sum) return out_sum; + /* + * For non-blocking reads with MSG_PEEK, we need to return -1 and + * EWOULDBLOCK or EAGAIN in case the socket is connected. Check connect + * status and return accordingly. + */ + if (errno == EIO && (flags & MSG_PEEK) && + (context->fd_flags() & O_NONBLOCK) && + context->read_connect_status() == 0) + return Errno(EWOULDBLOCK); + return result; }