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
This commit is contained in:
Sebastian Sumpf 2024-02-16 10:06:59 +01:00 committed by Christian Helmuth
parent 0b63bb91b6
commit 7cbce1f47c

View File

@ -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;
}