[PATCH 4/8] alfred: vis: handle short reads on the unix socket

Sven Eckelmann <[email protected]> Tue, 28 Jul 2026 18:01:33 +0200
Newsgroups org.open-mesh.lists.batman
Message-ID <[email protected]>
The answer of the alfred daemon is received over a SOCK_STREAM unix socket
which doesn't preserve message boundaries. read() can therefore return less
than the requested number of bytes. Such a short read was treated like an
end of stream, the current packet was dropped and the answer loop
terminated.

Retry the read until the requested amount of data, end of stream or a real
error was received (ignoring temporary interruptions EINTR).

Fixes: 2e3e312f7757 ("alfred: add vis")
Signed-off-by: Sven Eckelmann <[email protected]>
---
 vis/vis.c | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/vis/vis.c b/vis/vis.c
index d529583..33fa692 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -694,6 +694,29 @@ static int vis_request_data(struct globals *globals)
 	return globals->unix_sock;
 }
 
+static ssize_t read_full(int fd, void *buf, size_t count)
+{
+	size_t read_len = 0;
+	uint8_t *pos = buf;
+	ssize_t ret;
+
+	while (read_len < count) {
+		ret = read(fd, pos + read_len, count - read_len);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+
+			return ret;
+		}
+
+		if (ret == 0)
+			break;
+
+		read_len += ret;
+	}
+
+	return read_len;
+}
 
 static struct vis_v1 *vis_receive_answer_packet(int sock, uint16_t *len)
 {
@@ -704,11 +727,11 @@ static struct vis_v1 *vis_receive_answer_packet(int sock, uint16_t *len)
 	int ret;
 	int l;
 
-	ret = read(sock, buf, sizeof(*tlv));
+	ret = read_full(sock, buf, sizeof(*tlv));
 	if (ret < 0)
 		return NULL;
 
-	if (ret < (int)sizeof(*tlv)) 
+	if (ret < (int)sizeof(*tlv))
 		return NULL;
 
 	tlv = (struct alfred_tlv *)buf;
@@ -726,7 +749,7 @@ static struct vis_v1 *vis_receive_answer_packet(int sock, uint16_t *len)
 		return NULL;
 
 	/* read the rest of the packet */
-	ret = read(sock, buf + sizeof(*tlv), l);
+	ret = read_full(sock, buf + sizeof(*tlv), l);
 	if (ret < l)
 		return NULL;
 

-- 
2.47.3