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