Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
From 3d8be6bd4d3d9086c57856cf80c03258fdd16327 Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Tue, 3 Mar 2026 22:18:22 +0900
Subject: [PATCH 49/N] Cygwin: pty: Fix nat pipe hand-over when pcon is
disabled

The nat pipe ownership hand-over mechanism relies on the console
process list - the set of processes attached to a console, enumerable
via `GetConsoleProcessList()`. For non-cygwin process in pcon_activated
case, this list contains all processes attached to the pseudo console.
Otherwise, it contains all processes attached to the invisible console.

04f386e9af (Cygwin: console: Inherit pcon hand over from parent pty,
2024-10-31) added a last-resort fallback in `get_winpid_to_hand_over()`
that hands nat pipe ownership to any process in the console process
list, including Cygwin processes. This fallback is needed when a
Cygwin process on the pseudo console (that might be exec'ed from non-
cygwin process) must take over management of an active pseudo console
after the original owner exits.

When the pseudo console is disabled, this fallback incorrectly finds a
Cygwin process (such as the shell) and assigns it nat pipe ownership,
because both the original nat pipe owner and the shell are assosiated
with the same invisible console. Since there is no console for that
process to manage, ownership never gets released, input stays stuck on
the nat pipe.

Only the third (last-resort) call in the cascade needs guarding: the
first two calls filter for native (non-Cygwin) processes via the `nat`
parameter, and handing ownership to another native process is fine
regardless of pcon state. It is only the fallback to Cygwin processes
that is dangerous without an active pseudo console.

Guard the fallback with a `pcon_activated` check, since handing nat
pipe ownership to a Cygwin process only makes sense when there is an
active pseudo console for it to manage.

Fixes: 04f386e9af99 ("Cygwin: console: Inherit pcon hand over from parent pty")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cherry-picked-from: 699c6892f1 (Cygwin: pty: Fix nat pipe hand-over when pcon is disabled, 2026-03-03)
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/pty.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index 90f5867..e07bbfe 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -3559,7 +3559,7 @@ fhandler_pty_slave::get_winpid_to_hand_over (tty *ttyp,
if (!switch_to)
switch_to = get_console_process_id (current_pid,
false, true, false, true);
- if (!switch_to)
+ if (!switch_to && ttyp->pcon_activated)
switch_to = get_console_process_id (current_pid,
false, false, false, false);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From a0f8f2baa5454daaa3d751ab07bf0fee205c2b13 Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Tue, 24 Mar 2026 11:25:40 +0900
Subject: [PATCH 50/N] Cygwin: console: Release pipe_sw_mutex in
pcon_hand_over_proc()

Currently, pipe_sw_mutex is held in the process which is running
in console inherited from pseudo console until the process ends.
Due to this behaviour, the process may cause deadlock when it
attempts to acquire input_mutex in set_input_mode() called via
close_ctty(). This deadlock occurs because the pty master
acquire input_mutex first and acquire pipe_sw_mutex next while
the process exiting acquire pipe_sw_mutex first.

To avoid this deadlock, this patch releases pipe_sw_mutex in
pcon_hand_over_proc(). In addition, pointless pipe_sw_mutex
acquire/release is drppped in pcon_hand_over_proc().

Fixes: 04f386e9af99 ("Cygwin: console: Inherit pcon hand over from parent pty")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Cherry-picked-from: 9ef8e3ad3b (Cygwin: console: Release pipe_sw_mutex in pcon_hand_over_proc(), 2026-03-24)
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/console.cc | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
index 831df4f..9e11611 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -1946,8 +1946,6 @@ fhandler_console::pcon_hand_over_proc (void)
char buf[MAX_PATH];
shared_name (buf, PIPE_SW_MUTEX, parent_pty);
HANDLE mtx = OpenMutex (MAXIMUM_ALLOWED, FALSE, buf);
- WaitForSingleObject (mtx, INFINITE);
- ReleaseMutex (mtx);
DWORD res = WaitForSingleObject (mtx, INFINITE);
if (res == WAIT_OBJECT_0 || res == WAIT_ABANDONED)
{
@@ -1958,8 +1956,7 @@ fhandler_console::pcon_hand_over_proc (void)
}
else
system_printf("Acquiring pcon_ho_mutex failed.");
- /* Do not release the mutex.
- Hold onto the mutex until this process completes. */
+ ReleaseMutex (mtx);
}

bool
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
From 79ae2b09ed0b2dd826a333857246e7cb963922d8 Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Sat, 28 Mar 2026 19:59:29 +0900
Subject: [PATCH 51/N] Cygwin: pty: Fix input transfer when multiple
non-cygwin apps exist

Cygwin maintains POSIX line discipline for its own processes:
input goes through `line_edit()` before reaching the reading process.
Native (non-Cygwin) processes must not receive line-edited input;
they expect raw console input instead. To support both, the PTY keeps
two independent pipe pairs for input: a "cyg" pipe for Cygwin processes
and a "nat" pipe for native ones. The runtime switches between the two
as the foreground process changes.

