|
19 | 19 | #include "Errors.h" |
20 | 20 | #include "Log.h" |
21 | 21 | #include "Optional.h" |
22 | | - |
23 | | -#include <boost/algorithm/string/join.hpp> |
24 | | -#include <boost/iostreams/copy.hpp> |
25 | 22 | #include <boost/process/args.hpp> |
26 | 23 | #include <boost/process/child.hpp> |
27 | 24 | #include <boost/process/env.hpp> |
28 | 25 | #include <boost/process/exe.hpp> |
29 | 26 | #include <boost/process/io.hpp> |
30 | 27 | #include <boost/process/pipe.hpp> |
31 | 28 | #include <boost/process/search_path.hpp> |
| 29 | +#include <fmt/ranges.h> |
32 | 30 |
|
33 | 31 | using namespace boost::process; |
34 | | -using namespace boost::iostreams; |
35 | 32 |
|
36 | 33 | namespace Trinity |
37 | 34 | { |
38 | | - |
39 | | -template<typename T> |
40 | | -class TCLogSink |
41 | | -{ |
42 | | - T callback_; |
43 | | - |
44 | | -public: |
45 | | - typedef char char_type; |
46 | | - typedef sink_tag category; |
47 | | - |
48 | | - // Requires a callback type which has a void(std::string) signature |
49 | | - TCLogSink(T callback) |
50 | | - : callback_(std::move(callback)) { } |
51 | | - |
52 | | - std::streamsize write(char const* str, std::streamsize size) |
53 | | - { |
54 | | - std::string_view consoleStr(str, size); |
55 | | - size_t lineEnd = consoleStr.find_first_of("\r\n"); |
56 | | - std::streamsize processedCharacters = size; |
57 | | - if (lineEnd != std::string_view::npos) |
58 | | - { |
59 | | - consoleStr = consoleStr.substr(0, lineEnd); |
60 | | - processedCharacters = lineEnd + 1; |
61 | | - } |
62 | | - |
63 | | - if (!consoleStr.empty()) |
64 | | - callback_(consoleStr); |
65 | | - |
66 | | - return processedCharacters; |
67 | | - } |
68 | | -}; |
69 | | - |
70 | | -template<typename T> |
71 | | -auto MakeTCLogSink(T&& callback) |
72 | | - -> TCLogSink<typename std::decay<T>::type> |
73 | | -{ |
74 | | - return { std::forward<T>(callback) }; |
75 | | -} |
76 | | - |
77 | 35 | template<typename T> |
78 | 36 | static int CreateChildProcess(T waiter, std::string const& executable, |
79 | 37 | std::vector<std::string> const& argsVector, |
@@ -101,15 +59,11 @@ static int CreateChildProcess(T waiter, std::string const& executable, |
101 | 59 | if (!secure) |
102 | 60 | { |
103 | 61 | TC_LOG_TRACE(logger, "Starting process \"{}\" with arguments: \"{}\".", |
104 | | - executable, boost::algorithm::join(argsVector, " ")); |
| 62 | + executable, fmt::join(argsVector, " ")); |
105 | 63 | } |
106 | 64 |
|
107 | 65 | // prepare file with only read permission (boost process opens with read_write) |
108 | | - std::shared_ptr<FILE> inputFile(!input.empty() ? fopen(input.c_str(), "rb") : nullptr, [](FILE* ptr) |
109 | | - { |
110 | | - if (ptr != nullptr) |
111 | | - fclose(ptr); |
112 | | - }); |
| 66 | + auto inputFile = std::shared_ptr<FILE>(!input.empty() ? fopen(input.c_str(), "rb") : nullptr, [](FILE* f) { if (f) fclose(f); }); |
113 | 67 |
|
114 | 68 | // Start the child process |
115 | 69 | child c = [&]() |
@@ -140,18 +94,20 @@ static int CreateChildProcess(T waiter, std::string const& executable, |
140 | 94 | } |
141 | 95 | }(); |
142 | 96 |
|
143 | | - auto outInfo = MakeTCLogSink([&](std::string_view msg) |
| 97 | + std::string line; |
| 98 | + while (std::getline(outStream, line, '\n')) |
144 | 99 | { |
145 | | - TC_LOG_INFO(logger, "{}", msg); |
146 | | - }); |
| 100 | + std::erase(line, '\r'); |
| 101 | + if (!line.empty()) |
| 102 | + TC_LOG_INFO(logger, "{}", line); |
| 103 | + } |
147 | 104 |
|
148 | | - auto outError = MakeTCLogSink([&](std::string_view msg) |
| 105 | + while (std::getline(errStream, line, '\n')) |
149 | 106 | { |
150 | | - TC_LOG_ERROR(logger, "{}", msg); |
151 | | - }); |
152 | | - |
153 | | - copy(outStream, outInfo); |
154 | | - copy(errStream, outError); |
| 107 | + std::erase(line, '\r'); |
| 108 | + if (!line.empty()) |
| 109 | + TC_LOG_ERROR(logger, "{}", line); |
| 110 | + } |
155 | 111 |
|
156 | 112 | // Call the waiter in the current scope to prevent |
157 | 113 | // the streams from closing too early on leaving the scope. |
|
0 commit comments