mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibLine: Unregister signal handlers on destruction
This fixes an issue that shows up as a nice crash when "^R<enter>^C", which is actually the event loop trying to call into a deleted object (the search editor).
This commit is contained in:
parent
d07ac4130f
commit
9b126a2250
Notes:
sideshowbarker
2024-07-18 23:58:35 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/9b126a22509 Pull-request: https://github.com/SerenityOS/serenity/pull/4839 Reviewed-by: https://github.com/tomuta
3 changed files with 27 additions and 10 deletions
|
@ -180,7 +180,7 @@ void Editor::set_default_keybinds()
|
|||
Editor::Editor(Configuration configuration)
|
||||
: m_configuration(move(configuration))
|
||||
{
|
||||
m_always_refresh = configuration.refresh_behaviour == Configuration::RefreshBehaviour::Eager;
|
||||
m_always_refresh = m_configuration.refresh_behaviour == Configuration::RefreshBehaviour::Eager;
|
||||
m_pending_chars = ByteBuffer::create_uninitialized(0);
|
||||
get_terminal_size();
|
||||
m_suggestion_display = make<XtermSuggestionDisplay>(m_num_lines, m_num_columns);
|
||||
|
@ -451,19 +451,24 @@ void Editor::initialize()
|
|||
for (auto& keybind : m_configuration.keybindings)
|
||||
register_key_input_callback(keybind);
|
||||
|
||||
Core::EventLoop::register_signal(SIGINT, [this](int) {
|
||||
interrupted();
|
||||
});
|
||||
if (m_configuration.m_signal_mode == Configuration::WithSignalHandlers) {
|
||||
m_signal_handlers.append(Core::EventLoop::register_signal(SIGINT, [this](int) {
|
||||
interrupted();
|
||||
}));
|
||||
|
||||
Core::EventLoop::register_signal(SIGWINCH, [this](int) {
|
||||
resized();
|
||||
});
|
||||
m_signal_handlers.append(Core::EventLoop::register_signal(SIGWINCH, [this](int) {
|
||||
resized();
|
||||
}));
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void Editor::interrupted()
|
||||
{
|
||||
if (m_is_searching)
|
||||
return m_search_editor->interrupted();
|
||||
|
||||
if (!m_is_editing)
|
||||
return;
|
||||
|
||||
|
@ -482,7 +487,7 @@ void Editor::interrupted()
|
|||
m_buffer.clear();
|
||||
m_is_editing = false;
|
||||
restore();
|
||||
m_notifier->set_event_mask(Core::Notifier::None);
|
||||
m_notifier->set_enabled(false);
|
||||
deferred_invoke([this](auto&) {
|
||||
remove_child(*m_notifier);
|
||||
m_notifier = nullptr;
|
||||
|
@ -503,7 +508,7 @@ void Editor::really_quit_event_loop()
|
|||
|
||||
m_returned_line = string;
|
||||
|
||||
m_notifier->set_event_mask(Core::Notifier::None);
|
||||
m_notifier->set_enabled(false);
|
||||
deferred_invoke([this](auto&) {
|
||||
remove_child(*m_notifier);
|
||||
m_notifier = nullptr;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <AK/Utf8View.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/DirIterator.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Notifier.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibLine/KeyCallbackMachine.h>
|
||||
|
@ -74,6 +75,10 @@ struct Configuration {
|
|||
NoEscapeSequences,
|
||||
NonInteractive,
|
||||
};
|
||||
enum SignalHandler {
|
||||
WithSignalHandlers,
|
||||
NoSignalHandlers,
|
||||
};
|
||||
|
||||
Configuration()
|
||||
{
|
||||
|
@ -88,11 +93,13 @@ struct Configuration {
|
|||
|
||||
void set(RefreshBehaviour refresh) { refresh_behaviour = refresh; }
|
||||
void set(OperationMode mode) { operation_mode = mode; }
|
||||
void set(SignalHandler mode) { m_signal_mode = mode; }
|
||||
void set(const KeyBinding& binding) { keybindings.append(binding); }
|
||||
|
||||
static Configuration from_config(const StringView& libname = "line");
|
||||
|
||||
RefreshBehaviour refresh_behaviour { RefreshBehaviour::Lazy };
|
||||
SignalHandler m_signal_mode { SignalHandler::WithSignalHandlers };
|
||||
OperationMode operation_mode { OperationMode::Unset };
|
||||
Vector<KeyBinding> keybindings;
|
||||
};
|
||||
|
@ -180,6 +187,8 @@ public:
|
|||
m_previous_num_columns = m_num_columns;
|
||||
get_terminal_size();
|
||||
m_suggestion_display->set_vt_size(m_num_lines, m_num_columns);
|
||||
if (m_is_searching)
|
||||
m_search_editor->resized();
|
||||
}
|
||||
|
||||
size_t cursor() const { return m_cursor; }
|
||||
|
@ -321,6 +330,8 @@ private:
|
|||
ASSERT(m_initialized);
|
||||
tcsetattr(0, TCSANOW, &m_default_termios);
|
||||
m_initialized = false;
|
||||
for (auto id : m_signal_handlers)
|
||||
Core::EventLoop::unregister_signal(id);
|
||||
}
|
||||
|
||||
const StringMetrics& current_prompt_metrics() const
|
||||
|
@ -462,6 +473,7 @@ private:
|
|||
|
||||
bool m_initialized { false };
|
||||
bool m_refresh_needed { false };
|
||||
Vector<int, 2> m_signal_handlers;
|
||||
|
||||
bool m_is_editing { false };
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ void Editor::enter_search()
|
|||
// Disable our own notifier so as to avoid interfering with the search editor.
|
||||
m_notifier->set_enabled(false);
|
||||
|
||||
m_search_editor = Editor::construct(Configuration { Configuration::Eager }); // Has anyone seen 'Inception'?
|
||||
m_search_editor = Editor::construct(Configuration { Configuration::Eager, Configuration::NoSignalHandlers }); // Has anyone seen 'Inception'?
|
||||
m_search_editor->initialize();
|
||||
add_child(*m_search_editor);
|
||||
|
||||
|
|
Loading…
Reference in a new issue