msys2-runtime: console: tty::restore really restores the previous mode

Previously, tty::restore sets the console mode to a predetermined
console mode that is widely common for many non-cygwin console apps.
So, if a non-cygwin app that is started from cygwin process changes
the console mode and executes cygwin sub-process, the console mode
is changed to the predetermined mode rather than being restored the
original mode that is set by the non-cygwin app.
With this patch, the console mode is stored when a cygwin process is
started from non-cygwin app, then tty::restore restores the previous
console mode that is used by the previous non-cygwin app when the
cygwin app exits.

This is a companion of https://github.com/msys2/msys2-runtime/pull/269.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin 2025-03-21 17:51:22 +01:00
parent 30a68e6a73
commit 04202bd717
3 changed files with 189 additions and 6 deletions

View File

@ -0,0 +1,180 @@
From c1770e171505eb674626c2b7abf3403e6b4b7b79 Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Fri, 21 Mar 2025 13:58:23 +0900
Subject: [PATCH 41/N] Cygwin: console: tty::restore really restores the
previous mode
Previously, tty::restore sets the console mode to a predetermined
console mode that is widely common for many non-cygwin console apps.
So, if a non-cygwin app that is started from cygwin process changes
the console mode and executes cygwin sub-process, the console mode
is changed to the predetermined mode rather than being restored the
original mode that is set by the non-cygwin app.
With this patch, the console mode is stored when a cygwin process is
started from non-cygwin app, then tty::restore restores the previous
console mode that is used by the previous non-cygwin app when the
cygwin app exits.
Addresses: https://github.com/msys2/msys2-runtime/issues/268
Fixes: 3312f2d21f13 ("Cygwin: console: Redesign mode set strategy on close().")
Reported-by: Eu Pin Tien, Jeremy Drake <cygwin@jdrake.com>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Signed-off-by: Eu-Pin Tien <eu-pin.tien@diamond.ac.uk>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
winsup/cygwin/fhandler/console.cc | 49 ++++++++++++-------------
winsup/cygwin/local_includes/fhandler.h | 4 +-
winsup/cygwin/release/3.6.1 | 5 +++
3 files changed, 32 insertions(+), 26 deletions(-)
create mode 100644 winsup/cygwin/release/3.6.1
diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc
index da335b3..f162698 100644
--- a/winsup/cygwin/fhandler/console.cc
+++ b/winsup/cygwin/fhandler/console.cc
@@ -804,6 +804,9 @@ fhandler_console::rabuflen ()
return con_ra.rabuflen;
}
+static DWORD prev_input_mode_backup;
+static DWORD prev_output_mode_backup;
+
/* The function set_{in,out}put_mode() should be static so that they
can be called even after the fhandler_console instance is deleted. */
void
@@ -818,11 +821,11 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
GetConsoleMode (p->input_handle, &oflags);
DWORD flags = oflags
& (ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE);
- con.curr_input_mode = m;
switch (m)
{
case tty::restore:
- flags |= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+ flags = con.prev_input_mode;
+ con.prev_input_mode = prev_input_mode_backup;
break;
case tty::cygwin:
flags |= ENABLE_WINDOW_INPUT;
@@ -846,6 +849,12 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
flags |= ENABLE_PROCESSED_INPUT;
break;
}
+ if (con.curr_input_mode != tty::cygwin && m == tty::cygwin)
+ {
+ prev_input_mode_backup = con.prev_input_mode;
+ con.prev_input_mode = oflags;
+ }
+ con.curr_input_mode = m;
SetConsoleMode (p->input_handle, flags);
if (!(oflags & ENABLE_VIRTUAL_TERMINAL_INPUT)
&& (flags & ENABLE_VIRTUAL_TERMINAL_INPUT)
@@ -868,10 +877,11 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
if (con.orig_virtual_terminal_processing_mode)
flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
WaitForSingleObject (p->output_mutex, mutex_timeout);
- con.curr_output_mode = m;
switch (m)
{
case tty::restore:
+ flags = con.prev_output_mode;
+ con.prev_output_mode = prev_output_mode_backup;
break;
case tty::cygwin:
if (wincap.has_con_24bit_colors () && !con_is_legacy)
@@ -883,6 +893,12 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
flags |= DISABLE_NEWLINE_AUTO_RETURN;
break;
}
+ if (con.curr_output_mode != tty::cygwin && m == tty::cygwin)
+ {
+ prev_output_mode_backup = con.prev_output_mode;
+ GetConsoleMode (p->output_handle, &con.prev_output_mode);
+ }
+ con.curr_output_mode = m;
acquire_attach_mutex (mutex_timeout);
DWORD resume_pid = attach_console (con.owner);
SetConsoleMode (p->output_handle, flags);
@@ -916,7 +932,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p)
/* Cleaning-up console mode for non-cygwin app. */
/* conmode can be tty::restore when non-cygwin app is
exec'ed from login shell. */
- tty::cons_mode conmode = cons_mode_on_close (p);
+ tty::cons_mode conmode = cons_mode_on_close ();
set_output_mode (conmode, ti, p);
set_input_mode (conmode, ti, p);
set_disable_master_thread (con.owner == GetCurrentProcessId ());
@@ -1978,9 +1994,8 @@ fhandler_console::close (int flag)
if (shared_console_info[unit] && myself->ppid == 1
&& (dev_t) myself->ctty == get_device ())
{
- tty::cons_mode conmode = cons_mode_on_close (&handle_set);
- set_output_mode (conmode, &get_ttyp ()->ti, &handle_set);
- set_input_mode (conmode, &get_ttyp ()->ti, &handle_set);
+ set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
+ set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set);
set_disable_master_thread (true, this);
}
@@ -4687,26 +4702,10 @@ fhandler_console::fstat (struct stat *st)
}
tty::cons_mode
-fhandler_console::cons_mode_on_close (handle_set_t *p)
+fhandler_console::cons_mode_on_close ()
{
- const _minor_t unit = p->unit;
-
if (myself->ppid != 1) /* Execed from normal cygwin process. */
return tty::cygwin;
- if (!process_alive (con.owner)) /* The Master process already died. */
- return tty::restore;
- if (con.owner == GetCurrentProcessId ()) /* Master process */
- return tty::restore;
-
- PROCESS_BASIC_INFORMATION pbi;
- NTSTATUS status =
- NtQueryInformationProcess (GetCurrentProcess (), ProcessBasicInformation,
- &pbi, sizeof (pbi), NULL);
- if (NT_SUCCESS (status)
- && con.owner == (DWORD) pbi.InheritedFromUniqueProcessId)
- /* The parent is the stub process. */
- return tty::restore;
-
- return tty::native; /* Otherwise */
+ return tty::restore; /* otherwise, restore */
}
diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h
index b00a1a1..8c71d84 100644
--- a/winsup/cygwin/local_includes/fhandler.h
+++ b/winsup/cygwin/local_includes/fhandler.h
@@ -2146,6 +2146,8 @@ class dev_console
bool disable_master_thread;
tty::cons_mode curr_input_mode;
tty::cons_mode curr_output_mode;
+ DWORD prev_input_mode;
+ DWORD prev_output_mode;
bool master_thread_suspended;
int num_processed; /* Number of input events in the current input buffer
already processed by cons_master_thread(). */
@@ -2366,7 +2368,7 @@ private:
void setup_pcon_hand_over ();
static void pcon_hand_over_proc ();
- static tty::cons_mode cons_mode_on_close (handle_set_t *);
+ static tty::cons_mode cons_mode_on_close ();
friend tty_min * tty_list::get_cttyp ();
};
diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1
new file mode 100644
index 0000000..0b54b5f
--- /dev/null
+++ b/winsup/cygwin/release/3.6.1
@@ -0,0 +1,5 @@
+Fixes:
+------
+
+- Console mode is really restored to the previous mode.
+ Addresses: https://github.com/msys2/msys2-runtime/issues/268

