Blame SOURCES/0071-remote-viewer-add-handler-for-SIGINT-signal.patch

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