From: Szymon Lukasz <noh4...@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 <noh4...@gmail.com> Signed-off-by: Filip Hejsek <filip.hej...@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 4e2436b1968b5c513f7d4e84e010b0d4fb31a1b1..7cc45c3a274434020fe33b1ca0a4d839de994e97 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -431,4 +431,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 161f78c35c32fc03ad576d2bd8e91bdfe09b265d..d1b308d5f8051e99f12f4d32435a04e294060a10 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 51aeb2432e77eae7081c6945e21812acc71b5f37..db4bb9c88dade805bc98322c1a053c65e9e97f7e 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 @@ -121,6 +122,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.51.0