View File

@ -4,7 +4,7 @@
pkgbase=msys2-runtime pkgbase=msys2-runtime
pkgname=('msys2-runtime' 'msys2-runtime-devel') pkgname=('msys2-runtime' 'msys2-runtime-devel')
pkgver=3.6.0 pkgver=3.6.0
pkgrel=1 pkgrel=2
pkgdesc="Cygwin POSIX emulation engine" pkgdesc="Cygwin POSIX emulation engine"
arch=('x86_64') arch=('x86_64')
url="https://www.cygwin.com/" url="https://www.cygwin.com/"
@ -69,9 +69,10 @@ source=('msys2-runtime'::git://sourceware.org/git/newlib-cygwin.git#tag=cygwin-$
0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch 0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch
0038-uname-report-msys2-runtime-commit-hash-too.patch 0038-uname-report-msys2-runtime-commit-hash-too.patch
0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch 0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch
0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch) 0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch
0041-Cygwin-console-tty-restore-really-restores-the-previ.patch)
sha256sums=('89d856fbf9f8d753a644651f95ccd769a43135d93b1bc322582f6fb87ebf4cea' sha256sums=('89d856fbf9f8d753a644651f95ccd769a43135d93b1bc322582f6fb87ebf4cea'
'fd9705555296df0bb56be1976b29f3f244829d17face92f9d1a9b04edd227dbd' '564998f09ca51148aba183e52ac8e78169c98d3e1a92e163f56a00cd7c840a68'
'5945b95c6b3caf18cc8356802e9af1770746a76c27d0931b897d48d072603fcf' '5945b95c6b3caf18cc8356802e9af1770746a76c27d0931b897d48d072603fcf'
'8f2def0add5397487e2470fd7219bd80233e4d43e9f78d92d042907fede0570a' '8f2def0add5397487e2470fd7219bd80233e4d43e9f78d92d042907fede0570a'
'0cebee2ed462579029512e46e4bd3c7bddd4d92823ef69803a938007c66d2843' '0cebee2ed462579029512e46e4bd3c7bddd4d92823ef69803a938007c66d2843'
@ -111,7 +112,8 @@ sha256sums=('89d856fbf9f8d753a644651f95ccd769a43135d93b1bc322582f6fb87ebf4cea'
'4850fd4c82bc090726f57d1a1c562cb5a5e654172444ee4eba6abe3021880abb' '4850fd4c82bc090726f57d1a1c562cb5a5e654172444ee4eba6abe3021880abb'
'eafc8a892ad6cd89b2d0c2ae6e788ede27c42501b82650d569a95671b0046fa3' 'eafc8a892ad6cd89b2d0c2ae6e788ede27c42501b82650d569a95671b0046fa3'
'384001ba02f597aad992624aed9d63cc7f1c70af842b09eac6ea628aa24947ad' '384001ba02f597aad992624aed9d63cc7f1c70af842b09eac6ea628aa24947ad'
'278461f45bf55fa054a7f59feb87bf6a4ed251b03bf91edc12c088c85418f4e3') '278461f45bf55fa054a7f59feb87bf6a4ed251b03bf91edc12c088c85418f4e3'
'ff3c524f8802b79d268ad94ba7d0c2684741dc047c1ef5781081b02218333252')
# Helper macros to help make tasks easier # # Helper macros to help make tasks easier #
apply_patch_with_msg() { apply_patch_with_msg() {
@ -188,7 +190,8 @@ prepare() {
0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch \ 0037-Avoid-sharing-cygheaps-across-Cygwin-versions.patch \
0038-uname-report-msys2-runtime-commit-hash-too.patch \ 0038-uname-report-msys2-runtime-commit-hash-too.patch \
0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \ 0039-fixup-Instead-of-creating-Cygwin-symlinks-use-deep-c.patch \
0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch 0040-Cygwin-Adjust-CWD-magic-to-accommodate-for-the-lates.patch \
0041-Cygwin-console-tty-restore-really-restores-the-previ.patch
} }
build() { build() {

View File

@ -1 +1 @@
7878787624144cd3b9cbd8a41b25d7d266b7173c c1770e171505eb674626c2b7abf3403e6b4b7b79