1919#include " Errors.h"
2020#include " Log.h"
2121#include " Optional.h"
22+ #ifndef BOOST_ALLOW_DEPRECATED_HEADERS
23+ #define BOOST_ALLOW_DEPRECATED_HEADERS
2224#include < boost/process/args.hpp>
2325#include < boost/process/child.hpp>
2426#include < boost/process/env.hpp>
27+ #include < boost/process/error.hpp>
2528#include < boost/process/exe.hpp>
2629#include < boost/process/io.hpp>
2730#include < boost/process/pipe.hpp>
2831#include < boost/process/search_path.hpp>
32+ #undef BOOST_ALLOW_DEPRECATED_HEADERS
33+ #endif
2934#include < fmt/ranges.h>
3035
3136namespace bp = boost::process;
@@ -61,7 +66,7 @@ class AsyncProcessResultImplementation
6166
6267 ~AsyncProcessResultImplementation () = default ;
6368
64- int StartProcess ()
69+ int32 StartProcess ()
6570 {
6671 ASSERT (!my_child, " Process started already!" );
6772
@@ -83,15 +88,22 @@ class AsyncProcessResultImplementation
8388#pragma warning(pop)
8489#endif
8590
86- if (!is_secure)
91+ if (is_secure)
92+ {
93+ TC_LOG_TRACE (logger, R"( Starting process "{}".)" ,
94+ executable);
95+ }
96+ else
8797 {
88- TC_LOG_TRACE (logger, " Starting process \ " {}\ " with arguments: \ " {}\" . " ,
98+ TC_LOG_TRACE (logger, R"( Starting process "{}" with arguments: "{}". ) " ,
8999 executable, fmt::join (args, " " ));
90100 }
91101
92102 // prepare file with only read permission (boost process opens with read_write)
93103 auto inputFile = std::shared_ptr<FILE>(!input_file.empty () ? fopen (input_file.c_str (), " rb" ) : nullptr , [](FILE* f) { if (f) fclose (f); });
94104
105+ std::error_code ec;
106+
95107 // Start the child process
96108 if (inputFile)
97109 {
@@ -101,7 +113,8 @@ class AsyncProcessResultImplementation
101113 bp::env = bp::environment (boost::this_process::environment ()),
102114 bp::std_in = inputFile.get (),
103115 bp::std_out = outStream,
104- bp::std_err = errStream
116+ bp::std_err = errStream,
117+ bp::error = ec
105118 );
106119 }
107120 else
@@ -110,12 +123,19 @@ class AsyncProcessResultImplementation
110123 bp::exe = boost::filesystem::absolute (executable).string (),
111124 bp::args = args,
112125 bp::env = bp::environment (boost::this_process::environment ()),
113- bp::std_in = boost::process ::close,
126+ bp::std_in = bp ::close,
114127 bp::std_out = outStream,
115- bp::std_err = errStream
128+ bp::std_err = errStream,
129+ bp::error = ec
116130 );
117131 }
118132
133+ if (ec)
134+ {
135+ TC_LOG_ERROR (logger, R"( >> Failed to start process "{}": {})" , executable, ec.message ());
136+ return EXIT_FAILURE;
137+ }
138+
119139 std::future<void > stdOutReader = std::async (std::launch::async, [&]
120140 {
121141 std::string line;
@@ -138,19 +158,15 @@ class AsyncProcessResultImplementation
138158 }
139159 });
140160
141- std::error_code ec;
142161 my_child->wait (ec);
143162 int32 const result = !ec && !was_terminated ? my_child->exit_code () : EXIT_FAILURE;
144163 my_child.reset ();
145164
146165 stdOutReader.wait ();
147166 stdErrReader.wait ();
148167
149- if (!is_secure)
150- {
151- TC_LOG_TRACE (logger, " >> Process \" {}\" finished with return value {}." ,
152- executable, result);
153- }
168+ TC_LOG_TRACE (logger, R"( >> Process "{}" finished with return value {}.)" ,
169+ executable, result);
154170
155171 return result;
156172 }
@@ -180,7 +196,7 @@ class AsyncProcessResultImplementation
180196 }
181197};
182198
183- int StartProcess (std::string executable, std::vector<std::string> args,
199+ int32 StartProcess (std::string executable, std::vector<std::string> args,
184200 std::string logger, std::string input_file, bool secure)
185201{
186202 AsyncProcessResultImplementation handle (
0 commit comments