From e581ec3043d528cadb56c5d49b1b29c92fa78d83 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sat, 30 Mar 2013 15:42:51 +0100 Subject: [PATCH] lib: fix sync_recv to handle segmentation While it should not happen with Unix sockets, a read() can return only partial data. Therefore, we continue to poll until we get the appropriate length. This fix was proposed by Chris Yang. Closes #31. --- src/lib/connection.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/connection.c b/src/lib/connection.c index 3b3227cc..2fe7c44d 100644 --- a/src/lib/connection.c +++ b/src/lib/connection.c @@ -68,6 +68,7 @@ sync_recv(lldpctl_conn_t *lldpctl, { struct lldpctl_conn_sync_t *conn = user_data; size_t nb; + size_t remain, offset = 0; if (conn->fd == -1 && ((conn->fd = sync_connect(lldpctl)) == -1)) { @@ -75,14 +76,17 @@ sync_recv(lldpctl_conn_t *lldpctl, return LLDPCTL_ERR_CANNOT_CONNECT; } - while ((nb = read(conn->fd, (void*)data, length)) == -1) { - if (errno == EAGAIN || errno == EINTR) continue; - return LLDPCTL_ERR_CALLBACK_FAILURE; - } - return nb; + remain = length; + do { + if ((nb = read(conn->fd, (void*)data + offset, remain)) == -1 && + (errno == EAGAIN || errno == EINTR)) + continue; + remain -= nb; + offset += nb; + } while (remain > 0 && nb > 0); + return offset; } - lldpctl_conn_t* lldpctl_new(lldpctl_send_callback send, lldpctl_recv_callback recv, void *user_data) { -- 2.39.5