[virt-tools-list] [PATCH 1/3] remote-viewer: add handler for SIGINT signal
Francesco Giudici
fgiudici at redhat.com
Tue Nov 12 11:29:10 UTC 2019
When remote-viewer is started from terminal, CTRL-C sends a SIGINT
signal to the program causing immediate termination.
Catch the signal in order to properly shutdown remote-viewer once the
application is started.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1713311
Signed-off-by: Francesco Giudici <fgiudici at redhat.com>
---
src/virt-viewer-app.c | 79 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index da8cfa9..06e237b 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -36,6 +36,7 @@
#include <glib/gprintf.h>
#include <glib/gi18n.h>
#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -1756,6 +1757,74 @@ static gboolean opt_fullscreen = FALSE;
static gboolean opt_kiosk = FALSE;
static gboolean opt_kiosk_quit = FALSE;
+#ifndef G_OS_WIN32
+static int sigint_pipe[2];
+
+static void
+sigint_handler(int signum)
+{
+ int savedErrno;
+
+ g_return_if_fail(signum == SIGINT);
+
+ savedErrno = errno;
+ if (write(sigint_pipe[1], "x", 1) == -1 && errno != EAGAIN)
+ g_debug("SIGINT handler failure\n");
+ errno = savedErrno;
+}
+
+static void
+register_sigint_handler()
+{
+ int flags, i;
+ struct sigaction sa;
+
+ if (pipe(sigint_pipe) == -1)
+ goto err;
+
+ for (i = 0; i < 2; i++) {
+ flags = fcntl(sigint_pipe[i], F_GETFL);
+ if (flags == -1)
+ goto err;
+ flags |= O_NONBLOCK;
+ if (fcntl(sigint_pipe[i], F_SETFL, flags) == -1)
+ goto err;
+ }
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sa.sa_handler = sigint_handler;
+ if (sigaction(SIGINT, &sa, NULL) == -1)
+ goto err;
+
+ return;
+
+err:
+ g_debug("Cannot register SIGINT handler\n");
+}
+
+static gboolean
+sigint_cb(GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ VirtViewerApp *self = VIRT_VIEWER_APP(data);
+ VirtViewerAppPrivate *priv = self->priv;
+ gchar sbuf;
+
+ g_assert(condition == G_IO_IN);
+
+ g_debug("got SIGINT, quitting\n");
+ if (priv->started)
+ virt_viewer_app_quit(self);
+ else
+ exit(0);
+
+ g_io_channel_read_chars (source, &sbuf, 1, NULL, NULL);
+ return TRUE;
+}
+#endif
+
static void
title_maybe_changed(VirtViewerApp *self, GParamSpec* pspec G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
{
@@ -1766,10 +1835,20 @@ static void
virt_viewer_app_init(VirtViewerApp *self)
{
GError *error = NULL;
+#ifndef G_OS_WIN32
+ GIOChannel *sigint_channel = NULL;
+#endif
+
self->priv = virt_viewer_app_get_instance_private(self);
gtk_window_set_default_icon_name("virt-viewer");
+#ifndef G_OS_WIN32
+ register_sigint_handler();
+ sigint_channel = g_io_channel_unix_new(sigint_pipe[0]);
+ g_io_add_watch(sigint_channel, G_IO_IN, sigint_cb, self);
+#endif
+
self->priv->displays = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
self->priv->config = g_key_file_new();
self->priv->config_file = g_build_filename(g_get_user_config_dir(),
--
2.21.0
More information about the virt-tools-list
mailing list