tests/qtest: Use send/recv for socket communication

Socket communication in the libqtest and libqmp codes uses read()
and write() which work on any file descriptor on *nix, and sockets
in *nix are an example of a file descriptor.

However sockets on Windows do not use *nix-style file descriptors,
so read() and write() cannot be used on sockets on Windows.
Switch over to use send() and recv() instead which work on both
Windows and *nix.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20221028045736.679903-3-bin.meng@windriver.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
Xuzhou Cheng 2022-10-28 12:57:27 +08:00 committed by Thomas Huth
parent c9923550b4
commit 84c662d254
4 changed files with 41 additions and 4 deletions

View File

@ -33,6 +33,19 @@ int qemu_socketpair(int domain, int type, int protocol, int sv[2]);
#endif
int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
/*
* A variant of send(2) which handles partial send.
*
* Return the number of bytes transferred over the socket.
* Set errno if fewer than `count' bytes are sent.
*
* This function don't work with non-blocking socket's.
* Any of the possibilities with non-blocking socket's is bad:
* - return a short write (then name is wrong)
* - busy wait adding (errno == EAGAIN) to the loop
*/
ssize_t qemu_send_full(int s, const void *buf, size_t count)
G_GNUC_WARN_UNUSED_RESULT;
int socket_set_cork(int fd, int v);
int socket_set_nodelay(int fd);
void qemu_socket_set_block(int fd);

View File

@ -23,6 +23,7 @@
#endif
#include "qemu/cutils.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "qapi/qmp/json-parser.h"
#include "qapi/qmp/qjson.h"
@ -36,7 +37,7 @@ typedef struct {
static void socket_send(int fd, const char *buf, size_t size)
{
size_t res = qemu_write_full(fd, buf, size);
ssize_t res = qemu_send_full(fd, buf, size);
assert(res == size);
}
@ -69,7 +70,7 @@ QDict *qmp_fd_receive(int fd)
ssize_t len;
char c;
len = read(fd, &c, 1);
len = recv(fd, &c, 1, 0);
if (len == -1 && errno == EINTR) {
continue;
}

View File

@ -27,6 +27,7 @@
#include "libqmp.h"
#include "qemu/ctype.h"
#include "qemu/cutils.h"
#include "qemu/sockets.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qapi/qmp/qlist.h"
@ -428,7 +429,7 @@ void qtest_quit(QTestState *s)
static void socket_send(int fd, const char *buf, size_t size)
{
size_t res = qemu_write_full(fd, buf, size);
ssize_t res = qemu_send_full(fd, buf, size);
assert(res == size);
}
@ -460,7 +461,7 @@ static GString *qtest_client_socket_recv_line(QTestState *s)
ssize_t len;
char buffer[1024];
len = read(s->fd, buffer, sizeof(buffer));
len = recv(s->fd, buffer, sizeof(buffer), 0);
if (len == -1 && errno == EINTR) {
continue;
}

View File

@ -502,6 +502,28 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
return ret;
}
ssize_t qemu_send_full(int s, const void *buf, size_t count)
{
ssize_t ret = 0;
ssize_t total = 0;
while (count) {
ret = send(s, buf, count, 0);
if (ret < 0) {
if (errno == EINTR) {
continue;
}
break;
}
count -= ret;
buf += ret;
total += ret;
}
return total;
}
void qemu_set_hw_version(const char *version)
{
hw_version = version;