From e4a52e5c0ef9ac6bfc1885afd0d9277993461fe8 Mon Sep 17 00:00:00 2001
From: D-AIRY <admin@ds-servers.com>
Date: Mon, 30 Mar 2020 09:54:00 +0300
Subject: [PATCH] Handling console in more portable way

---
 source/core/sxcore.h    | 41 ++++++++++++++++++++++++++++++++---------
 source/xcommon/IXCore.h | 40 +++++++++++++++++++++++++++++++---------
 2 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/source/core/sxcore.h b/source/core/sxcore.h
index 3ca24f8dc..c9a848442 100644
--- a/source/core/sxcore.h
+++ b/source/core/sxcore.h
@@ -484,22 +484,45 @@ class COutPtr
 		m_fOut = ::_fdopen(_dup(hOut), "a+");
 		::setvbuf(m_fOut, NULL, _IONBF, 0);
 
-		m_fStdout = *stdout;
-		m_fStderr = *stderr;
-
-		*stdout = *m_fOut;
-		*stderr = *m_fOut;
+#ifdef _MSC_VER
+		if(_fileno(stdout) < 0)
+		{
+			char szPipename[255];
+			HANDLE hPipe = NULL;
+			{
+				sprintf(szPipename, "\\\\.\\pipe\\SkyXEngineConsoleStdout-%u-%u", GetCurrentProcessId(), GetCurrentThreadId());
+				hPipe = CreateNamedPipe(szPipename, PIPE_ACCESS_DUPLEX, PIPE_NOWAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL);
+				freopen(szPipename, "w", stdout);
+				_dup2(_fileno(m_fOut), _fileno(stdout));
+				CloseHandle(hPipe);
+			}
+
+			{
+				sprintf(szPipename, "\\\\.\\pipe\\SkyXEngineConsoleStderr-%u-%u", GetCurrentProcessId(), GetCurrentThreadId());
+				hPipe = CreateNamedPipe(szPipename, PIPE_ACCESS_DUPLEX, PIPE_NOWAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL);
+				freopen(szPipename, "w", stderr);
+				_dup2(_fileno(m_fOut), _fileno(stderr));
+				CloseHandle(hPipe);
+			}
+		}
+		else
+		{
+#endif
+			_dup2(_fileno(m_fOut), _fileno(stdout));
+			_dup2(_fileno(m_fOut), _fileno(stderr));
+#ifdef _MSC_VER
+	}
+#endif
+		::setvbuf(stdout, NULL, _IONBF, 0);
+		::setvbuf(stderr, NULL, _IONBF, 0);
+		//close(hOut);
 	}
 	~COutPtr()
 	{
-		*stdout = m_fStdout;
-		*stderr = m_fStderr;
 		fclose(m_fOut);
 	}
 
 	FILE *m_fOut;
-	FILE m_fStdout;
-	FILE m_fStderr;
 };
 
 /*! Устанавливает поток вывода. Для работы консоли
diff --git a/source/xcommon/IXCore.h b/source/xcommon/IXCore.h
index 1e291a066..113aac443 100644
--- a/source/xcommon/IXCore.h
+++ b/source/xcommon/IXCore.h
@@ -69,22 +69,44 @@ class CCoreOutPtr
 		m_fOut = ::_fdopen(_dup(hOut), "a+");
 		::setvbuf(m_fOut, NULL, _IONBF, 0);
 
-		m_fStdout = *stdout;
-		m_fStderr = *stderr;
-
-		*stdout = *m_fOut;
-		*stderr = *m_fOut;
+#ifdef _MSC_VER
+		if(_fileno(stdout) < 0)
+		{
+			char szPipename[255];
+			HANDLE hPipe = NULL;
+			{
+				sprintf(szPipename, "\\\\.\\pipe\\SkyXEngineConsoleStdout-%u-%u", GetCurrentProcessId(), GetCurrentThreadId());
+				hPipe = CreateNamedPipe(szPipename, PIPE_ACCESS_DUPLEX, PIPE_NOWAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL);
+				freopen(szPipename, "w", stdout);
+				_dup2(_fileno(m_fOut), _fileno(stdout));
+				CloseHandle(hPipe);
+			}
+
+			{
+				sprintf(szPipename, "\\\\.\\pipe\\SkyXEngineConsoleStderr-%u-%u", GetCurrentProcessId(), GetCurrentThreadId());
+				hPipe = CreateNamedPipe(szPipename, PIPE_ACCESS_DUPLEX, PIPE_NOWAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL);
+				freopen(szPipename, "w", stderr);
+				_dup2(_fileno(m_fOut), _fileno(stderr));
+				CloseHandle(hPipe);
+			}
+		}
+		else
+		{
+#endif
+			_dup2(_fileno(m_fOut), _fileno(stdout));
+			_dup2(_fileno(m_fOut), _fileno(stderr));
+#ifdef _MSC_VER
+		}
+#endif
+		::setvbuf(stdout, NULL, _IONBF, 0);
+		::setvbuf(stderr, NULL, _IONBF, 0);
 	}
 	~CCoreOutPtr()
 	{
-		*stdout = m_fStdout;
-		*stderr = m_fStderr;
 		fclose(m_fOut);
 	}
 
 	FILE *m_fOut;
-	FILE m_fStdout;
-	FILE m_fStderr;
 };
 
 /*! Устанавливает поток вывода. Для работы консоли
-- 
GitLab