aboutsummaryrefslogtreecommitdiff
path: root/tools/testing/vsock/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/vsock/util.c')
-rw-r--r--tools/testing/vsock/util.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/tools/testing/vsock/util.c b/tools/testing/vsock/util.c
index 9430ef5b8bc3..fe316b02a590 100644
--- a/tools/testing/vsock/util.c
+++ b/tools/testing/vsock/util.c
@@ -344,7 +344,9 @@ void send_buf(int fd, const void *buf, size_t len, int flags,
ret = send(fd, buf + nwritten, len - nwritten, flags);
timeout_check("send");
- if (ret == 0 || (ret < 0 && errno != EINTR))
+ if (ret < 0 && errno == EINTR)
+ continue;
+ if (ret <= 0)
break;
nwritten += ret;
@@ -379,8 +381,14 @@ void send_buf(int fd, const void *buf, size_t len, int flags,
}
}
+#define RECV_PEEK_RETRY_USEC (10 * 1000)
+
/* Receive bytes in a buffer and check the return value.
*
+ * When MSG_PEEK is set, recv() is retried until it returns at least
+ * expected_ret bytes. The function returns on error, EOF, or timeout
+ * as usual.
+ *
* expected_ret:
* <0 Negative errno (for testing errors)
* 0 End-of-file
@@ -396,9 +404,20 @@ void recv_buf(int fd, void *buf, size_t len, int flags, ssize_t expected_ret)
ret = recv(fd, buf + nread, len - nread, flags);
timeout_check("recv");
- if (ret == 0 || (ret < 0 && errno != EINTR))
+ if (ret < 0 && errno == EINTR)
+ continue;
+ if (ret <= 0)
break;
+ if (flags & MSG_PEEK) {
+ if (ret >= expected_ret) {
+ nread = ret;
+ break;
+ }
+ timeout_usleep(RECV_PEEK_RETRY_USEC);
+ continue;
+ }
+
nread += ret;
} while (nread < len);
timeout_end();