revert: "fix(lifecycle): on Windows, CTRL_CLOSE kills Nvim mid-teardown"

Revert commit 5a71131282

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>
This commit is contained in:
Justin M. Keyes
2026-08-19 19:33:25 +02:00
parent 5a71131282
commit 2fea699b96
2 changed files with 7 additions and 24 deletions

View File

@@ -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);

View File

@@ -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)