From 2fea699b9695b95a55b2b714b472417dec991a71 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 19 Aug 2026 19:33:25 +0200 Subject: [PATCH] revert: "fix(lifecycle): on Windows, CTRL_CLOSE kills Nvim mid-teardown" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert commit 5a71131282010225745d94b068a95fc7eb4db2a9 That change seems good in theory, but it consistently causes 2 failures FAILED …/api/vim_spec.lua @ 3213: API nvim_list_chans, nvim_get_chan_info stream=job :terminal channel Expected values to be equal. Expected: { argv = { "D:/a/neovim/neovim/build/bin/nvim.exe", "-u", "NONE", "-i", "NONE" }, exitcode = 129, id = 4, mode = "terminal", pty = "?", stream = "job" ... } Actual: { argv = { "D:/a/neovim/neovim/build/bin/nvim.exe", "-u", "NONE", "-i", "NONE" }, exitcode = 143, id = 4, mode = "terminal", pty = "?", stream = "job", ... } stack traceback: …/api/vim_spec.lua:3257: in function <…/api/vim_spec.lua:3213> FAILED …/terminal/tui_spec.lua @ 3669: TUI exits immediately when stdin is closed …/terminal/tui_spec.lua:3669: retry() attempts: 69 Expected values to be equal. Expected: vim.NIL Actual: { name = "nvim.exe", pid = 2256, ppid = 8200, } stack traceback: …/testutil.lua:98: in function 'retry' …/terminal/tui_spec.lua:3669: in function <…/terminal/tui_spec.lua:3656> --- src/nvim/os/signal.c | 26 +++----------------------- test/functional/terminal/tui_spec.lua | 5 ++++- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index 311344cf06..7f9cdf4ce5 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -66,32 +66,12 @@ void signal_init(void) signal_start(); } -#ifdef MSWIN -/// Swallows console control events during shutdown. -static BOOL WINAPI signal_ctrl_handler(DWORD type) -{ - switch (type) { - case CTRL_CLOSE_EVENT: - // Returning true is not enough; Windows terminates the process as soon as the handler returns. - // So block instead, like libuv's own handler does, and let the exit finish. - Sleep(INFINITE); - return true; - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - return true; - default: - return false; - } -} -#endif - /// During shutdown, we don't want the default actions of these signals. +/// +/// Note: Windows still has the race. See 5a7113128201 for attempted fix. static void signal_ignore_deadly(void) { -#ifdef MSWIN - // Handlers run in reverse registration order, so this one runs before libuv's. - SetConsoleCtrlHandler(signal_ctrl_handler, true); -#else +#ifndef MSWIN signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 1c8e73e5e6..ead5f55e35 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -3669,7 +3669,10 @@ describe('TUI', function() retry(nil, 2000, function() eq(vim.NIL, api.nvim_get_proc(pid)) end) - screen:expect({ any = '%[Process exited 1%]' }) + -- On Windows the console terminates the child with STATUS_CONTROL_C_EXIT (-1073741510). + screen:expect({ + any = is_os('win') and '%[Process exited %-?%d+%]' or '%[Process exited 1%]', + }) -- Closing stdin must skip the DA1 wait. t.assert_nolog('timed out waiting for DA1 response', testlog, 100) end)