From: Szymon Lukasz <noh4hss@gmail.com>
Block SIGWINCH, so it is delivered only via signalfd.
Install a handler that uses NotifierList to tell
interested parties about SIGWINCH delivery.
Signed-off-by: Szymon Lukasz <noh4hss@gmail.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
---
include/qemu/main-loop.h | 4 ++++
ui/curses.c | 11 ++++++-----
util/main-loop.c | 21 +++++++++++++++++++++
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 8c1241a2c1..ff41346b0b 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -449,4 +449,8 @@ typedef struct MainLoopPoll {
void main_loop_poll_add_notifier(Notifier *notify);
void main_loop_poll_remove_notifier(Notifier *notify);
+#ifndef _WIN32
+void sigwinch_add_notifier(Notifier *n);
+#endif
+
#endif
diff --git a/ui/curses.c b/ui/curses.c
index 161f78c35c..d1b308d5f8 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -33,6 +33,7 @@
#include <iconv.h>
#include "qapi/error.h"
+#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "ui/console.h"
#include "ui/input.h"
@@ -149,7 +150,7 @@ static void curses_resize(DisplayChangeListener *dcl,
}
#if !defined(_WIN32) && defined(SIGWINCH) && defined(KEY_RESIZE)
-static volatile sig_atomic_t got_sigwinch;
+static bool got_sigwinch;
static void curses_winch_check(void)
{
struct winsize {
@@ -172,17 +173,17 @@ static void curses_winch_check(void)
invalidate = 1;
}
-static void curses_winch_handler(int signum)
+static void curses_winch_handler(Notifier *n, void *data)
{
got_sigwinch = true;
}
static void curses_winch_init(void)
{
- struct sigaction old, winch = {
- .sa_handler = curses_winch_handler,
+ static Notifier n = {
+ .notify = curses_winch_handler
};
- sigaction(SIGWINCH, &winch, &old);
+ sigwinch_add_notifier(&n);
}
#else
static void curses_winch_check(void) {}
diff --git a/util/main-loop.c b/util/main-loop.c
index ad8645c30a..136886e4ee 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -100,6 +100,7 @@ static int qemu_signal_init(Error **errp)
sigaddset(&set, SIGIO);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGBUS);
+ sigaddset(&set, SIGWINCH);
/* SIGINT cannot be handled via signalfd, so that ^C can be used
* to interrupt QEMU when it is being run under gdb. SIGHUP and
* SIGTERM are also handled asynchronously, even though it is not
@@ -124,6 +125,26 @@ static int qemu_signal_init(Error **errp)
return 0;
}
+static NotifierList sigwinch_notifiers =
+ NOTIFIER_LIST_INITIALIZER(sigwinch_notifiers);
+
+static void sigwinch_handler(int signum)
+{
+ notifier_list_notify(&sigwinch_notifiers, NULL);
+}
+
+void sigwinch_add_notifier(Notifier *n)
+{
+ if (notifier_list_empty(&sigwinch_notifiers)) {
+ struct sigaction action = {
+ .sa_handler = sigwinch_handler,
+ };
+ sigaction(SIGWINCH, &action, NULL);
+ }
+
+ notifier_list_add(&sigwinch_notifiers, n);
+}
+
#else /* _WIN32 */
static int qemu_signal_init(Error **errp)
--
2.52.0