From ba71f209af4eeef1c1855430eb777139e0b3e788 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 11 Sep 2017 14:21:07 +0800 Subject: [PATCH] Fork server to background when the client/server process receives SIGHUP Avoid losing the whole session when closing the terminal emulator of the client/server process, only the client will be removed and the server will be forked. --- src/main.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main.cc b/src/main.cc index 19a6d400..0108df17 100644 --- a/src/main.cc +++ b/src/main.cc @@ -53,7 +53,7 @@ struct startup_error : runtime_error }; inline void write_stdout(StringView str) { write(1, str); } -inline void write_stderr(StringView str) { write(2, str); } +inline void write_stderr(StringView str) { try { write(2, str); } catch (runtime_error&) {} } String runtime_directory() { @@ -337,6 +337,7 @@ void register_options() static Client* local_client = nullptr; static int local_client_exit = 0; +static sig_atomic_t sighup_raised = 0; static UserInterface* local_ui = nullptr; static bool convert_to_client_pending = false; @@ -412,8 +413,8 @@ std::unique_ptr create_local_ui(UIType ui_type) kak_assert(not local_ui); local_ui = this; m_old_sighup = set_signal_handler(SIGHUP, [](int) { - ClientManager::instance().remove_client(*local_client, false, -1); static_cast(local_ui)->on_sighup(); + sighup_raised = 1; }); m_old_sigtstp = set_signal_handler(SIGTSTP, [](int) { @@ -645,7 +646,14 @@ int run_server(StringView session, StringView server_init, client_manager.clear_window_trash(); buffer_manager.clear_buffer_trash(); - if (convert_to_client_pending) + if (sighup_raised) + { + ClientManager::instance().remove_client(*local_client, true, 0); + if (not client_manager.empty() and fork_server_to_background()) + return 0; + sighup_raised = 0; + } + else if (convert_to_client_pending) { String buffer_name = local_client->context().buffer().name(); String selections = selection_list_to_string(local_client->context().selections());