aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/os-win32.h15
-rw-r--r--ui/console.c3
-rw-r--r--ui/dbus.c9
-rw-r--r--ui/gtk.c7
-rw-r--r--ui/sdl2.c16
-rw-r--r--ui/spice-core.c29
-rw-r--r--util/oslib-win32.c75
7 files changed, 97 insertions, 57 deletions
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index e2849f88ab..15c296e0eb 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -171,10 +171,21 @@ bool qemu_socket_select(int sockfd, WSAEVENT hEventObject,
bool qemu_socket_unselect(int sockfd, Error **errp);
-/* We wrap all the sockets functions so that we can
- * set errno based on WSAGetLastError()
+/* We wrap all the sockets functions so that we can set errno based on
+ * WSAGetLastError(), and use file-descriptors instead of SOCKET.
*/
+/*
+ * qemu_close_socket_osfhandle:
+ * @fd: a file descriptor associated with a SOCKET
+ *
+ * Close only the C run-time file descriptor, leave the SOCKET opened.
+ *
+ * Returns zero on success. On error, -1 is returned, and errno is set to
+ * indicate the error.
+ */
+int qemu_close_socket_osfhandle(int fd);
+
#undef close
#define close qemu_close_wrap
int qemu_close_wrap(int fd);
diff --git a/ui/console.c b/ui/console.c
index f3783021e5..6e8a3cdc62 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2303,6 +2303,9 @@ QemuConsole *qemu_console_lookup_unused(void)
QEMUCursor *qemu_console_get_cursor(QemuConsole *con)
{
+ if (con == NULL) {
+ con = active_console;
+ }
return con->cursor;
}
diff --git a/ui/dbus.c b/ui/dbus.c
index 0513de9918..b9e9698503 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -304,11 +304,20 @@ dbus_display_add_client(int csock, Error **errp)
g_cancellable_cancel(dbus_display->add_client_cancellable);
}
+#ifdef WIN32
+ socket = g_socket_new_from_fd(_get_osfhandle(csock), &err);
+#else
socket = g_socket_new_from_fd(csock, &err);
+#endif
if (!socket) {
error_setg(errp, "Failed to setup D-Bus socket: %s", err->message);
+ close(csock);
return false;
}
+#ifdef WIN32
+ /* socket owns the SOCKET handle now, so release our osf handle */
+ qemu_close_socket_osfhandle(csock);
+#endif
conn = g_socket_connection_factory_create_connection(socket);
diff --git a/ui/gtk.c b/ui/gtk.c
index fd82e9b1ca..f16e0f8dee 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -450,7 +450,8 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
GdkDisplay *dpy;
gint x_root, y_root;
- if (qemu_input_is_absolute()) {
+ if (!gtk_widget_get_realized(vc->gfx.drawing_area) ||
+ qemu_input_is_absolute()) {
return;
}
@@ -1783,7 +1784,9 @@ static void gd_vc_chr_accept_input(Chardev *chr)
VCChardev *vcd = VC_CHARDEV(chr);
VirtualConsole *vc = vcd->console;
- gd_vc_send_chars(vc);
+ if (vc) {
+ gd_vc_send_chars(vc);
+ }
}
static void gd_vc_chr_set_echo(Chardev *chr, bool echo)
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 35c58c1104..b12dec4caf 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -843,22 +843,6 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
assert(o->type == DISPLAY_TYPE_SDL);
-#ifdef __linux__
- /* on Linux, SDL may use fbcon|directfb|svgalib when run without
- * accessible $DISPLAY to open X11 window. This is often the case
- * when qemu is run using sudo. But in this case, and when actually
- * run in X11 environment, SDL fights with X11 for the video card,
- * making current display unavailable, often until reboot.
- * So make x11 the default SDL video driver if this variable is unset.
- * This is a bit hackish but saves us from bigger problem.
- * Maybe it's a good idea to fix this in SDL instead.
- */
- if (!g_setenv("SDL_VIDEODRIVER", "x11", 0)) {
- fprintf(stderr, "Could not set SDL_VIDEODRIVER environment variable\n");
- exit(1);
- }
-#endif
-
if (SDL_GetHintBoolean("QEMU_ENABLE_SDL_LOGGING", SDL_FALSE)) {
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE);
}
diff --git a/ui/spice-core.c b/ui/spice-core.c
index b05c830086..67cfd3ca9c 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -90,13 +90,23 @@ struct SpiceWatch {
static void watch_read(void *opaque)
{
SpiceWatch *watch = opaque;
- watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
+ int fd = watch->fd;
+
+#ifdef WIN32
+ fd = _get_osfhandle(fd);
+#endif
+ watch->func(fd, SPICE_WATCH_EVENT_READ, watch->opaque);
}
static void watch_write(void *opaque)
{
SpiceWatch *watch = opaque;
- watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
+ int fd = watch->fd;
+
+#ifdef WIN32
+ fd = _get_osfhandle(fd);
+#endif
+ watch->func(fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
}
static void watch_update_mask(SpiceWatch *watch, int event_mask)
@@ -117,6 +127,14 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
{
SpiceWatch *watch;
+#ifdef WIN32
+ fd = _open_osfhandle(fd, _O_BINARY);
+ if (fd < 0) {
+ error_setg_win32(&error_warn, WSAGetLastError(), "Couldn't associate a FD with the SOCKET");
+ return NULL;
+ }
+#endif
+
watch = g_malloc0(sizeof(*watch));
watch->fd = fd;
watch->func = func;
@@ -129,6 +147,10 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
static void watch_remove(SpiceWatch *watch)
{
qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
+#ifdef WIN32
+ /* SOCKET is owned by spice */
+ qemu_close_to_socket(watch->fd);
+#endif
g_free(watch);
}
@@ -908,6 +930,9 @@ static int qemu_spice_set_pw_expire(time_t expires)
static int qemu_spice_display_add_client(int csock, int skipauth, int tls)
{
+#ifdef WIN32
+ csock = qemu_close_socket_osfhandle(csock);
+#endif
if (tls) {
return spice_server_add_ssl_client(spice_server, csock, skipauth);
} else {
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 16f8a67f7e..a98638729a 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -479,40 +479,27 @@ int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
return ret;
}
-
#undef close
-int qemu_close_wrap(int fd)
+int qemu_close_socket_osfhandle(int fd)
{
- int ret;
+ SOCKET s = _get_osfhandle(fd);
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;
- }
+ /*
+ * 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;
}
- ret = close(fd);
-
- if (s != INVALID_SOCKET && !SetHandleInformation((HANDLE)s, flags, flags)) {
+ if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
errno = EACCES;
return -1;
}
@@ -521,15 +508,33 @@ int qemu_close_wrap(int fd)
* 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 (close(fd) < 0 && errno != EBADF) {
+ return -1;
}
- if (s != INVALID_SOCKET) {
- ret = closesocket(s);
- if (ret < 0) {
- errno = socket_error();
- }
+ if (!SetHandleInformation((HANDLE)s, flags, flags)) {
+ errno = EACCES;
+ return -1;
+ }
+
+ return 0;
+}
+
+int qemu_close_wrap(int fd)
+{
+ SOCKET s = INVALID_SOCKET;
+ int ret = -1;
+
+ if (!fd_is_socket(fd)) {
+ return close(fd);
+ }
+
+ s = _get_osfhandle(fd);
+ qemu_close_socket_osfhandle(fd);
+
+ ret = closesocket(s);
+ if (ret < 0) {
+ errno = socket_error();
}
return ret;