Skip to content

Commit

Permalink
[Windows] Improve console IO redirection.
Browse files Browse the repository at this point in the history
  • Loading branch information
bruvzg committed Apr 26, 2024
1 parent 6118592 commit 8748147
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 25 deletions.
4 changes: 4 additions & 0 deletions platform/windows/console_wrapper_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ int main(int argc, char *argv[]) {
STARTUPINFOW si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

WCHAR new_command_line[32767];
_snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW()));
Expand Down
34 changes: 27 additions & 7 deletions platform/windows/os_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,24 @@ void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_str
}

void RedirectIOToConsole() {
// Save current handles.
HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE h_stderr = GetStdHandle(STD_ERROR_HANDLE);

if (AttachConsole(ATTACH_PARENT_PROCESS)) {
// Restore redirection (Note: if not redirected it's NULL handles not INVALID_HANDLE_VALUE).
if (h_stdin != 0) {
SetStdHandle(STD_INPUT_HANDLE, h_stdin);
}
if (h_stdout != 0) {
SetStdHandle(STD_OUTPUT_HANDLE, h_stdout);
}
if (h_stderr != 0) {
SetStdHandle(STD_ERROR_HANDLE, h_stderr);
}

// Update file handles.
RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
Expand Down Expand Up @@ -173,10 +190,6 @@ void OS_Windows::initialize() {
add_error_handler(&error_handlers);
#endif

#ifndef WINDOWS_SUBSYSTEM_CONSOLE
RedirectIOToConsole();
#endif

FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
Expand Down Expand Up @@ -1521,10 +1534,10 @@ void OS_Windows::unset_environment(const String &p_var) const {
}

String OS_Windows::get_stdin_string() {
WCHAR buff[1024];
char buff[1024];
DWORD count = 0;
if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) {
return String::utf16((const char16_t *)buff, count);
if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) {
return String::utf8((const char *)buff, count);
}

return String();
Expand Down Expand Up @@ -1908,6 +1921,13 @@ String OS_Windows::get_system_ca_certificates() {
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;

#ifndef WINDOWS_SUBSYSTEM_CONSOLE
RedirectIOToConsole();
#endif

SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);

CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

#ifdef WASAPI_ENABLED
Expand Down
22 changes: 4 additions & 18 deletions platform/windows/windows_terminal_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,12 @@ void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_er
}
buf[len] = 0;

int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, nullptr, 0);
if (wlen < 0) {
return;
}

wchar_t *wbuf = (wchar_t *)memalloc((len + 1) * sizeof(wchar_t));
ERR_FAIL_NULL_MSG(wbuf, "Out of memory.");
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
wbuf[wlen] = 0;

if (p_err) {
fwprintf(stderr, L"%ls", wbuf);
} else {
wprintf(L"%ls", wbuf);
}

memfree(wbuf);
DWORD written = 0;
HANDLE h = p_err ? GetStdHandle(STD_ERROR_HANDLE) : GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(h, &buf[0], len, &written, nullptr);

#ifdef DEBUG_ENABLED
fflush(stdout);
FlushFileBuffers(h);
#endif
}

Expand Down

0 comments on commit 8748147

Please sign in to comment.