Skip to content

Commit

Permalink
util: make do_send_recv work with partial send/recv
Browse files Browse the repository at this point in the history
According to msdn documentation and Linux man pages, send() should try
to send as much as possible in blocking mode, while recv() may return
earlier with a smaller available amount, we should try to continue
send/recv from there.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20221006113657.2656108-3-marcandre.lureau@redhat.com>
  • Loading branch information
elmarco committed Oct 12, 2022
1 parent c1f7980 commit 3f08376
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions util/iov.c
Expand Up @@ -111,12 +111,17 @@ do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send)
/*XXX Note: windows has WSASend() and WSARecv() */
unsigned i = 0;
ssize_t ret = 0;
ssize_t off = 0;
while (i < iov_cnt) {
ssize_t r = do_send
? send(sockfd, iov[i].iov_base, iov[i].iov_len, 0)
: recv(sockfd, iov[i].iov_base, iov[i].iov_len, 0);
? send(sockfd, iov[i].iov_base + off, iov[i].iov_len - off, 0)
: recv(sockfd, iov[i].iov_base + off, iov[i].iov_len - off, 0);
if (r > 0) {
ret += r;
off += r;
if (off < iov[i].iov_len) {
continue;
}
} else if (!r) {
break;
} else if (errno == EINTR) {
Expand All @@ -129,6 +134,7 @@ do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send)
}
break;
}
off = 0;
i++;
}
return ret;
Expand Down

0 comments on commit 3f08376

Please sign in to comment.