mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 12:49:36 -06:00
execute_process: Restore termination of processes on timeout
Since commit 5420639a8d (cmExecuteProcessCommand: Replace cmsysProcess
with cmUVProcessChain, 2023-06-01, v3.28.0-rc1~138^2~8) we have not
actually terminated child processes on an `execute_process` timeout.
Similarly for other migrations from cmsysProcess to cmUVProcessChain.
Teach cmUVProcessChain clients that implement timeouts to actually
terminate remaining child processes when the timeout is reached.
Fixes: #27378
This commit is contained in:
@@ -982,6 +982,7 @@ bool cmCTestBuildHandler::RunMakeCommand(const std::string& command,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
chain.Terminate();
|
||||||
cmCTestOptionalLog(this->CTest, WARNING,
|
cmCTestOptionalLog(this->CTest, WARNING,
|
||||||
"There was a timeout" << std::endl, this->Quiet);
|
"There was a timeout" << std::endl, this->Quiet);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1179,6 +1179,7 @@ bool cmCTest::RunMakeCommand(const std::string& command, std::string& output,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
chain.Terminate();
|
||||||
cmCTestLog(this, WARNING, "There was a timeout" << std::endl);
|
cmCTestLog(this, WARNING, "There was a timeout" << std::endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1351,6 +1352,8 @@ bool cmCTest::RunTest(const std::vector<std::string>& argv,
|
|||||||
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
|
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
chain.Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -3611,6 +3614,7 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
|
|||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
|
chain.Terminate();
|
||||||
const char* error_str = "Process terminated due to timeout\n";
|
const char* error_str = "Process terminated due to timeout\n";
|
||||||
cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
|
cmCTestLog(this, ERROR_MESSAGE, error_str << std::endl);
|
||||||
stdErr->append(error_str, strlen(error_str));
|
stdErr->append(error_str, strlen(error_str));
|
||||||
|
|||||||
@@ -391,6 +391,9 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|||||||
!(chain.Finished() && outputData.Finished && errorData.Finished)) {
|
!(chain.Finished() && outputData.Finished && errorData.Finished)) {
|
||||||
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
|
if (timedOut) {
|
||||||
|
chain.Terminate();
|
||||||
|
}
|
||||||
if (!arguments.OutputQuiet &&
|
if (!arguments.OutputQuiet &&
|
||||||
(arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
|
(arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
|
||||||
processOutput.DecodeText(std::string(), strdata, 1);
|
processOutput.DecodeText(std::string(), strdata, 1);
|
||||||
|
|||||||
@@ -696,6 +696,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
|
|||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
|
chain.Terminate();
|
||||||
const char* error_str = "Process terminated due to timeout\n";
|
const char* error_str = "Process terminated due to timeout\n";
|
||||||
if (outputflag != OUTPUT_NONE) {
|
if (outputflag != OUTPUT_NONE) {
|
||||||
std::cerr << error_str << std::endl;
|
std::cerr << error_str << std::endl;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <cm3p/uv.h>
|
#include <cm3p/uv.h>
|
||||||
|
|
||||||
|
#include "cmsys/Process.h"
|
||||||
|
|
||||||
#include "cm_fileno.hxx"
|
#include "cm_fileno.hxx"
|
||||||
|
|
||||||
#include "cmGetPipes.h"
|
#include "cmGetPipes.h"
|
||||||
@@ -58,6 +60,7 @@ struct cmUVProcessChain::InternalData
|
|||||||
const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
|
const cmUVProcessChainBuilder::ProcessConfiguration& config, bool first,
|
||||||
bool last);
|
bool last);
|
||||||
void Finish();
|
void Finish();
|
||||||
|
void Terminate();
|
||||||
};
|
};
|
||||||
|
|
||||||
cmUVProcessChainBuilder::cmUVProcessChainBuilder() = default;
|
cmUVProcessChainBuilder::cmUVProcessChainBuilder() = default;
|
||||||
@@ -388,6 +391,15 @@ void cmUVProcessChain::InternalData::Finish()
|
|||||||
this->Valid = true;
|
this->Valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmUVProcessChain::InternalData::Terminate()
|
||||||
|
{
|
||||||
|
for (std::unique_ptr<ProcessData> const& p : this->Processes) {
|
||||||
|
if (!p->ProcessStatus.Finished) {
|
||||||
|
cmsysProcess_KillPID(static_cast<unsigned long>(p->Process->pid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmUVProcessChain::cmUVProcessChain()
|
cmUVProcessChain::cmUVProcessChain()
|
||||||
: Data(cm::make_unique<InternalData>())
|
: Data(cm::make_unique<InternalData>())
|
||||||
{
|
{
|
||||||
@@ -472,6 +484,11 @@ bool cmUVProcessChain::Finished() const
|
|||||||
return this->Data->ProcessesCompleted >= this->Data->Processes.size();
|
return this->Data->ProcessesCompleted >= this->Data->Processes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmUVProcessChain::Terminate()
|
||||||
|
{
|
||||||
|
this->Data->Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<cmUVProcessChain::ExceptionCode, std::string>
|
std::pair<cmUVProcessChain::ExceptionCode, std::string>
|
||||||
cmUVProcessChain::Status::GetException() const
|
cmUVProcessChain::Status::GetException() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ public:
|
|||||||
const Status& GetStatus(std::size_t index) const;
|
const Status& GetStatus(std::size_t index) const;
|
||||||
bool Finished() const;
|
bool Finished() const;
|
||||||
|
|
||||||
|
/** Terminate any remaining child processes.
|
||||||
|
Call this only after exiting the event loop, and at most once. */
|
||||||
|
void Terminate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class cmUVProcessChainBuilder;
|
friend class cmUVProcessChainBuilder;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user