---
 winsup/cygwin/fhandler_tty.cc | 130 +++++++++++++---------------------
 1 file changed, 49 insertions(+), 81 deletions(-)

diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 843807aab..f723ec7cf 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -370,7 +370,43 @@ CreateProcessW_Hooked
 void set_ishybrid_and_switch_to_pcon (HANDLE) {}
 #endif /* USE_API_HOOK */
 
-bool
+static char *
+convert_mb_str (UINT cp_to, size_t *len_to,
+               UINT cp_from, const char *ptr_from, size_t len_from)
+{
+  char *buf;
+  size_t nlen;
+  if (cp_to != cp_from)
+    {
+      size_t wlen =
+       MultiByteToWideChar (cp_from, 0, ptr_from, len_from, NULL, 0);
+      wchar_t *wbuf = (wchar_t *)
+       HeapAlloc (GetProcessHeap (), 0, wlen * sizeof (wchar_t));
+      wlen =
+       MultiByteToWideChar (cp_from, 0, ptr_from, len_from, wbuf, wlen);
+      nlen = WideCharToMultiByte (cp_to, 0, wbuf, wlen, NULL, 0, NULL, NULL);
+      buf = (char *) HeapAlloc (GetProcessHeap (), 0, nlen);
+      nlen = WideCharToMultiByte (cp_to, 0, wbuf, wlen, buf, nlen, NULL, NULL);
+      HeapFree (GetProcessHeap (), 0, wbuf);
+    }
+  else
+    {
+      /* Just copy */
+      buf = (char *) HeapAlloc (GetProcessHeap (), 0, len_from);
+      memcpy (buf, ptr_from, len_from);
+      nlen = len_from;
+    }
+  *len_to = nlen;
+  return buf;
+}
+
+static void
+mb_str_free (char *ptr)
+{
+  HeapFree (GetProcessHeap (), 0, ptr);
+}
+
+static bool
 bytes_available (DWORD& n, HANDLE h)
 {
   DWORD navail, nleft;
@@ -1270,34 +1306,11 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
 
   reset_switch_to_pcon ();
 
-  char *buf;
-  ssize_t nlen;
-  UINT targetCodePage = get_ttyp ()->switch_to_pcon_out ?
+  UINT target_code_page = get_ttyp ()->switch_to_pcon_out ?
     GetConsoleOutputCP () : get_ttyp ()->term_code_page;
-  if (targetCodePage != get_ttyp ()->term_code_page)
-    {
-      size_t wlen =
-       MultiByteToWideChar (get_ttyp ()->term_code_page, 0,
-                            (char *)ptr, len, NULL, 0);
-      wchar_t *wbuf = (wchar_t *)
-       HeapAlloc (GetProcessHeap (), 0, wlen * sizeof (wchar_t));
-      wlen =
-       MultiByteToWideChar (get_ttyp ()->term_code_page, 0,
-                            (char *)ptr, len, wbuf, wlen);
-      nlen = WideCharToMultiByte (targetCodePage, 0,
-                                 wbuf, wlen, NULL, 0, NULL, NULL);
-      buf = (char *) HeapAlloc (GetProcessHeap (), 0, nlen);
-      nlen = WideCharToMultiByte (targetCodePage, 0,
-                                 wbuf, wlen, buf, nlen, NULL, NULL);
-      HeapFree (GetProcessHeap (), 0, wbuf);
-    }
-  else
-    {
-      /* Just copy */
-      buf = (char *) HeapAlloc (GetProcessHeap (), 0, len);
-      memcpy (buf, (char *)ptr, len);
-      nlen = len;
-    }
+  ssize_t nlen;
+  char *buf = convert_mb_str (target_code_page, (size_t *) &nlen,
+                get_ttyp ()->term_code_page, (const char *) ptr, len);
 
   /* If not attached to this pseudo console, try to attach temporarily. */
   pid_restore = 0;
@@ -1334,7 +1347,7 @@ fhandler_pty_slave::write (const void *ptr, size_t len)
       towrite = -1;
     }
   release_output_mutex ();
