Cygwin: console: Handle setting very long window title correctly.
- Previously, the console code could not handle escape sequence setting window title longer than 256 byte correctly. This patch fixes the issue. Addresses: https://cygwin.com/pipermail/cygwin/2022-June/251662.html
This commit is contained in:
parent
fdbd153932
commit
fe10e8f03a
|
@ -73,19 +73,59 @@ private:
|
||||||
static const size_t WPBUF_LEN = 256u;
|
static const size_t WPBUF_LEN = 256u;
|
||||||
char buf[WPBUF_LEN];
|
char buf[WPBUF_LEN];
|
||||||
size_t ixput;
|
size_t ixput;
|
||||||
|
HANDLE output_handle;
|
||||||
public:
|
public:
|
||||||
|
void init (HANDLE &handle)
|
||||||
|
{
|
||||||
|
output_handle = handle;
|
||||||
|
empty ();
|
||||||
|
}
|
||||||
inline void put (char x)
|
inline void put (char x)
|
||||||
{
|
{
|
||||||
if (ixput < WPBUF_LEN)
|
if (ixput == WPBUF_LEN)
|
||||||
buf[ixput++] = x;
|
send ();
|
||||||
|
buf[ixput++] = x;
|
||||||
}
|
}
|
||||||
inline void empty () { ixput = 0u; }
|
inline void empty () { ixput = 0u; }
|
||||||
inline void send (HANDLE &handle)
|
inline void send ()
|
||||||
{
|
{
|
||||||
|
if (!output_handle)
|
||||||
|
{
|
||||||
|
empty ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mbtowc_p f_mbtowc =
|
||||||
|
(__MBTOWC == __ascii_mbtowc) ? __utf8_mbtowc : __MBTOWC;
|
||||||
wchar_t bufw[WPBUF_LEN];
|
wchar_t bufw[WPBUF_LEN];
|
||||||
DWORD len = sys_mbstowcs (bufw, WPBUF_LEN, buf, ixput);
|
DWORD len = 0;
|
||||||
|
mbstate_t ps;
|
||||||
|
memset (&ps, 0, sizeof (ps));
|
||||||
|
char *p = buf;
|
||||||
|
while (ixput)
|
||||||
|
{
|
||||||
|
int bytes = f_mbtowc (_REENT, bufw + len, p, ixput, &ps);
|
||||||
|
if (bytes < 0)
|
||||||
|
{
|
||||||
|
if ((size_t) ps.__count < ixput)
|
||||||
|
{ /* Discard one byte and retry. */
|
||||||
|
p++;
|
||||||
|
ixput--;
|
||||||
|
memset (&ps, 0, sizeof (ps));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Halfway through the multibyte char. */
|
||||||
|
memmove (buf, p, ixput);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
p += bytes;
|
||||||
|
ixput -= bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
acquire_attach_mutex (mutex_timeout);
|
acquire_attach_mutex (mutex_timeout);
|
||||||
WriteConsoleW (handle, bufw, len, NULL, 0);
|
WriteConsoleW (output_handle, bufw, len, NULL, 0);
|
||||||
release_attach_mutex ();
|
release_attach_mutex ();
|
||||||
}
|
}
|
||||||
} wpbuf;
|
} wpbuf;
|
||||||
|
@ -1485,6 +1525,7 @@ fhandler_console::open (int flags, mode_t)
|
||||||
}
|
}
|
||||||
set_output_handle (h);
|
set_output_handle (h);
|
||||||
handle_set.output_handle = h;
|
handle_set.output_handle = h;
|
||||||
|
wpbuf.init (get_output_handle ());
|
||||||
|
|
||||||
setup_io_mutex ();
|
setup_io_mutex ();
|
||||||
handle_set.input_mutex = input_mutex;
|
handle_set.input_mutex = input_mutex;
|
||||||
|
@ -2353,7 +2394,7 @@ fhandler_console::char_command (char c)
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
if (wincap.has_con_esc_rep ())
|
if (wincap.has_con_esc_rep ())
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
else if (last_char && last_char != L'\n')
|
else if (last_char && last_char != L'\n')
|
||||||
{
|
{
|
||||||
acquire_attach_mutex (mutex_timeout);
|
acquire_attach_mutex (mutex_timeout);
|
||||||
|
@ -2367,7 +2408,7 @@ fhandler_console::char_command (char c)
|
||||||
con.scroll_region.Bottom = con.args[1] ? con.args[1] - 1 : -1;
|
con.scroll_region.Bottom = con.args[1] ? con.args[1] - 1 : -1;
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
break;
|
break;
|
||||||
case 'L': /* IL */
|
case 'L': /* IL */
|
||||||
if (wincap.has_con_broken_il_dl ())
|
if (wincap.has_con_broken_il_dl ())
|
||||||
|
@ -2400,7 +2441,7 @@ fhandler_console::char_command (char c)
|
||||||
srBottom + 1 - con.b.srWindow.Top);
|
srBottom + 1 - con.b.srWindow.Top);
|
||||||
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
||||||
wpbuf.put ('T');
|
wpbuf.put ('T');
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
__small_swprintf (bufw, L"\033[%d;%dr",
|
__small_swprintf (bufw, L"\033[%d;%dr",
|
||||||
srTop + 1 - con.b.srWindow.Top,
|
srTop + 1 - con.b.srWindow.Top,
|
||||||
srBottom + 1 - con.b.srWindow.Top);
|
srBottom + 1 - con.b.srWindow.Top);
|
||||||
|
@ -2414,7 +2455,7 @@ fhandler_console::char_command (char c)
|
||||||
{
|
{
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'M': /* DL */
|
case 'M': /* DL */
|
||||||
|
@ -2437,7 +2478,7 @@ fhandler_console::char_command (char c)
|
||||||
acquire_attach_mutex (mutex_timeout);
|
acquire_attach_mutex (mutex_timeout);
|
||||||
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
||||||
wpbuf.put ('S');
|
wpbuf.put ('S');
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
__small_swprintf (bufw, L"\033[%d;%dr",
|
__small_swprintf (bufw, L"\033[%d;%dr",
|
||||||
srTop + 1 - con.b.srWindow.Top,
|
srTop + 1 - con.b.srWindow.Top,
|
||||||
srBottom + 1 - con.b.srWindow.Top);
|
srBottom + 1 - con.b.srWindow.Top);
|
||||||
|
@ -2451,7 +2492,7 @@ fhandler_console::char_command (char c)
|
||||||
{
|
{
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'J': /* ED */
|
case 'J': /* ED */
|
||||||
|
@ -2480,13 +2521,13 @@ fhandler_console::char_command (char c)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
break;
|
break;
|
||||||
case 'h': /* DECSET */
|
case 'h': /* DECSET */
|
||||||
case 'l': /* DECRST */
|
case 'l': /* DECRST */
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
if (con.saw_question_mark)
|
if (con.saw_question_mark)
|
||||||
{
|
{
|
||||||
bool need_fix_tab_position = false;
|
bool need_fix_tab_position = false;
|
||||||
|
@ -2515,7 +2556,7 @@ fhandler_console::char_command (char c)
|
||||||
}
|
}
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (con.saw_greater_than_sign)
|
if (con.saw_greater_than_sign)
|
||||||
|
@ -2523,13 +2564,13 @@ fhandler_console::char_command (char c)
|
||||||
/* Text attribute settings */
|
/* Text attribute settings */
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Other escape sequences */
|
/* Other escape sequences */
|
||||||
wpbuf.put (c);
|
wpbuf.put (c);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -3380,7 +3421,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
/* For xterm mode only */
|
/* For xterm mode only */
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.put (*src);
|
wpbuf.put (*src);
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
}
|
}
|
||||||
else if (con.savex >= 0 && con.savey >= 0)
|
else if (con.savex >= 0 && con.savey >= 0)
|
||||||
cursor_set (false, con.savex, con.savey);
|
cursor_set (false, con.savex, con.savey);
|
||||||
|
@ -3394,7 +3435,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
/* For xterm mode only */
|
/* For xterm mode only */
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.put (*src);
|
wpbuf.put (*src);
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cursor_get (&con.savex, &con.savey);
|
cursor_get (&con.savex, &con.savey);
|
||||||
|
@ -3427,7 +3468,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
wpbuf.put (*src);
|
wpbuf.put (*src);
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
wpbuf.empty();
|
wpbuf.empty();
|
||||||
}
|
}
|
||||||
|
@ -3452,7 +3493,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
handled and just sent them. */
|
handled and just sent them. */
|
||||||
wpbuf.put (*src);
|
wpbuf.put (*src);
|
||||||
/* Just send the sequence */
|
/* Just send the sequence */
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
wpbuf.empty();
|
wpbuf.empty();
|
||||||
}
|
}
|
||||||
|
@ -3549,7 +3590,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
{
|
{
|
||||||
wpbuf.put (*src);
|
wpbuf.put (*src);
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
wpbuf.empty ();
|
wpbuf.empty ();
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
src++;
|
src++;
|
||||||
|
@ -3566,7 +3607,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
if (*src < ' ')
|
if (*src < ' ')
|
||||||
{
|
{
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
else if (*src == '\007' && con.state == gettitle)
|
else if (*src == '\007' && con.state == gettitle)
|
||||||
set_console_title (con.my_title_buf);
|
set_console_title (con.my_title_buf);
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
|
@ -3591,7 +3632,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
/* Send OSC Ps; Pt BEL other than OSC Ps; ? BEL */
|
/* Send OSC Ps; Pt BEL other than OSC Ps; ? BEL */
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
||||||
&& !con.saw_question_mark)
|
&& !con.saw_question_mark)
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
wpbuf.empty();
|
wpbuf.empty();
|
||||||
}
|
}
|
||||||
|
@ -3604,7 +3645,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
||||||
/* Send OSC Ps; Pt ST other than OSC Ps; ? ST */
|
/* Send OSC Ps; Pt ST other than OSC Ps; ? ST */
|
||||||
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
||||||
&& !con.saw_question_mark)
|
&& !con.saw_question_mark)
|
||||||
wpbuf.send (get_output_handle ());
|
wpbuf.send ();
|
||||||
con.state = normal;
|
con.state = normal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3868,6 +3909,7 @@ fhandler_console::fixup_after_fork_exec (bool execing)
|
||||||
{
|
{
|
||||||
set_unit ();
|
set_unit ();
|
||||||
setup_io_mutex ();
|
setup_io_mutex ();
|
||||||
|
wpbuf.init (get_output_handle ());
|
||||||
|
|
||||||
if (!execing)
|
if (!execing)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,3 +14,6 @@ Bug Fixes
|
||||||
- Fix a regression that prevented Cygwin from starting if cygwin1.dll
|
- Fix a regression that prevented Cygwin from starting if cygwin1.dll
|
||||||
is in the root directory.
|
is in the root directory.
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin/2022-May/251548.html
|
Addresses: https://cygwin.com/pipermail/cygwin/2022-May/251548.html
|
||||||
|
|
||||||
|
- Handle setting very long window title correctly in console.
|
||||||
|
Addresses: https://cygwin.com/pipermail/cygwin/2022-June/251662.html
|
||||||
|
|
Loading…
Reference in New Issue