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;
|
||||
char buf[WPBUF_LEN];
|
||||
size_t ixput;
|
||||
HANDLE output_handle;
|
||||
public:
|
||||
void init (HANDLE &handle)
|
||||
{
|
||||
output_handle = handle;
|
||||
empty ();
|
||||
}
|
||||
inline void put (char x)
|
||||
{
|
||||
if (ixput < WPBUF_LEN)
|
||||
buf[ixput++] = x;
|
||||
if (ixput == WPBUF_LEN)
|
||||
send ();
|
||||
buf[ixput++] = x;
|
||||
}
|
||||
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];
|
||||
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);
|
||||
WriteConsoleW (handle, bufw, len, NULL, 0);
|
||||
WriteConsoleW (output_handle, bufw, len, NULL, 0);
|
||||
release_attach_mutex ();
|
||||
}
|
||||
} wpbuf;
|
||||
|
@ -1485,6 +1525,7 @@ fhandler_console::open (int flags, mode_t)
|
|||
}
|
||||
set_output_handle (h);
|
||||
handle_set.output_handle = h;
|
||||
wpbuf.init (get_output_handle ());
|
||||
|
||||
setup_io_mutex ();
|
||||
handle_set.input_mutex = input_mutex;
|
||||
|
@ -2353,7 +2394,7 @@ fhandler_console::char_command (char c)
|
|||
wpbuf.put (c);
|
||||
if (wincap.has_con_esc_rep ())
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
else if (last_char && last_char != L'\n')
|
||||
{
|
||||
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;
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
break;
|
||||
case 'L': /* IL */
|
||||
if (wincap.has_con_broken_il_dl ())
|
||||
|
@ -2400,7 +2441,7 @@ fhandler_console::char_command (char c)
|
|||
srBottom + 1 - con.b.srWindow.Top);
|
||||
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
||||
wpbuf.put ('T');
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
__small_swprintf (bufw, L"\033[%d;%dr",
|
||||
srTop + 1 - con.b.srWindow.Top,
|
||||
srBottom + 1 - con.b.srWindow.Top);
|
||||
|
@ -2414,7 +2455,7 @@ fhandler_console::char_command (char c)
|
|||
{
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
}
|
||||
break;
|
||||
case 'M': /* DL */
|
||||
|
@ -2437,7 +2478,7 @@ fhandler_console::char_command (char c)
|
|||
acquire_attach_mutex (mutex_timeout);
|
||||
WriteConsoleW (get_output_handle (), bufw, wcslen (bufw), 0, 0);
|
||||
wpbuf.put ('S');
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
__small_swprintf (bufw, L"\033[%d;%dr",
|
||||
srTop + 1 - con.b.srWindow.Top,
|
||||
srBottom + 1 - con.b.srWindow.Top);
|
||||
|
@ -2451,7 +2492,7 @@ fhandler_console::char_command (char c)
|
|||
{
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
}
|
||||
break;
|
||||
case 'J': /* ED */
|
||||
|
@ -2480,13 +2521,13 @@ fhandler_console::char_command (char c)
|
|||
}
|
||||
else
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
break;
|
||||
case 'h': /* DECSET */
|
||||
case 'l': /* DECRST */
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
if (con.saw_question_mark)
|
||||
{
|
||||
bool need_fix_tab_position = false;
|
||||
|
@ -2515,7 +2556,7 @@ fhandler_console::char_command (char c)
|
|||
}
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
break;
|
||||
case 'm':
|
||||
if (con.saw_greater_than_sign)
|
||||
|
@ -2523,13 +2564,13 @@ fhandler_console::char_command (char c)
|
|||
/* Text attribute settings */
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
break;
|
||||
default:
|
||||
/* Other escape sequences */
|
||||
wpbuf.put (c);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
@ -3380,7 +3421,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
/* For xterm mode only */
|
||||
/* Just send the sequence */
|
||||
wpbuf.put (*src);
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
}
|
||||
else if (con.savex >= 0 && con.savey >= 0)
|
||||
cursor_set (false, con.savex, con.savey);
|
||||
|
@ -3394,7 +3435,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
/* For xterm mode only */
|
||||
/* Just send the sequence */
|
||||
wpbuf.put (*src);
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
}
|
||||
else
|
||||
cursor_get (&con.savex, &con.savey);
|
||||
|
@ -3427,7 +3468,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
}
|
||||
else
|
||||
wpbuf.put (*src);
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
con.state = normal;
|
||||
wpbuf.empty();
|
||||
}
|
||||
|
@ -3452,7 +3493,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
handled and just sent them. */
|
||||
wpbuf.put (*src);
|
||||
/* Just send the sequence */
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
con.state = normal;
|
||||
wpbuf.empty();
|
||||
}
|
||||
|
@ -3549,7 +3590,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
{
|
||||
wpbuf.put (*src);
|
||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
wpbuf.empty ();
|
||||
con.state = normal;
|
||||
src++;
|
||||
|
@ -3566,7 +3607,7 @@ fhandler_console::write (const void *vsrc, size_t len)
|
|||
if (*src < ' ')
|
||||
{
|
||||
if (wincap.has_con_24bit_colors () && !con_is_legacy)
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
else if (*src == '\007' && con.state == gettitle)
|
||||
set_console_title (con.my_title_buf);
|
||||
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 */
|
||||
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
||||
&& !con.saw_question_mark)
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
con.state = normal;
|
||||
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 */
|
||||
if (wincap.has_con_24bit_colors () && !con_is_legacy
|
||||
&& !con.saw_question_mark)
|
||||
wpbuf.send (get_output_handle ());
|
||||
wpbuf.send ();
|
||||
con.state = normal;
|
||||
}
|
||||
else
|
||||
|
@ -3868,6 +3909,7 @@ fhandler_console::fixup_after_fork_exec (bool execing)
|
|||
{
|
||||
set_unit ();
|
||||
setup_io_mutex ();
|
||||
wpbuf.init (get_output_handle ());
|
||||
|
||||
if (!execing)
|
||||
return;
|
||||
|
|
|
@ -14,3 +14,6 @@ Bug Fixes
|
|||
- Fix a regression that prevented Cygwin from starting if cygwin1.dll
|
||||
is in the root directory.
|
||||
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