Browse Source

[Windows] Disable console I/O redirection, if it's already redirected to the pipe or file.

(cherry picked from commit 99a1e552acebef5db9794fbc17e7658acc660e64)
bruvzg 3 years ago
parent
commit
ba2e891ec8
1 changed files with 15 additions and 7 deletions
  1. 15 7
      platform/windows/os_windows.cpp

+ 15 - 7
platform/windows/os_windows.cpp

@@ -107,15 +107,23 @@ static String format_error_message(DWORD id) {
 
 
 extern HINSTANCE godot_hinstance;
 extern HINSTANCE godot_hinstance;
 
 
+void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) {
+	const HANDLE h_existing = GetStdHandle(p_std_handle);
+	if (h_existing != INVALID_HANDLE_VALUE) { // Redirect only if attached console have a valid handle.
+		const HANDLE h_cpp = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(p_cpp_stream)));
+		if (h_cpp == INVALID_HANDLE_VALUE) { // Redirect only if it's not already redirected to the pipe or file.
+			FILE *fp = p_cpp_stream;
+			freopen_s(&fp, p_file_name, p_mode, p_cpp_stream); // Redirect stream.
+			setvbuf(p_cpp_stream, nullptr, _IONBF, 0); // Disable stream buffering.
+		}
+	}
+}
+
 void RedirectIOToConsole() {
 void RedirectIOToConsole() {
 	if (AttachConsole(ATTACH_PARENT_PROCESS)) {
 	if (AttachConsole(ATTACH_PARENT_PROCESS)) {
-		FILE *fpstdin = stdin;
-		FILE *fpstdout = stdout;
-		FILE *fpstderr = stderr;
-
-		freopen_s(&fpstdin, "CONIN$", "r", stdin);
-		freopen_s(&fpstdout, "CONOUT$", "w", stdout);
-		freopen_s(&fpstderr, "CONOUT$", "w", stderr);
+		RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
+		RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
+		RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
 
 
 		printf("\n"); // Make sure our output is starting from the new line.
 		printf("\n"); // Make sure our output is starting from the new line.
 	}
 	}