|
|
d8475c |
From a724dff8a3ba6d5e8d3baf79b0041b1b73bd190d Mon Sep 17 00:00:00 2001
|
|
|
d8475c |
From: Francesco Giudici <fgiudici@redhat.com>
|
|
|
d8475c |
Date: Fri, 17 Jan 2020 16:06:13 +0100
|
|
|
d8475c |
Subject: [PATCH] remote-viewer: add handler for SIGINT signal
|
|
|
d8475c |
MIME-Version: 1.0
|
|
|
d8475c |
Content-Type: text/plain; charset=UTF-8
|
|
|
d8475c |
Content-Transfer-Encoding: 8bit
|
|
|
d8475c |
|
|
|
d8475c |
When remote-viewer is started from terminal, CTRL-C sends a SIGINT
|
|
|
d8475c |
signal to the program causing immediate termination. On linux clients
|
|
|
d8475c |
usb redirected devices are left without any kernel driver attached,
|
|
|
d8475c |
causing them to appear as no more available to the host.
|
|
|
d8475c |
Add a SIGINT handler to allow a clean exit, in particular to allow
|
|
|
d8475c |
the kernel to attach back the host driver.
|
|
|
d8475c |
The issue is present on linux only.
|
|
|
d8475c |
|
|
|
d8475c |
To perform usb device redirection, virt-viewer leverages spice-gtk
|
|
|
d8475c |
library, which in turn relies on usbredir library, which uses libusb.
|
|
|
d8475c |
In order to take control of the usb device the auto-loaded kernel
|
|
|
d8475c |
driver must be detached. This is achieved (in the very end) with
|
|
|
d8475c |
libusb_detach_kernel_driver(). Then the device interfaces can be claimed
|
|
|
d8475c |
with libusb_claim_interface() and get in control to the application.
|
|
|
d8475c |
During normal application termination, the usb channel is teared down,
|
|
|
d8475c |
performing a reset of the usb device and giving back the control of the
|
|
|
d8475c |
device to the kernel (libusb_attach_kernel_driver()).
|
|
|
d8475c |
If the application quits without doing this, the device interfaces will
|
|
|
d8475c |
end up with no driver attached, making them not usable in the host
|
|
|
d8475c |
system.
|
|
|
d8475c |
|
|
|
d8475c |
Note that enabling libusb_set_auto_detach_kernel_driver() does not solve
|
|
|
d8475c |
the issue, as this is just a convenient API from libusb: libusb will
|
|
|
d8475c |
take care of detaching/attaching the driver to the interfaces of the usb
|
|
|
d8475c |
device each time a call to libusb_release_interface() and
|
|
|
d8475c |
libusb_claim_interface() is performed. An unexpected quit of the
|
|
|
d8475c |
application will skip the libusb_release_interface() call too, leaving
|
|
|
d8475c |
the interfaces without any driver attached.
|
|
|
d8475c |
|
|
|
d8475c |
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1713311
|
|
|
d8475c |
|
|
|
d8475c |
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
d8475c |
Signed-off-by: Francesco Giudici <fgiudici@redhat.com>
|
|
|
d8475c |
---
|
|
|
d8475c |
src/virt-viewer-app.c | 25 +++++++++++++++++++++++++
|
|
|
d8475c |
1 file changed, 25 insertions(+)
|
|
|
d8475c |
|
|
|
d8475c |
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
|
|
|
d8475c |
index da8cfa9..343b1af 100644
|
|
|
d8475c |
--- a/src/virt-viewer-app.c
|
|
|
d8475c |
+++ b/src/virt-viewer-app.c
|
|
|
d8475c |
@@ -37,6 +37,10 @@
|
|
|
d8475c |
#include <glib/gi18n.h>
|
|
|
d8475c |
#include <errno.h>
|
|
|
d8475c |
|
|
|
d8475c |
+#ifndef G_OS_WIN32
|
|
|
d8475c |
+#include <glib-unix.h>
|
|
|
d8475c |
+#endif
|
|
|
d8475c |
+
|
|
|
d8475c |
#ifdef HAVE_SYS_SOCKET_H
|
|
|
d8475c |
#include <sys/socket.h>
|
|
|
d8475c |
#endif
|
|
|
d8475c |
@@ -1756,6 +1760,23 @@ static gboolean opt_fullscreen = FALSE;
|
|
|
d8475c |
static gboolean opt_kiosk = FALSE;
|
|
|
d8475c |
static gboolean opt_kiosk_quit = FALSE;
|
|
|
d8475c |
|
|
|
d8475c |
+#ifndef G_OS_WIN32
|
|
|
d8475c |
+static gboolean
|
|
|
d8475c |
+sigint_cb(gpointer data)
|
|
|
d8475c |
+{
|
|
|
d8475c |
+ VirtViewerApp *self = VIRT_VIEWER_APP(data);
|
|
|
d8475c |
+ VirtViewerAppPrivate *priv = self->priv;
|
|
|
d8475c |
+
|
|
|
d8475c |
+ g_debug("got SIGINT, quitting\n");
|
|
|
d8475c |
+ if (priv->started)
|
|
|
d8475c |
+ virt_viewer_app_quit(self);
|
|
|
d8475c |
+ else
|
|
|
d8475c |
+ exit(EXIT_SUCCESS);
|
|
|
d8475c |
+
|
|
|
d8475c |
+ return G_SOURCE_CONTINUE;
|
|
|
d8475c |
+}
|
|
|
d8475c |
+#endif
|
|
|
d8475c |
+
|
|
|
d8475c |
static void
|
|
|
d8475c |
title_maybe_changed(VirtViewerApp *self, GParamSpec* pspec G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
|
|
|
d8475c |
{
|
|
|
d8475c |
@@ -1770,6 +1791,10 @@ virt_viewer_app_init(VirtViewerApp *self)
|
|
|
d8475c |
|
|
|
d8475c |
gtk_window_set_default_icon_name("virt-viewer");
|
|
|
d8475c |
|
|
|
d8475c |
+#ifndef G_OS_WIN32
|
|
|
d8475c |
+ g_unix_signal_add (SIGINT, sigint_cb, self);
|
|
|
d8475c |
+#endif
|
|
|
d8475c |
+
|
|
|
d8475c |
self->priv->displays = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
|
|
d8475c |
self->priv->config = g_key_file_new();
|
|
|
d8475c |
self->priv->config_file = g_build_filename(g_get_user_config_dir(),
|
|
|
d8475c |
--
|
|
|
d8475c |
2.26.0
|
|
|
d8475c |
|