- After commit 6cc299f0e20e4b76f7dbab5ea8c296ffa4859b62, outputs of cygwin programs which call both printf() and WriteConsole() are frequently distorted. This patch fixes the issue. --- winsup/cygwin/fhandler.h | 2 ++ winsup/cygwin/fhandler_tty.cc | 46 ++++++++++++++++++++++++----------- 2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 35190c0fe..2c18b215a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -2209,6 +2209,8 @@ class fhandler_pty_slave: public fhandler_pty_common } void setup_locale (void); void set_freeconsole_on_close (bool val); + void trigger_redraw_screen (void); + void wait_pcon_fwd (void); }; #define __ptsname(buf, unit) __small_sprintf ((buf), "/dev/pty%d", (unit)) diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 71a1f42ba..ea971e11f 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -1109,7 +1109,7 @@ skip_console_setting: } else if ((fd == 1 || fd == 2) && !get_ttyp ()->switch_to_pcon_out) { - cygwait (get_ttyp ()->fwd_done, INFINITE); + wait_pcon_fwd (); if (get_ttyp ()->pcon_pid == 0 || kill (get_ttyp ()->pcon_pid, 0) != 0) get_ttyp ()->pcon_pid = myself->pid; @@ -1152,7 +1152,7 @@ fhandler_pty_slave::reset_switch_to_pcon (void) } if (get_ttyp ()->switch_to_pcon_out) /* Wait for pty_master_fwd_thread() */ - cygwait (get_ttyp ()->fwd_done, INFINITE); + wait_pcon_fwd (); get_ttyp ()->pcon_pid = 0; get_ttyp ()->switch_to_pcon_in = false; get_ttyp ()->switch_to_pcon_out = false; @@ -2680,6 +2680,34 @@ fhandler_pty_slave::set_freeconsole_on_close (bool val) freeconsole_on_close = val; } +void +fhandler_pty_slave::trigger_redraw_screen (void) +{ + /* Forcibly redraw screen based on console screen buffer. */ + /* The following code triggers redrawing the screen. */ + CONSOLE_SCREEN_BUFFER_INFO sbi; + GetConsoleScreenBufferInfo (get_output_handle (), &sbi); + SMALL_RECT rect = {0, 0, + (SHORT) (sbi.dwSize.X -1), (SHORT) (sbi.dwSize.Y - 1)}; + COORD dest = {0, 0}; + CHAR_INFO fill = {' ', 0}; + ScrollConsoleScreenBuffer (get_output_handle (), &rect, NULL, dest, &fill); +} + +void +fhandler_pty_slave::wait_pcon_fwd (void) +{ + /* The transfer may be interruted once, so wait twice. */ + /* First time */ + ResetEvent (get_ttyp ()->fwd_done); + trigger_redraw_screen (); + cygwait (get_ttyp ()->fwd_done, INFINITE); + /* Second time */ + ResetEvent (get_ttyp ()->fwd_done); + trigger_redraw_screen (); + cygwait (get_ttyp ()->fwd_done, INFINITE); +} + void fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set) { @@ -2727,7 +2755,7 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set) DWORD mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; SetConsoleMode (get_output_handle (), mode); if (!get_ttyp ()->switch_to_pcon_out) - cygwait (get_ttyp ()->fwd_done, INFINITE); + wait_pcon_fwd (); if (get_ttyp ()->pcon_pid == 0 || kill (get_ttyp ()->pcon_pid, 0) != 0) get_ttyp ()->pcon_pid = myself->pid; @@ -2735,16 +2763,7 @@ fhandler_pty_slave::fixup_after_attach (bool native_maybe, int fd_set) if (get_ttyp ()->need_redraw_screen) { - /* Forcibly redraw screen based on console screen buffer. */ - /* The following code triggers redrawing the screen. */ - CONSOLE_SCREEN_BUFFER_INFO sbi; - GetConsoleScreenBufferInfo (get_output_handle (), &sbi); - SMALL_RECT rect = {0, 0, - (SHORT) (sbi.dwSize.X -1), (SHORT) (sbi.dwSize.Y - 1)}; - COORD dest = {0, 0}; - CHAR_INFO fill = {' ', 0}; - ScrollConsoleScreenBuffer (get_output_handle (), - &rect, NULL, dest, &fill); + trigger_redraw_screen (); get_ttyp ()->need_redraw_screen = false; } } @@ -3016,7 +3035,6 @@ fhandler_pty_master::pty_master_fwd_thread () termios_printf ("ReadFile for forwarding failed, %E"); break; } - ResetEvent (get_ttyp ()->fwd_done); ssize_t wlen = rlen; char *ptr = outbuf; if (get_pseudo_console ()) -- 2.21.0