aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-03-13 13:44:17 +0000
committerPeter Maydell <peter.maydell@linaro.org>2023-03-13 13:44:17 +0000
commit284c52eec2d0a1b9c47f06c3eee46762c5fc0915 (patch)
tree2020afbc1d980f53767c061e01e23ee98e722c83 /util
parent29c8a9e31a982874ce4e2c15f2bf82d5f8dc3517 (diff)
parent4bf21c7f748bee42b6f4692f8c37a11d1033b2d1 (diff)
downloadqemu-284c52eec2d0a1b9c47f06c3eee46762c5fc0915.zip
qemu-284c52eec2d0a1b9c47f06c3eee46762c5fc0915.tar.gz
qemu-284c52eec2d0a1b9c47f06c3eee46762c5fc0915.tar.bz2
Merge tag 'win-socket-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging
QMP command to import win32 sockets # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmQPDQ0cHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5eTUD/41+bodkctP9wtNQT5g # 4P2XQysa9dhxIaQuPT48J5bN0velOAv+p+e9jNMojVPHogACRGkjJUGrh2AhaWJO # bpqB5teNz3pbTLAHNrqiJdUrJDI0WSqBN2q7WgfbzvHMugBqul13n6UG/cVWH8D3 # pDX3miBl9Cv3zUDFzPjHH3eR/MHz+6wXmuzUGQdWqyGBoLwqgWA3Bqh39BDVOeJf # 03Kq3TbJSP096EjGGrq1pTYDIIv9AKzUWgn8tT8S73sD3J0BN28Gl5HirXDx8e/4 # 2WtW/XLYKjqoUl7RmXOjfOarCV+kxzdoYCAUYfyH6DLWrkXc41L5ugFdyxxQ66Sh # +on7hKCBzPEOPEXmlm6HlMj3bK4C/GI6mIoaZgCrsvj9xlehhQNtwpndAwAR8esH # perQ6q+jPdoQnBvOBgC3amckS1kYdbQivTILkoopumw/q4waG5reyA4rshbhm/bs # U33ZRzob0XyRWqvWAcq9hnWB5gvQCcppeJlu60gocnX5wdZOjbnsBXw3l+r2osIh # izJbxwM6xmz9oHh50nhDCn42JrNdSnZJdJ/XA/lrOkTHQ6kbZO7v86Y/mKQz+Vyx # Uyhb8/y8gKrUkZlGCEMvQVcyvOA8vneX8WhfZUm6w5MWWCNKfCrEl6UGmFkPAL0m # +sUYIhN5PSxWSQU5MWogXtQEPA== # =/Y/7 # -----END PGP SIGNATURE----- # gpg: Signature made Mon 13 Mar 2023 11:46:21 GMT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'win-socket-pull-request' of https://gitlab.com/marcandre.lureau/qemu: (25 commits) monitor: restrict command getfd to POSIX hosts qtest: enable vnc-display test on win32 libqtest: make qtest_qmp_add_client work on win32 qmp: add 'get-win32-socket' monitor: release the lock before calling close() qmp: 'add_client' actually expects sockets osdep: implement qemu_socketpair() for win32 tests/docker: fix a win32 error due to portability char: do not double-close fd when failing to add client tests: fix path separator, use g_build_filename() win32: replace closesocket() with close() wrapper os-posix: remove useless ioctlsocket() define win32: avoid mixing SOCKET and file descriptor space slirp: open-code qemu_socket_(un)select() slirp: unregister the win32 SOCKET main-loop: remove qemu_fd_register(), win32/slirp/socket specific aio/win32: aio_set_fd_handler() only supports SOCKET aio: make aio_set_fd_poll() static to aio-posix.c win32/socket: introduce qemu_socket_unselect() helper win32/socket: introduce qemu_socket_select() helper ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util')
-rw-r--r--util/aio-posix.c6
-rw-r--r--util/aio-win32.c23
-rw-r--r--util/error.c10
-rw-r--r--util/main-loop.c11
-rw-r--r--util/oslib-posix.c70
-rw-r--r--util/oslib-win32.c350
-rw-r--r--util/qemu-sockets.c22
7 files changed, 346 insertions, 146 deletions
diff --git a/util/aio-posix.c b/util/aio-posix.c
index 6cc6256..a8be940 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -180,9 +180,9 @@ void aio_set_fd_handler(AioContext *ctx,
}
}
-void aio_set_fd_poll(AioContext *ctx, int fd,
- IOHandler *io_poll_begin,
- IOHandler *io_poll_end)
+static void aio_set_fd_poll(AioContext *ctx, int fd,
+ IOHandler *io_poll_begin,
+ IOHandler *io_poll_end)
{
AioHandler *node = find_aio_handler(ctx, fd);
diff --git a/util/aio-win32.c b/util/aio-win32.c
index 80cfe01..6bded00 100644
--- a/util/aio-win32.c
+++ b/util/aio-win32.c
@@ -22,6 +22,7 @@
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "qemu/rcu_queue.h"
+#include "qemu/error-report.h"
struct AioHandler {
EventNotifier *e;
@@ -70,13 +71,20 @@ void aio_set_fd_handler(AioContext *ctx,
IOHandler *io_poll_ready,
void *opaque)
{
- /* fd is a SOCKET in our case */
AioHandler *old_node;
AioHandler *node = NULL;
+ SOCKET s;
+
+ if (!fd_is_socket(fd)) {
+ error_report("fd=%d is not a socket, AIO implementation is missing", fd);
+ return;
+ }
+
+ s = _get_osfhandle(fd);
qemu_lockcnt_lock(&ctx->list_lock);
QLIST_FOREACH(old_node, &ctx->aio_handlers, node) {
- if (old_node->pfd.fd == fd && !old_node->deleted) {
+ if (old_node->pfd.fd == s && !old_node->deleted) {
break;
}
}
@@ -87,7 +95,7 @@ void aio_set_fd_handler(AioContext *ctx,
/* Alloc and insert if it's not already there */
node = g_new0(AioHandler, 1);
- node->pfd.fd = fd;
+ node->pfd.fd = s;
node->pfd.events = 0;
if (node->io_read) {
@@ -115,7 +123,7 @@ void aio_set_fd_handler(AioContext *ctx,
QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node);
event = event_notifier_get_handle(&ctx->notifier);
- WSAEventSelect(node->pfd.fd, event, bitmask);
+ qemu_socket_select(fd, event, bitmask, NULL);
}
if (old_node) {
aio_remove_fd_handler(ctx, old_node);
@@ -125,13 +133,6 @@ void aio_set_fd_handler(AioContext *ctx,
aio_notify(ctx);
}
-void aio_set_fd_poll(AioContext *ctx, int fd,
- IOHandler *io_poll_begin,
- IOHandler *io_poll_end)
-{
- /* Not implemented */
-}
-
void aio_set_event_notifier(AioContext *ctx,
EventNotifier *e,
bool is_external,
diff --git a/util/error.c b/util/error.c
index 1e7af66..5537245 100644
--- a/util/error.c
+++ b/util/error.c
@@ -27,8 +27,9 @@ struct Error
Error *error_abort;
Error *error_fatal;
+Error *error_warn;
-static void error_handle_fatal(Error **errp, Error *err)
+static void error_handle(Error **errp, Error *err)
{
if (errp == &error_abort) {
fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
@@ -43,6 +44,9 @@ static void error_handle_fatal(Error **errp, Error *err)
error_report_err(err);
exit(1);
}
+ if (errp == &error_warn) {
+ warn_report_err(err);
+ }
}
G_GNUC_PRINTF(6, 0)
@@ -71,7 +75,7 @@ static void error_setv(Error **errp,
err->line = line;
err->func = func;
- error_handle_fatal(errp, err);
+ error_handle(errp, err);
*errp = err;
errno = saved_errno;
@@ -284,7 +288,7 @@ void error_propagate(Error **dst_errp, Error *local_err)
if (!local_err) {
return;
}
- error_handle_fatal(dst_errp, local_err);
+ error_handle(dst_errp, local_err);
if (dst_errp && !*dst_errp) {
*dst_errp = local_err;
} else {
diff --git a/util/main-loop.c b/util/main-loop.c
index 3c0f525..e180c85 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -252,10 +252,6 @@ static int max_priority;
static int glib_pollfds_idx;
static int glib_n_poll_fds;
-void qemu_fd_register(int fd)
-{
-}
-
static void glib_pollfds_fill(int64_t *cur_timeout)
{
GMainContext *context = g_main_context_default();
@@ -414,13 +410,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
}
}
-void qemu_fd_register(int fd)
-{
- WSAEventSelect(fd, event_notifier_get_handle(&qemu_aio_context->notifier),
- FD_READ | FD_ACCEPT | FD_CLOSE |
- FD_CONNECT | FD_WRITE | FD_OOB);
-}
-
static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
fd_set *xfds)
{
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index 77d882e..760390b 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -583,76 +583,6 @@ char *qemu_get_pid_name(pid_t pid)
}
-pid_t qemu_fork(Error **errp)
-{
- sigset_t oldmask, newmask;
- struct sigaction sig_action;
- int saved_errno;
- pid_t pid;
-
- /*
- * Need to block signals now, so that child process can safely
- * kill off caller's signal handlers without a race.
- */
- sigfillset(&newmask);
- if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) != 0) {
- error_setg_errno(errp, errno,
- "cannot block signals");
- return -1;
- }
-
- pid = fork();
- saved_errno = errno;
-
- if (pid < 0) {
- /* attempt to restore signal mask, but ignore failure, to
- * avoid obscuring the fork failure */
- (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
- error_setg_errno(errp, saved_errno,
- "cannot fork child process");
- errno = saved_errno;
- return -1;
- } else if (pid) {
- /* parent process */
-
- /* Restore our original signal mask now that the child is
- * safely running. Only documented failures are EFAULT (not
- * possible, since we are using just-grabbed mask) or EINVAL
- * (not possible, since we are using correct arguments). */
- (void)pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
- } else {
- /* child process */
- size_t i;
-
- /* Clear out all signal handlers from parent so nothing
- * unexpected can happen in our child once we unblock
- * signals */
- sig_action.sa_handler = SIG_DFL;
- sig_action.sa_flags = 0;
- sigemptyset(&sig_action.sa_mask);
-
- for (i = 1; i < NSIG; i++) {
- /* Only possible errors are EFAULT or EINVAL The former
- * won't happen, the latter we expect, so no need to check
- * return value */
- (void)sigaction(i, &sig_action, NULL);
- }
-
- /* Unmask all signals in child, since we've no idea what the
- * caller's done with their signal mask and don't want to
- * propagate that to children */
- sigemptyset(&newmask);
- if (pthread_sigmask(SIG_SETMASK, &newmask, NULL) != 0) {
- Error *local_err = NULL;
- error_setg_errno(&local_err, errno,
- "cannot unblock signals");
- error_report_err(local_err);
- _exit(1);
- }
- }
- return pid;
-}
-
void *qemu_alloc_stack(size_t *sz)
{
void *ptr, *guardpage;
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 07ade41..16f8a67 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -180,7 +180,7 @@ static int socket_error(void)
void qemu_socket_set_block(int fd)
{
unsigned long opt = 0;
- WSAEventSelect(fd, NULL, 0);
+ qemu_socket_unselect(fd, NULL);
ioctlsocket(fd, FIONBIO, &opt);
}
@@ -283,21 +283,155 @@ char *qemu_get_pid_name(pid_t pid)
}
-pid_t qemu_fork(Error **errp)
+bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
+ long lNetworkEvents, Error **errp)
{
- errno = ENOSYS;
- error_setg_errno(errp, errno,
- "cannot fork child process");
- return -1;
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (errp == NULL) {
+ errp = &error_warn;
+ }
+
+ if (s == INVALID_SOCKET) {
+ error_setg(errp, "invalid socket fd=%d", sockfd);
+ return false;
+ }
+
+ if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) {
+ error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()");
+ return false;
+ }
+
+ return true;
}
+bool qemu_socket_unselect(int sockfd, Error **errp)
+{
+ return qemu_socket_select(sockfd, NULL, 0, errp);
+}
+
+int qemu_socketpair(int domain, int type, int protocol, int sv[2])
+{
+ struct sockaddr_un addr = {
+ 0,
+ };
+ socklen_t socklen;
+ int listener = -1;
+ int client = -1;
+ int server = -1;
+ g_autofree char *path = NULL;
+ int tmpfd;
+ u_long arg;
+ int ret = -1;
+
+ g_return_val_if_fail(sv != NULL, -1);
+
+ addr.sun_family = AF_UNIX;
+ socklen = sizeof(addr);
+
+ tmpfd = g_file_open_tmp(NULL, &path, NULL);
+ if (tmpfd == -1 || !path) {
+ errno = EACCES;
+ goto out;
+ }
+
+ close(tmpfd);
+
+ if (strlen(path) >= sizeof(addr.sun_path)) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
+
+ listener = socket(domain, type, protocol);
+ if (listener == -1) {
+ goto out;
+ }
+
+ if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) {
+ errno = EACCES;
+ goto out;
+ }
+ g_clear_pointer(&path, g_free);
+
+ if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) {
+ goto out;
+ }
+
+ if (listen(listener, 1) == -1) {
+ goto out;
+ }
+
+ client = socket(domain, type, protocol);
+ if (client == -1) {
+ goto out;
+ }
+
+ arg = 1;
+ if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
+ goto out;
+ }
+
+ if (connect(client, (struct sockaddr *)&addr, socklen) == -1 &&
+ WSAGetLastError() != WSAEWOULDBLOCK) {
+ goto out;
+ }
+
+ server = accept(listener, NULL, NULL);
+ if (server == -1) {
+ goto out;
+ }
+
+ arg = 0;
+ if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) {
+ goto out;
+ }
+
+ arg = 0;
+ if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) {
+ goto out;
+ }
+
+ if (arg != GetCurrentProcessId()) {
+ errno = EPERM;
+ goto out;
+ }
+
+ sv[0] = server;
+ server = -1;
+ sv[1] = client;
+ client = -1;
+ ret = 0;
+
+out:
+ if (listener != -1) {
+ close(listener);
+ }
+ if (client != -1) {
+ close(client);
+ }
+ if (server != -1) {
+ close(server);
+ }
+ if (path) {
+ DeleteFile(path);
+ }
+ return ret;
+}
#undef connect
int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
socklen_t addrlen)
{
int ret;
- ret = connect(sockfd, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = connect(s, addr, addrlen);
if (ret < 0) {
if (WSAGetLastError() == WSAEWOULDBLOCK) {
errno = EINPROGRESS;
@@ -313,7 +447,13 @@ int qemu_connect_wrap(int sockfd, const struct sockaddr *addr,
int qemu_listen_wrap(int sockfd, int backlog)
{
int ret;
- ret = listen(sockfd, backlog);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = listen(s, backlog);
if (ret < 0) {
errno = socket_error();
}
@@ -326,7 +466,13 @@ int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
socklen_t addrlen)
{
int ret;
- ret = bind(sockfd, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = bind(s, addr, addrlen);
if (ret < 0) {
errno = socket_error();
}
@@ -334,15 +480,82 @@ int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
}
+#undef close
+int qemu_close_wrap(int fd)
+{
+ int ret;
+ DWORD flags = 0;
+ SOCKET s = INVALID_SOCKET;
+
+ if (fd_is_socket(fd)) {
+ s = _get_osfhandle(fd);
+
+ /*
+ * If we were to just call _close on the descriptor, it would close the
+ * HANDLE, but it wouldn't free any of the resources associated to the
+ * SOCKET, and we can't call _close after calling closesocket, because
+ * closesocket has already closed the HANDLE, and _close would attempt to
+ * close the HANDLE again, resulting in a double free. We can however
+ * protect the HANDLE from actually being closed long enough to close the
+ * file descriptor, then close the socket itself.
+ */
+ if (!GetHandleInformation((HANDLE)s, &flags)) {
+ errno = EACCES;
+ return -1;
+ }
+
+ if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
+ errno = EACCES;
+ return -1;
+ }
+ }
+
+ ret = close(fd);
+
+ if (s != INVALID_SOCKET && !SetHandleInformation((HANDLE)s, flags, flags)) {
+ errno = EACCES;
+ return -1;
+ }
+
+ /*
+ * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying handle,
+ * but the FD is actually freed
+ */
+ if (ret < 0 && (s == INVALID_SOCKET || errno != EBADF)) {
+ return ret;
+ }
+
+ if (s != INVALID_SOCKET) {
+ ret = closesocket(s);
+ if (ret < 0) {
+ errno = socket_error();
+ }
+ }
+
+ return ret;
+}
+
+
#undef socket
int qemu_socket_wrap(int domain, int type, int protocol)
{
- int ret;
- ret = socket(domain, type, protocol);
- if (ret < 0) {
+ SOCKET s;
+ int fd;
+
+ s = socket(domain, type, protocol);
+ if (s == -1) {
errno = socket_error();
+ return -1;
}
- return ret;
+
+ fd = _open_osfhandle(s, _O_BINARY);
+ if (fd < 0) {
+ closesocket(s);
+ /* _open_osfhandle may not set errno, and closesocket() may override it */
+ errno = ENOMEM;
+ }
+
+ return fd;
}
@@ -350,12 +563,27 @@ int qemu_socket_wrap(int domain, int type, int protocol)
int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
socklen_t *addrlen)
{
- int ret;
- ret = accept(sockfd, addr, addrlen);
- if (ret < 0) {
+ int fd;
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ s = accept(s, addr, addrlen);
+ if (s == -1) {
errno = socket_error();
+ return -1;
}
- return ret;
+
+ fd = _open_osfhandle(s, _O_BINARY);
+ if (fd < 0) {
+ closesocket(s);
+ /* _open_osfhandle may not set errno, and closesocket() may override it */
+ errno = ENOMEM;
+ }
+
+ return fd;
}
@@ -363,7 +591,13 @@ int qemu_accept_wrap(int sockfd, struct sockaddr *addr,
int qemu_shutdown_wrap(int sockfd, int how)
{
int ret;
- ret = shutdown(sockfd, how);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = shutdown(s, how);
if (ret < 0) {
errno = socket_error();
}
@@ -375,19 +609,13 @@ int qemu_shutdown_wrap(int sockfd, int how)
int qemu_ioctlsocket_wrap(int fd, int req, void *val)
{
int ret;
- ret = ioctlsocket(fd, req, val);
- if (ret < 0) {
- errno = socket_error();
- }
- return ret;
-}
+ SOCKET s = _get_osfhandle(fd);
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
-#undef closesocket
-int qemu_closesocket_wrap(int fd)
-{
- int ret;
- ret = closesocket(fd);
+ ret = ioctlsocket(s, req, val);
if (ret < 0) {
errno = socket_error();
}
@@ -400,7 +628,13 @@ int qemu_getsockopt_wrap(int sockfd, int level, int optname,
void *optval, socklen_t *optlen)
{
int ret;
- ret = getsockopt(sockfd, level, optname, optval, optlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = getsockopt(s, level, optname, optval, optlen);
if (ret < 0) {
errno = socket_error();
}
@@ -413,7 +647,13 @@ int qemu_setsockopt_wrap(int sockfd, int level, int optname,
const void *optval, socklen_t optlen)
{
int ret;
- ret = setsockopt(sockfd, level, optname, optval, optlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = setsockopt(s, level, optname, optval, optlen);
if (ret < 0) {
errno = socket_error();
}
@@ -426,7 +666,13 @@ int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr,
socklen_t *addrlen)
{
int ret;
- ret = getpeername(sockfd, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = getpeername(s, addr, addrlen);
if (ret < 0) {
errno = socket_error();
}
@@ -439,7 +685,13 @@ int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
socklen_t *addrlen)
{
int ret;
- ret = getsockname(sockfd, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = getsockname(s, addr, addrlen);
if (ret < 0) {
errno = socket_error();
}
@@ -451,7 +703,13 @@ int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr,
ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags)
{
int ret;
- ret = send(sockfd, buf, len, flags);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = send(s, buf, len, flags);
if (ret < 0) {
errno = socket_error();
}
@@ -464,7 +722,13 @@ ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *addr, socklen_t addrlen)
{
int ret;
- ret = sendto(sockfd, buf, len, flags, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = sendto(s, buf, len, flags, addr, addrlen);
if (ret < 0) {
errno = socket_error();
}
@@ -476,7 +740,13 @@ ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags,
ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags)
{
int ret;
- ret = recv(sockfd, buf, len, flags);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = recv(s, buf, len, flags);
if (ret < 0) {
errno = socket_error();
}
@@ -489,7 +759,13 @@ ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *addr, socklen_t *addrlen)
{
int ret;
- ret = recvfrom(sockfd, buf, len, flags, addr, addrlen);
+ SOCKET s = _get_osfhandle(sockfd);
+
+ if (s == INVALID_SOCKET) {
+ return -1;
+ }
+
+ ret = recvfrom(s, buf, len, flags, addr, addrlen);
if (ret < 0) {
errno = socket_error();
}
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 6538859..c06a4dc 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -326,7 +326,7 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
* recover from this situation, so we need to recreate the
* socket to allow bind attempts for subsequent ports:
*/
- closesocket(slisten);
+ close(slisten);
slisten = -1;
}
}
@@ -337,7 +337,7 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
listen_failed:
saved_errno = errno;
if (slisten >= 0) {
- closesocket(slisten);
+ close(slisten);
}
freeaddrinfo(res);
errno = saved_errno;
@@ -380,7 +380,7 @@ static int inet_connect_addr(const InetSocketAddress *saddr,
if (rc < 0) {
error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
saddr->host, saddr->port);
- closesocket(sock);
+ close(sock);
return -1;
}
@@ -483,7 +483,7 @@ int inet_connect_saddr(InetSocketAddress *saddr, Error **errp)
if (ret < 0) {
error_setg_errno(errp, errno, "Unable to set KEEPALIVE");
- closesocket(sock);
+ close(sock);
return -1;
}
}
@@ -580,7 +580,7 @@ static int inet_dgram_saddr(InetSocketAddress *sraddr,
err:
if (sock != -1) {
- closesocket(sock);
+ close(sock);
}
if (local) {
freeaddrinfo(local);
@@ -777,7 +777,7 @@ static int vsock_connect_addr(const VsockSocketAddress *vaddr,
if (rc < 0) {
error_setg_errno(errp, errno, "Failed to connect to '%s:%s'",
vaddr->cid, vaddr->port);
- closesocket(sock);
+ close(sock);
return -1;
}
@@ -814,13 +814,13 @@ static int vsock_listen_saddr(VsockSocketAddress *vaddr,
if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) {
error_setg_errno(errp, errno, "Failed to bind socket");
- closesocket(slisten);
+ close(slisten);
return -1;
}
if (listen(slisten, num) != 0) {
error_setg_errno(errp, errno, "Failed to listen on socket");
- closesocket(slisten);
+ close(slisten);
return -1;
}
return slisten;
@@ -978,7 +978,7 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
err:
g_free(pathbuf);
- closesocket(sock);
+ close(sock);
return -1;
}
@@ -1041,7 +1041,7 @@ static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp)
return sock;
err:
- closesocket(sock);
+ close(sock);
return -1;
}
@@ -1238,7 +1238,7 @@ int socket_listen(SocketAddress *addr, int num, Error **errp)
*/
if (listen(fd, num) != 0) {
error_setg_errno(errp, errno, "Failed to listen on fd socket");
- closesocket(fd);
+ close(fd);
return -1;
}
break;