[PATCH 2/4] Cygwin: pty: Update workaround for rlwrap for pseudo console
Takashi Yano
takashi.yano@nifty.ne.jp
Fri Feb 20 17:02:41 GMT 2026
In tcgetattr(), the conventional workaround for rlwrap v0.40 or later
is not work as expected with OpenConsole.exe for some reason. This
patch update the workaround so that it works even with OpenConsole.exe
by rebuilding tcgetattr responce reffering the corrent console mode
instead of just overriding it depends on pseudo console setting up
state.
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Reviewed-by:
---
winsup/cygwin/fhandler/pty.cc | 86 ++++++++++++++++++++++++++++-------
1 file changed, 70 insertions(+), 16 deletions(-)
diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
index a4bb53573..8963b9424 100644
--- a/winsup/cygwin/fhandler/pty.cc
+++ b/winsup/cygwin/fhandler/pty.cc
@@ -1738,18 +1738,48 @@ fhandler_pty_slave::tcgetattr (struct termios *t)
{
*t = get_ttyp ()->ti;
- /* Workaround for rlwrap */
- cygheap_fdenum cfd (false);
- while (cfd.next () >= 0)
- if (cfd->get_major () == DEV_PTYM_MAJOR
- && cfd->get_minor () == get_minor ())
- {
- if (get_ttyp ()->pcon_start)
- t->c_lflag &= ~(ICANON | ECHO);
- if (get_ttyp ()->pcon_activated)
- t->c_iflag &= ~ICRNL;
- break;
- }
+ /* Conventional workaround for rlwrap v0.40 or later is not work
+ as expected with OpenConsole.exe for some reason. The following
+ workaround is perhaps better solution even for apps other than
+ rlwrap under pcon_activated mode. */
+ if (get_ttyp ()->pcon_activated)
+ {
+ DWORD mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
+ t->c_lflag &= ~(ICANON | ECHO);
+ t->c_iflag &= ~ICRNL;
+ cygheap_fdenum cfd (false);
+ while (cfd.next () >= 0)
+ if (cfd->get_major () == DEV_PTYM_MAJOR
+ && cfd->get_minor () == get_minor ())
+ {
+ if (nat_pipe_owner_self (get_ttyp ()->nat_pipe_owner_pid))
+ {
+ DWORD resume_pid =
+ attach_console_temporarily (get_ttyp()->nat_pipe_owner_pid);
+ GetConsoleMode (get_ttyp ()->h_pcon_in, &mode);
+ resume_from_temporarily_attach (resume_pid);
+ break;
+ }
+ HANDLE pcon_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
+ get_ttyp ()->nat_pipe_owner_pid);
+ HANDLE h_pcon_in;
+ DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
+ GetCurrentProcess (), &h_pcon_in,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ DWORD resume_pid =
+ attach_console_temporarily (get_ttyp()->nat_pipe_owner_pid);
+ if (!GetConsoleMode (h_pcon_in, &mode) && get_ttyp ()->pcon_start)
+ mode = 0;
+ resume_from_temporarily_attach (resume_pid);
+ CloseHandle (h_pcon_in);
+ CloseHandle (pcon_owner);
+ break;
+ }
+ if (mode & ENABLE_LINE_INPUT)
+ t->c_lflag |= ICANON;
+ if (mode & ENABLE_ECHO_INPUT)
+ t->c_lflag |= ECHO;
+ }
return 0;
}
@@ -2473,11 +2503,35 @@ int
fhandler_pty_master::tcgetattr (struct termios *t)
{
*t = cygwin_shared->tty[get_minor ()]->ti;
- /* Workaround for rlwrap v0.40 or later */
- if (get_ttyp ()->pcon_start)
- t->c_lflag &= ~(ICANON | ECHO);
+
+ /* Conventional workaround for rlwrap v0.40 or later is not work
+ as expected with OpenConsole.exe for some reason. The following
+ workaround is perhaps better solution even for apps other than
+ rlwrap under pcon_activated mode. */
if (get_ttyp ()->pcon_activated)
- t->c_iflag &= ~ICRNL;
+ {
+ t->c_lflag &= ~(ICANON | ECHO);
+ t->c_iflag &= ~ICRNL;
+
+ HANDLE pcon_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
+ get_ttyp ()->nat_pipe_owner_pid);
+ HANDLE h_pcon_in;
+ DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
+ GetCurrentProcess (), &h_pcon_in,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ DWORD resume_pid =
+ attach_console_temporarily (get_ttyp()->nat_pipe_owner_pid);
+ DWORD mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
+ if (!GetConsoleMode (h_pcon_in, &mode) && get_ttyp ()->pcon_start)
+ mode = 0;
+ resume_from_temporarily_attach (resume_pid);
+ CloseHandle (h_pcon_in);
+ CloseHandle (pcon_owner);
+ if (mode & ENABLE_LINE_INPUT)
+ t->c_lflag |= ICANON;
+ if (mode & ENABLE_ECHO_INPUT)
+ t->c_lflag |= ECHO;
+ }
return 0;
}
--
2.51.0
More information about the Cygwin-patches
mailing list