diff options
-rw-r--r-- | include/sysemu/os-win32.h | 15 | ||||
-rw-r--r-- | ui/console.c | 3 | ||||
-rw-r--r-- | ui/dbus.c | 9 | ||||
-rw-r--r-- | ui/gtk.c | 7 | ||||
-rw-r--r-- | ui/sdl2.c | 16 | ||||
-rw-r--r-- | ui/spice-core.c | 29 | ||||
-rw-r--r-- | util/oslib-win32.c | 75 |
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; } @@ -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); @@ -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) @@ -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; |