@@ -325,4 +325,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
@@ -34,6 +34,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"
@@ -146,7 +147,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 {
@@ -169,17 +170,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) {}
@@ -90,6 +90,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
@@ -111,6 +112,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)
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> --- include/qemu/main-loop.h | 4 ++++ ui/curses.c | 11 ++++++----- util/main-loop.c | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-)