-  HeapFree (GetProcessHeap (), 0, buf);
+  mb_str_free (buf);
   flags = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
   if (get_ttyp ()->switch_to_pcon_out && !fallback)
     SetConsoleMode (get_output_handle (), dwMode | flags);
@@ -2260,33 +2273,10 @@ fhandler_pty_master::write (const void *ptr, size_t len)
      if current application is native console application. */
   if (to_be_read_from_pcon ())
     {
-      char *buf;
       size_t nlen;
+      char *buf = convert_mb_str
+       (CP_UTF8, &nlen, get_ttyp ()->term_code_page, (const char *) ptr, len);
 
-      if (get_ttyp ()->term_code_page != CP_UTF8)
-       {
-         size_t wlen =
-           MultiByteToWideChar (get_ttyp ()->term_code_page, 0,
-                                (char *)ptr, len, NULL, 0);
-         wchar_t *wbuf = (wchar_t *)
-           HeapAlloc (GetProcessHeap (), 0, wlen * sizeof (wchar_t));
-         wlen =
-           MultiByteToWideChar (get_ttyp ()->term_code_page, 0,
-                                (char *)ptr, len, wbuf, wlen);
-         nlen = WideCharToMultiByte (CP_UTF8, 0,
-                                     wbuf, wlen, NULL, 0, NULL, NULL);
-         buf = (char *) HeapAlloc (GetProcessHeap (), 0, nlen);
-         nlen = WideCharToMultiByte (CP_UTF8, 0,
-                                     wbuf, wlen, buf, nlen, NULL, NULL);
-         HeapFree (GetProcessHeap (), 0, wbuf);
-       }
-      else
-       {
-         /* Just copy */
-         buf = (char *) HeapAlloc (GetProcessHeap (), 0, len);
-         memcpy (buf, (char *)ptr, len);
-         nlen = len;
-       }
       DWORD wLen;
       WriteFile (to_slave, buf, nlen, &wLen, NULL);
 
@@ -2302,7 +2292,7 @@ fhandler_pty_master::write (const void *ptr, size_t len)
       else
        SetEvent (input_available_event);
 
-      HeapFree (GetProcessHeap (), 0, buf);
+      mb_str_free (buf);
       return len;
     }
 
@@ -3039,32 +3029,10 @@ fhandler_pty_master::pty_master_fwd_thread ()
            }
          wlen = rlen;
 
-         char *buf;
          size_t nlen;
-         if (get_ttyp ()->term_code_page != CP_UTF8)
-           {
-             size_t wlen2 =
-               MultiByteToWideChar (CP_UTF8, 0,
-                                    (char *)ptr, wlen, NULL, 0);
-             wchar_t *wbuf = (wchar_t *)
-               HeapAlloc (GetProcessHeap (), 0, wlen2 * sizeof (wchar_t));
-             wlen2 =
-               MultiByteToWideChar (CP_UTF8, 0,
-                                    (char *)ptr, wlen, wbuf, wlen2);
-             nlen = WideCharToMultiByte (get_ttyp ()->term_code_page, 0,
-                                         wbuf, wlen2, NULL, 0, NULL, NULL);
-             buf = (char *) HeapAlloc (GetProcessHeap (), 0, nlen);
-             nlen = WideCharToMultiByte (get_ttyp ()->term_code_page, 0,
-                                         wbuf, wlen2, buf, nlen, NULL, NULL);
-             HeapFree (GetProcessHeap (), 0, wbuf);
-           }
-         else
-           {
-             /* Just copy */
-             buf = (char *) HeapAlloc (GetProcessHeap (), 0, wlen);
-             memcpy (buf, (char *)ptr, wlen);
-             nlen = wlen;
-           }
+         char *buf = convert_mb_str
+           (get_ttyp ()->term_code_page, &nlen, CP_UTF8, ptr, wlen);
+
          ptr = buf;
          wlen = rlen = nlen;
 
@@ -3083,7 +3051,7 @@ fhandler_pty_master::pty_master_fwd_thread ()
              wlen = (rlen -= written);
            }
          release_output_mutex ();
-         HeapFree (GetProcessHeap (), 0, buf);
+         mb_str_free (buf);
          continue;
        }
       acquire_output_mutex (INFINITE);
-- 
2.21.0

Reply via email to