diff mbox series

[v4,2/6] util: make do_send_recv work with partial send/recv

Message ID 20221006113657.2656108-3-marcandre.lureau@redhat.com
State New
Headers show
Series io/command: implement portable spawn | expand

Commit Message

Marc-André Lureau Oct. 6, 2022, 11:36 a.m. UTC
From: Marc-André Lureau <marcandre.lureau@redhat.com>

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>
---
 util/iov.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Comments

Daniel P. Berrangé Oct. 12, 2022, 3:14 p.m. UTC | #1
On Thu, Oct 06, 2022 at 03:36:53PM +0400, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> 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>
> ---
>  util/iov.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
diff mbox series

Patch

diff --git a/util/iov.c b/util/iov.c
index 22d6996cce..b4be580022 100644
--- a/util/iov.c
+++ b/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;