From 212074c21dc84bba181c8ffde97a6a49b5d25675 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov <11535558+o-sdn-o@users.noreply.github.com> Date: Sat, 4 Oct 2025 19:57:18 +0500 Subject: [PATCH 1/2] Fix the SIGWINCH interrupt makes the write operation think its failed, and causes it to try again. xlink https://github.com/directvt/vtm/issues/819#issuecomment-3368223680 > When a window resize event is received (terminal generates WINDOW_BUFFER_SIZE_EVENT event when switching between alternate/normal buffer mode), the errno becomes EINTR which causes the write operation think its failed. potentially fixes PowerShell/Win32-OpenSSH#2275 --- contrib/win32/win32compat/console.c | 11 ----------- contrib/win32/win32compat/signal.c | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/contrib/win32/win32compat/console.c b/contrib/win32/win32compat/console.c index f34a8d19d40..12673ad3198 100644 --- a/contrib/win32/win32compat/console.c +++ b/contrib/win32/win32compat/console.c @@ -225,17 +225,6 @@ ConEnterRawMode() ScrollBottom = ConVisibleWindowHeight(); in_raw_mode = 1; - - /* - Consume and ignore the first WINDOW_BUFFER_SIZE_EVENT, as we've triggered it ourselves by updating the console settings above. - Not consuming this event can cause a race condition: the event can cause a write to the console to be printed twice as the - SIGWINCH interrupt makes the write operation think its failed, and causes it to try again. - */ - INPUT_RECORD peek_input; - int out_count = 0; - if (PeekConsoleInputW(GetConsoleInputHandle(), &peek_input, 1, &out_count) && peek_input.EventType == WINDOW_BUFFER_SIZE_EVENT) { - ReadConsoleInputW(GetConsoleInputHandle(), &peek_input, 1, &out_count); - } } /* Used to Uninitialize the Console */ diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index f61cdd882d8..e6eeda5cd53 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -230,7 +230,7 @@ sw_process_pending_signals() w32_raise(exp[i]); /* dont error EINTR for SIG_ALRM, */ /* sftp client is not expecting it */ - if (exp[i] != W32_SIGALRM) + if (exp[i] != W32_SIGALRM && exp[i] != W32_SIGWINCH) sig_int = TRUE; } else if (exp[i] == W32_SIGCHLD) /*if SIGCHLD is SIG_IGN, reap zombies*/ sw_cleanup_child_zombies(); From 811aa23b618616ada5c558b63730b12eb4b4dde4 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov <11535558+o-sdn-o@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:29:01 +0500 Subject: [PATCH 2/2] #2275: Add comments to the fix the SIGWINCH interrupt makes the write operation think its failed --- contrib/win32/win32compat/signal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index e6eeda5cd53..24560eceed9 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -228,8 +228,8 @@ sw_process_pending_signals() if (sigismember(&pending_tmp, exp[i])) { if (sig_handlers[exp[i]] != W32_SIG_IGN) { w32_raise(exp[i]); - /* dont error EINTR for SIG_ALRM, */ - /* sftp client is not expecting it */ + /* don't set errno=EINTR on SIGALRM, sftp client is not expecting it */ + /* don't set errno=EINTR on SIGWINCH in order to avoid breaking the sequence of waiting for completion of IO operations. */ if (exp[i] != W32_SIGALRM && exp[i] != W32_SIGWINCH) sig_int = TRUE; } else if (exp[i] == W32_SIGCHLD) /*if SIGCHLD is SIG_IGN, reap zombies*/