The PTY tracks which process "owns" the nat pipe session via the
shared-memory field `nat_pipe_owner_pid`. Only one process is the
owner at any time. When `setup_for_non_cygwin_app()` finds that the
current owner is still alive, it leaves ownership with that process
rather than claiming it for the new one.

This means that a Cygwin-spawned native process can go through
`cleanup_for_non_cygwin_app()` without being the nat pipe owner.
Before this fix, that cleanup called `transfer_input(to_cyg)`
unconditionally, draining the pseudo console's input buffer even
though another process still owned the session. Keystrokes that the
user had typed were moved to the cyg pipe prematurely, so the actual
owner found an empty console input buffer and appeared to lose all
input.

When looking for the next owner of the console in
`cleanup_for_non_cygwin_app()` (via `get_winpid_to_hand_over()`),
and when transferring the input back to the cyg pipe, guard both with
a `nat_pipe_owner_self()` check so that only the actual owner performs
these operations. Non-owner processes skip straight to detaching from
the pseudo console without disturbing the input buffer.

Fixes: f9542a2e8e75 ("Cygwin: pty: Re-fix the last bug regarding nat-pipe.")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Applied-from: https://inbox.sourceware.org/cygwin-patches/20260328110050.1928-1-takashi.yano@nifty.ne.jp/
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/pty.cc | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index e07bbfe..387fa17 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -4140,16 +4140,19 @@ fhandler_pty_slave::cleanup_for_non_cygwin_app (handle_set_t *p, tty *ttyp,
{
ttyp->wait_fwd ();
WaitForSingleObject (p->pipe_sw_mutex, INFINITE);
- DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
- if ((!switch_to && (ttyp->pcon_activated || stdin_is_ptys))
- && ttyp->pty_input_state_eq (tty::to_nat))
+ if (nat_pipe_owner_self (ttyp->nat_pipe_owner_pid))
{
- WaitForSingleObject (p->input_mutex, mutex_timeout);
- acquire_attach_mutex (mutex_timeout);
- transfer_input (tty::to_cyg, p->from_master_nat, ttyp,
- p->input_available_event);
- release_attach_mutex ();
- ReleaseMutex (p->input_mutex);
+ DWORD switch_to = get_winpid_to_hand_over (ttyp, force_switch_to);
+ if ((!switch_to && (ttyp->pcon_activated || stdin_is_ptys))
+ && ttyp->pty_input_state_eq (tty::to_nat))
+ {
+ WaitForSingleObject (p->input_mutex, mutex_timeout);
+ acquire_attach_mutex (mutex_timeout);
+ transfer_input (tty::to_cyg, p->from_master_nat, ttyp,
+ p->input_available_event);
+ release_attach_mutex ();
+ ReleaseMutex (p->input_mutex);
+ }
}
if (ttyp->pcon_activated)
close_pseudoconsole (ttyp, force_switch_to);
50 changes: 50 additions & 0 deletions msys2-runtime/0052-Cygwin-console-Fix-master-thread.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
From 10aff7d8f7857e1385025d5b44aec6402543aa6e Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Sat, 28 Mar 2026 19:55:45 +0900
Subject: [PATCH 52/N] Cygwin: console: Fix master thread

In Windows 11, key event with wRepeatCount == 0 is fixed-up to
wRepeatCount == 1 in conhost.exe.
https://github.com/microsoft/terminal/blob/v1.25.622.0/src/host/inputBuffer.cpp#L406

The console master thread (`cons_master_thread`) reads INPUT_RECORDs
from the console input buffer, processes signal-generating events,
and writes the remaining records back. After the writeback, it peeks
the buffer and uses `inrec_eq()` to verify that conhost stored the
records faithfully. On Windows 11, conhost normalizes `wRepeatCount`
from 0 to 1 on readback, causing `inrec_eq()` to report a mismatch
and triggering an unnecessary fixup path. Treat 0 and 1 as equivalent
for comparison purposes.

Addresses: https://github.com/git-for-windows/git/issues/5632
Fixes: ff4440fcf768 ("Cygwin: console: Introduce new thread which handles input signal.")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/console.cc | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
index 9e11611..80d6e34 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -318,9 +318,17 @@ inrec_eq (const INPUT_RECORD *a, const INPUT_RECORD *b, DWORD n)
written event. Therefore they are ignored. */
const KEY_EVENT_RECORD *ak = &a[i].Event.KeyEvent;
const KEY_EVENT_RECORD *bk = &b[i].Event.KeyEvent;
+ /* On Windows 11, conhost normalizes wRepeatCount from 0 to 1
+ on readback. Treat them as equivalent for comparison. */
+ WORD r1 = ak->wRepeatCount;
+ WORD r2 = bk->wRepeatCount;
+ if (r1 == 0)
+ r1 = 1;
+ if (r2 == 0)
+ r2 = 1;
if (ak->bKeyDown != bk->bKeyDown
|| ak->uChar.UnicodeChar != bk->uChar.UnicodeChar
- || ak->wRepeatCount != bk->wRepeatCount)
+ || r1 != r2)
return false;
}
else if (a[i].EventType == MOUSE_EVENT)
Loading
Loading