|
| 1 | +From 463ebcdca8feee7e92a2629fa3e0efbc6d28dc4a Mon Sep 17 00:00:00 2001 |
| 2 | +From: Takashi Yano < [email protected]> |
| 3 | +Date: Mon, 3 Mar 2025 15:31:23 +0900 |
| 4 | +Subject: [PATCH 55/N] Cygwin: console: Redesign mode set strategy on close(). |
| 5 | + |
| 6 | +The required console mode for a non-cygwin process is different from |
| 7 | +that for a cygwin process. There are currently three modes: tty::cygwin, |
| 8 | +tty::native, and tty::restore. The latter two are for the non-cygwin |
| 9 | +processes. tty::restore is the mode for the non-cygwin processes that |
| 10 | +started the cygwin process, used to restore the previous behaviour. |
| 11 | +tty::native is the mode that reflects some terminfo flags. The issue |
| 12 | +below is caused because the console mode fails to be restored to the |
| 13 | +previous console mode used by cmd.exe. |
| 14 | +This patch redesigns the strategy to determine which mode should be |
| 15 | +set on console close() to fix all similar problems. Previously, the |
| 16 | +number of handle count is used to determine the appropriate console |
| 17 | +mode. However, the handle count seems uncertain for that purpose. |
| 18 | +In the new design, the relation ship between the master process and |
| 19 | +the process that is about to close the console is mainly used. This |
| 20 | +can provide more certain result than previous one. |
| 21 | + |
| 22 | +Addresses: https://github.com/microsoft/git/issues/730 |
| 23 | +Backported-from: 3312f2d21f (Cygwin: console: Redesign mode set strategy on close()., 2025-03-03) |
| 24 | +Fixes: 30d266947842 ("Cygwin: console: Fix clean up conditions in close()") |
| 25 | +Reported-by: Mike Marcelais, Johannes Schindelin < [email protected]> |
| 26 | +Signed-off-by: Takashi Yano < [email protected]> |
| 27 | +Signed-off-by: Johannes Schindelin < [email protected]> |
| 28 | +--- |
| 29 | + winsup/cygwin/fhandler/console.cc | 47 ++++++++++++++++--------- |
| 30 | + winsup/cygwin/local_includes/fhandler.h | 1 + |
| 31 | + 2 files changed, 32 insertions(+), 16 deletions(-) |
| 32 | + |
| 33 | +diff --git a/winsup/cygwin/fhandler/console.cc b/winsup/cygwin/fhandler/console.cc |
| 34 | +index 2651e49..b095afa 100644 |
| 35 | +--- a/winsup/cygwin/fhandler/console.cc |
| 36 | ++++ b/winsup/cygwin/fhandler/console.cc |
| 37 | +@@ -916,8 +916,7 @@ fhandler_console::cleanup_for_non_cygwin_app (handle_set_t *p) |
| 38 | + /* Cleaning-up console mode for non-cygwin app. */ |
| 39 | + /* conmode can be tty::restore when non-cygwin app is |
| 40 | + exec'ed from login shell. */ |
| 41 | +- tty::cons_mode conmode = |
| 42 | +- (con.owner == GetCurrentProcessId ()) ? tty::restore : tty::cygwin; |
| 43 | ++ tty::cons_mode conmode = cons_mode_on_close (p); |
| 44 | + set_output_mode (conmode, ti, p); |
| 45 | + set_input_mode (conmode, ti, p); |
| 46 | + set_disable_master_thread (con.owner == GetCurrentProcessId ()); |
| 47 | +@@ -1976,22 +1975,13 @@ fhandler_console::close () |
| 48 | + |
| 49 | + acquire_output_mutex (mutex_timeout); |
| 50 | + |
| 51 | +- if (shared_console_info[unit] && !myself->cygstarted |
| 52 | ++ if (shared_console_info[unit] && myself->ppid == 1 |
| 53 | + && (dev_t) myself->ctty == get_device ()) |
| 54 | + { |
| 55 | +- /* Restore console mode if this is the last closure. */ |
| 56 | +- OBJECT_BASIC_INFORMATION obi; |
| 57 | +- NTSTATUS status; |
| 58 | +- status = NtQueryObject (get_handle (), ObjectBasicInformation, |
| 59 | +- &obi, sizeof obi, NULL); |
| 60 | +- if (NT_SUCCESS (status) |
| 61 | +- && obi.HandleCount == (con.owner == GetCurrentProcessId () ? 2 : 3)) |
| 62 | +- { |
| 63 | +- /* Cleaning-up console mode for cygwin apps. */ |
| 64 | +- set_output_mode (tty::restore, &get_ttyp ()->ti, &handle_set); |
| 65 | +- set_input_mode (tty::restore, &get_ttyp ()->ti, &handle_set); |
| 66 | +- set_disable_master_thread (true, this); |
| 67 | +- } |
| 68 | ++ tty::cons_mode conmode = cons_mode_on_close (&handle_set); |
| 69 | ++ set_output_mode (conmode, &get_ttyp ()->ti, &handle_set); |
| 70 | ++ set_input_mode (conmode, &get_ttyp ()->ti, &handle_set); |
| 71 | ++ set_disable_master_thread (true, this); |
| 72 | + } |
| 73 | + |
| 74 | + if (shared_console_info[unit] && con.owner == GetCurrentProcessId ()) |
| 75 | +@@ -4690,3 +4680,28 @@ fhandler_console::fstat (struct stat *st) |
| 76 | + } |
| 77 | + return 0; |
| 78 | + } |
| 79 | ++ |
| 80 | ++tty::cons_mode |
| 81 | ++fhandler_console::cons_mode_on_close (handle_set_t *p) |
| 82 | ++{ |
| 83 | ++ const _minor_t unit = p->unit; |
| 84 | ++ |
| 85 | ++ if (myself->ppid != 1) /* Execed from normal cygwin process. */ |
| 86 | ++ return tty::cygwin; |
| 87 | ++ |
| 88 | ++ if (!process_alive (con.owner)) /* The Master process already died. */ |
| 89 | ++ return tty::restore; |
| 90 | ++ if (con.owner == GetCurrentProcessId ()) /* Master process */ |
| 91 | ++ return tty::restore; |
| 92 | ++ |
| 93 | ++ PROCESS_BASIC_INFORMATION pbi; |
| 94 | ++ NTSTATUS status = |
| 95 | ++ NtQueryInformationProcess (GetCurrentProcess (), ProcessBasicInformation, |
| 96 | ++ &pbi, sizeof (pbi), NULL); |
| 97 | ++ if (NT_SUCCESS (status) |
| 98 | ++ && con.owner == (DWORD) pbi.InheritedFromUniqueProcessId) |
| 99 | ++ /* The parent is the stub process. */ |
| 100 | ++ return tty::restore; |
| 101 | ++ |
| 102 | ++ return tty::native; /* Otherwise */ |
| 103 | ++} |
| 104 | +diff --git a/winsup/cygwin/local_includes/fhandler.h b/winsup/cygwin/local_includes/fhandler.h |
| 105 | +index 88a6b7d..e19aca5 100644 |
| 106 | +--- a/winsup/cygwin/local_includes/fhandler.h |
| 107 | ++++ b/winsup/cygwin/local_includes/fhandler.h |
| 108 | +@@ -2391,6 +2391,7 @@ private: |
| 109 | + |
| 110 | + void setup_pcon_hand_over (); |
| 111 | + static void pcon_hand_over_proc (); |
| 112 | ++ static tty::cons_mode cons_mode_on_close (handle_set_t *); |
| 113 | + |
| 114 | + friend tty_min * tty_list::get_cttyp (); |
| 115 | + }; |
0 commit comments