The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
log_windows.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2014 - 2025
3 by Iris Morelle <shadowm2006@gmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16// For some reason, it became necessary to include this before the header
17// after switching to c++11
18#include <cstdio>
19
20#include "log_windows.hpp"
21
22#include "filesystem.hpp"
23#include "log.hpp"
25
26#include <iomanip>
27#include <iostream>
28
29#include <boost/algorithm/string/predicate.hpp>
30
31#ifndef UNICODE
32#define UNICODE
33#endif
34
35#define WIN32_LEAN_AND_MEAN
36
37#include <windows.h>
38
39static lg::log_domain log_setup("logsetup");
40#define ERR_LS LOG_STREAM(err, log_setup)
41#define WRN_LS LOG_STREAM(warn, log_setup)
42#define LOG_LS LOG_STREAM(info, log_setup)
43#define DBG_LS LOG_STREAM(debug, log_setup)
44
45namespace lg
46{
47
48namespace
49{
50/**
51 * Singleton class that handles sending logging output to a console on windows.
52 */
53class console_handler
54{
55public:
56 console_handler(const console_handler&) = delete;
57 console_handler& operator=(const console_handler&) = delete;
58
59 console_handler();
60
61 /**
62 * Returns whether we own the console we are attached to, if any.
63 */
64 bool owns_console() const;
65
66private:
67 bool created_wincon_;
68
69 /**
70 * Switches to using a native console.
71 */
72 void enable_native_console_output();
73};
74
75console_handler::console_handler()
76 : created_wincon_(false)
77{
78 DBG_LS << "Early init message";
79
80 if(GetConsoleWindow() != nullptr) {
81 // Someone already attached a console to us. Assume we were compiled
82 // with the console subsystem flag and that the standard streams are
83 // already pointing to the console.
84 LOG_LS << "Console already attached at startup (built with console subsystem flag?), log file disabled.";
85 } else {
86 enable_native_console_output();
87 }
88
89 DBG_LS << "Windows console init complete!";
90}
91
92bool console_handler::owns_console() const
93{
94 return created_wincon_;
95}
96
97void console_handler::enable_native_console_output()
98{
99 if(AttachConsole(ATTACH_PARENT_PROCESS)) {
100 LOG_LS << "Attached parent process console.";
101 } else if(AllocConsole()) {
102 LOG_LS << "Allocated own console.";
103 created_wincon_ = true;
104 } else {
105 // Wine as of version 4.21 just goes ERROR_ACCESS_DENIED when trying
106 // to allocate a console for a GUI subsystem application. We can ignore
107 // this since the user purportedly knows what they're doing and if they
108 // get radio silence from Wesnoth and no log files they'll realize that
109 // something went wrong.
110 WRN_LS << "Cannot attach or allocate a console, continuing anyway (is this Wine?)";
111 }
112
113 DBG_LS << "stderr to console";
114 fflush(stderr);
115 std::cerr.flush();
116 assert(freopen("CONOUT$", "wb", stderr) == stderr);
117
118 DBG_LS << "stdout to console";
119 fflush(stdout);
120 std::cout.flush();
121 assert(freopen("CONOUT$", "wb", stdout) == stdout);
122
123 DBG_LS << "stdin from console";
124 assert(freopen("CONIN$", "rb", stdin) == stdin);
125
126 LOG_LS << "Console streams handover complete!";
127}
128
129std::unique_ptr<console_handler> lfm;
130
131} // end anonymous namespace
132
134{
135 if(!lfm) {
136 lfm.reset(new console_handler());
137 }
138}
139
141{
142 return lfm && lfm->owns_console();
143}
144
145} // end namespace lg
Declarations for File-IO.
#define WRN_LS
#define LOG_LS
#define DBG_LS
Definition log.cpp:49
Standard logging facilities (interface).
static lg::log_domain log_setup("logsetup")
Definition pump.hpp:41
bool using_own_console()
Returns true if a console was allocated by the Wesnoth process.
void do_console_redirect()
Allocates a console if needed and redirects output to CONOUT.