diff --git a/src/logging.hpp b/src/logging.hpp index 43cc69f..1dcbbaf 100644 --- a/src/logging.hpp +++ b/src/logging.hpp @@ -26,6 +26,10 @@ template inline void print_message(FILE* fp, Level level, const char* fmt_s, const char* file, const char* func, int line, Args... args) { + // TODO: Better coding + void initialize_stderr(); + initialize_stderr(); + // TODO: Better coding fmt::print( fp, "{}: [thread {} TS: {}]: {}:{}:{} {}\n", levels[static_cast(level)], diff --git a/src/win32/windows_utils.cpp b/src/win32/windows_utils.cpp index 46aade2..afc7225 100644 --- a/src/win32/windows_utils.cpp +++ b/src/win32/windows_utils.cpp @@ -8,7 +8,11 @@ #include #include -typedef void* HWND; +// TODO: Fix the Windows header +// typedef void* HWND; +#define WIN32_LEAN_AND_MEAN +#include +// TODO: Fix the Windows header #include #include @@ -22,12 +26,52 @@ typedef void* HWND; #include #include +#include #include #include +#include #include #include #include +namespace ra2yrcpp::logging { + +static std::once_flag stderr_initialized; + +void initialize_stderr() { + std::call_once(stderr_initialized, []() { + // Ignore the result here, like what we do in gamemd-spawn.exe + AllocConsole(); + + // Check if the stderr is as expected + /* + * When `stdin`, `stdout`, and `stderr` aren't associated with a stream (for + * example, in a Windows application without a console window), the file + * descriptor values for these streams are returned from `_fileno` as the + * special value -2. ... + * https://learn.microsoft.com/cpp/c-runtime-library/reference/get-osfhandle + */ + if (fileno(stderr) == -2) { + // Code copied from: + // https://github.com/ocaml/ocaml/issues/9252#issuecomment-576383814 + // https://web.archive.org/web/20230601042758/https://social.msdn.microsoft.com/Forums/windows/en-US/286059e8-9163-4679-9663-efc63c5d9c53/allocconsole-backspace-and-newline-characters-incorrectly-printed-after-quotsystemquot-call?forum=vcgeneral#68a73761-7a40-4d4c-a15e-90902a1244ee-isAnswer + auto fd_stderr = _open_osfhandle((intptr_t)GetStdHandle(STD_ERROR_HANDLE), + _O_WRONLY | _O_BINARY); + + if (fd_stderr) { + dup2(fd_stderr, 2); + close(fd_stderr); + SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(2)); + } + + *stderr = *(fdopen(2, "wb")); + setvbuf(stderr, NULL, _IONBF, 0); + } + }); +} + +} // namespace ra2yrcpp::logging + using namespace windows_utils; void* windows_utils::load_library(std::string name) {