Skip to content

Commit

Permalink
tests/qtest: Use send/recv for socket communication
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
xchengL authored and huth committed Oct 28, 2022
1 parent c992355 commit 84c662d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
13 changes: 13 additions & 0 deletions include/qemu/sockets.h
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions tests/qtest/libqmp.c
Expand Up @@ -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"
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions tests/qtest/libqtest.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
22 changes: 22 additions & 0 deletions util/osdep.c
Expand Up @@ -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;
Expand Down

0 comments on commit 84c662d

Please sign in to comment.