util: make do_send_recv work with partial send/recv
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>
This commit is contained in:
parent
c1f7980913
commit
3f08376c2e
10
util/iov.c
10
util/iov.c
@ -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) {
|
||||
@ -129,6 +134,7 @@ do_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt, bool do_send)
|
||||
}
|
||||
break;
|
||||
}
|
||||
off = 0;
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user