]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fix output redirection under Windows
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 31 Mar 2021 13:35:33 +0000 (14:35 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Thu, 1 Apr 2021 19:16:50 +0000 (20:16 +0100)
If WriteConsoleW() fails, convert to the *console* code page and write to
stdout/stderr (as appropriate) with fwrite().

Mostly researched by bers in !177.

Fixes: #229
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
main.c
www/changelog.xml

diff --git a/main.c b/main.c
index c940a03fab324de29ba87c35a97b258c4b20fce9..ba5af16e08f83ccf6abe213473c6af446ed39899 100644 (file)
--- a/main.c
+++ b/main.c
@@ -317,14 +317,33 @@ static int __attribute__ ((format(printf, 2, 0)))
        HANDLE h = GetStdHandle(f == stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
        wchar_t wbuf[1024];
        char buf[1024];
-       int chars, wchars;
+       int bytes, wchars;
 
-       buf[sizeof(buf) - 1] = 0;
-       chars = _vsnprintf(buf, sizeof(buf) - 1, fmt, args);
-       wchars = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, sizeof(wbuf)/2);
-       WriteConsoleW(h, wbuf, wchars, NULL, NULL);
+       /* No need to NUL-terminate strings here */
+       bytes = _vsnprintf(buf, sizeof(buf), fmt, args);
+       if (bytes < 0)
+               return bytes;
+       if (bytes > sizeof(buf))
+               bytes = sizeof(buf);
 
-       return chars;
+       wchars = MultiByteToWideChar(CP_UTF8, 0, buf, bytes, wbuf, sizeof(wbuf)/2);
+       if (!wchars)
+               return -1;
+
+       /*
+        * If writing to console fails, that's probably due to redirection.
+        * Convert to console CP and write to the FH, following the example of
+        * https://github.com/wine-mirror/wine/blob/e909986e6e/programs/whoami/main.c#L33-L49
+        */
+       if (!WriteConsoleW(h, wbuf, wchars, NULL, NULL)) {
+               bytes = WideCharToMultiByte(GetConsoleOutputCP(), 0, wbuf, wchars,
+                                           buf, sizeof(buf), NULL, NULL);
+               if (!bytes)
+                       return -1;
+
+               return fwrite(buf, 1, bytes, f);
+       }
+       return bytes;
 }
 
 static int __attribute__ ((format(printf, 2, 3)))
index 23085a533c8448fa68777bbddab5a55112edebf1..3027ee7147a698418cb2acc08351158c04fd20f4 100644 (file)
@@ -36,6 +36,7 @@
        <li>Add support for PPP-based protocols, currently over TLS only (<a href="https://gitlab.com/openconnect/openconnect/-/merge_requests/165">!165</a>).</li>
        <li>Add support for two PPP-based protocols, F5 with <tt>--protocol=f5</tt> and Fortinet with <tt>--protocol=fortinet</tt> (<a href="https://gitlab.com/openconnect/openconnect/-/merge_requests/169">!169</a>).</li>
        <li>Add support for <a href="https://www.wintun.net/">Wintun</a> Layer 3 TUN driver under Windows.</li>
+       <li>Fix output redirection under Windows (<a href="https://gitlab.com/openconnect/openconnect/-/issues/229">#229</a>)</li>
      </ul><br/>
   </li>
   <li><b><a href="ftp://ftp.infradead.org/pub/openconnect/openconnect-8.10.tar.gz">OpenConnect v8.10</a></b>