diff options
author | Takashi Yano <takashi.yano@nifty.ne.jp> | 2025-03-21 12:54:28 +0900 |
---|---|---|
committer | Takashi Yano <takashi.yano@nifty.ne.jp> | 2025-03-21 13:17:53 +0900 |
commit | 0bfd91d578632b9348d769d2bc8611d6e9493d3a (patch) | |
tree | 0cd13ccd41254884e43246b370517946878b92c8 | |
parent | 8e50c7af7c49819245739d6f626f6fecc394ef7f (diff) | |
download | newlib-0bfd91d578632b9348d769d2bc8611d6e9493d3a.zip newlib-0bfd91d578632b9348d769d2bc8611d6e9493d3a.tar.gz newlib-0bfd91d578632b9348d769d2bc8611d6e9493d3a.tar.bz2 |
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>
-rw-r--r-- | winsup/cygwin/fhandler/console.cc | 49 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/fhandler.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/release/3.6.1 | 5 |
3 files changed, 32 insertions, 26 deletions
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 |