taken from https://stackoverflow.com/a/25927081 getting a proper output to console with redirection support on windows is apparently hell
| 45 | // taken from https://stackoverflow.com/a/25927081 |
| 46 | // getting a proper output to console with redirection support on windows is apparently hell |
| 47 | void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr) |
| 48 | { |
| 49 | // Re-initialize the C runtime "FILE" handles with clean handles bound to "nul". We do this because it has been |
| 50 | // observed that the file number of our standard handle file objects can be assigned internally to a value of -2 |
| 51 | // when not bound to a valid target, which represents some kind of unknown internal invalid state. In this state our |
| 52 | // call to "_dup2" fails, as it specifically tests to ensure that the target file number isn't equal to this value |
| 53 | // before allowing the operation to continue. We can resolve this issue by first "re-opening" the target files to |
| 54 | // use the "nul" device, which will place them into a valid state, after which we can redirect them to our target |
| 55 | // using the "_dup2" function. |
| 56 | if (bindStdIn) { |
| 57 | FILE* dummyFile; |
| 58 | freopen_s(&dummyFile, "nul", "r", stdin); |
| 59 | } |
| 60 | if (bindStdOut) { |
| 61 | FILE* dummyFile; |
| 62 | freopen_s(&dummyFile, "nul", "w", stdout); |
| 63 | } |
| 64 | if (bindStdErr) { |
| 65 | FILE* dummyFile; |
| 66 | freopen_s(&dummyFile, "nul", "w", stderr); |
| 67 | } |
| 68 | |
| 69 | // Redirect unbuffered stdin from the current standard input handle |
| 70 | if (bindStdIn) { |
| 71 | RedirectHandle(STD_INPUT_HANDLE, stdin, "r"); |
| 72 | } |
| 73 | |
| 74 | // Redirect unbuffered stdout to the current standard output handle |
| 75 | if (bindStdOut) { |
| 76 | RedirectHandle(STD_OUTPUT_HANDLE, stdout, "w"); |
| 77 | } |
| 78 | |
| 79 | // Redirect unbuffered stderr to the current standard error handle |
| 80 | if (bindStdErr) { |
| 81 | RedirectHandle(STD_ERROR_HANDLE, stderr, "w"); |
| 82 | } |
| 83 | |
| 84 | // Clear the error state for each of the C++ standard stream objects. We need to do this, as attempts to access the |
| 85 | // standard streams before they refer to a valid target will cause the iostream objects to enter an error state. In |
| 86 | // versions of Visual Studio after 2005, this seems to always occur during startup regardless of whether anything |
| 87 | // has been read from or written to the targets or not. |
| 88 | if (bindStdIn) { |
| 89 | std::wcin.clear(); |
| 90 | std::cin.clear(); |
| 91 | } |
| 92 | if (bindStdOut) { |
| 93 | std::wcout.clear(); |
| 94 | std::cout.clear(); |
| 95 | } |
| 96 | if (bindStdErr) { |
| 97 | std::wcerr.clear(); |
| 98 | std::cerr.clear(); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | bool AttachWindowsConsole() |
| 103 | { |
no test coverage detected