mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-11 01:29:36 -06:00
cmUVProcessChain: Open output streams automatically
Avoid repeating the logic at every call site.
This commit is contained in:
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
#include <cm/filesystem>
|
#include <cm/filesystem>
|
||||||
|
|
||||||
#include <cm3p/uv.h>
|
|
||||||
|
|
||||||
#include "cmBuildArgs.h"
|
#include "cmBuildArgs.h"
|
||||||
#include "cmBuildOptions.h"
|
#include "cmBuildOptions.h"
|
||||||
#include "cmCTest.h"
|
#include "cmCTest.h"
|
||||||
@@ -22,7 +20,6 @@
|
|||||||
#include "cmState.h"
|
#include "cmState.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmUVHandlePtr.h"
|
|
||||||
#include "cmUVProcessChain.h"
|
#include "cmUVProcessChain.h"
|
||||||
#include "cmUVStream.h"
|
#include "cmUVStream.h"
|
||||||
#include "cmWorkingDirectory.h"
|
#include "cmWorkingDirectory.h"
|
||||||
@@ -94,11 +91,8 @@ bool cmCTestBuildAndTest::RunTest(std::vector<std::string> const& argv,
|
|||||||
auto chain = builder.Start();
|
auto chain = builder.Start();
|
||||||
|
|
||||||
cmProcessOutput processOutput(cmProcessOutput::Auto);
|
cmProcessOutput processOutput(cmProcessOutput::Auto);
|
||||||
cm::uv_pipe_ptr outputStream;
|
|
||||||
outputStream.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(outputStream, chain.OutputStream());
|
|
||||||
auto outputHandle = cmUVStreamRead(
|
auto outputHandle = cmUVStreamRead(
|
||||||
outputStream,
|
chain.OutputStream(),
|
||||||
[&processOutput](std::vector<char> data) {
|
[&processOutput](std::vector<char> data) {
|
||||||
std::string decoded;
|
std::string decoded;
|
||||||
processOutput.DecodeText(data.data(), data.size(), decoded);
|
processOutput.DecodeText(data.data(), data.size(), decoded);
|
||||||
|
|||||||
@@ -872,18 +872,14 @@ bool cmCTestBuildHandler::RunMakeCommand(std::string const& command,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For every chunk of data
|
// For every chunk of data
|
||||||
cm::uv_pipe_ptr outputStream;
|
|
||||||
bool outFinished = false;
|
bool outFinished = false;
|
||||||
cm::uv_pipe_ptr errorStream;
|
|
||||||
bool errFinished = false;
|
bool errFinished = false;
|
||||||
auto startRead = [this, &chain, &processOutput, &tick,
|
auto startRead = [this, &processOutput, &tick,
|
||||||
&ofs](cm::uv_pipe_ptr& pipe, int stream,
|
&ofs](uv_stream_t* stream,
|
||||||
t_BuildProcessingQueueType& queue, bool& finished,
|
t_BuildProcessingQueueType& queue, bool& finished,
|
||||||
int id) -> std::unique_ptr<cmUVStreamReadHandle> {
|
int id) -> std::unique_ptr<cmUVStreamReadHandle> {
|
||||||
pipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(pipe, stream);
|
|
||||||
return cmUVStreamRead(
|
return cmUVStreamRead(
|
||||||
pipe,
|
stream,
|
||||||
[this, &processOutput, &queue, id, &tick, &ofs](std::vector<char> data) {
|
[this, &processOutput, &queue, id, &tick, &ofs](std::vector<char> data) {
|
||||||
// Replace '\0' with '\n', since '\0' does not really make sense. This
|
// Replace '\0' with '\n', since '\0' does not really make sense. This
|
||||||
// is for Visual Studio output
|
// is for Visual Studio output
|
||||||
@@ -909,11 +905,10 @@ bool cmCTestBuildHandler::RunMakeCommand(std::string const& command,
|
|||||||
finished = true;
|
finished = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
auto outputHandle = startRead(outputStream, chain.OutputStream(),
|
auto outputHandle = startRead(chain.OutputStream(),
|
||||||
this->BuildProcessingQueue, outFinished, 1);
|
this->BuildProcessingQueue, outFinished, 1);
|
||||||
auto errorHandle =
|
auto errorHandle = startRead(
|
||||||
startRead(errorStream, chain.ErrorStream(),
|
chain.ErrorStream(), this->BuildProcessingErrorQueue, errFinished, 2);
|
||||||
this->BuildProcessingErrorQueue, errFinished, 2);
|
|
||||||
|
|
||||||
while (!timedOut && !(outFinished && errFinished && chain.Finished())) {
|
while (!timedOut && !(outFinished && errFinished && chain.Finished())) {
|
||||||
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
#include "cmStateSnapshot.h"
|
#include "cmStateSnapshot.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmUVHandlePtr.h"
|
|
||||||
#include "cmUVProcessChain.h"
|
#include "cmUVProcessChain.h"
|
||||||
#include "cmUVStream.h"
|
#include "cmUVStream.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
@@ -236,23 +235,19 @@ void cmCTestLaunch::RunChild()
|
|||||||
auto chain = builder.Start();
|
auto chain = builder.Start();
|
||||||
|
|
||||||
// Record child stdout and stderr if necessary.
|
// Record child stdout and stderr if necessary.
|
||||||
cm::uv_pipe_ptr outPipe;
|
|
||||||
cm::uv_pipe_ptr errPipe;
|
|
||||||
bool outFinished = true;
|
bool outFinished = true;
|
||||||
bool errFinished = true;
|
bool errFinished = true;
|
||||||
cmProcessOutput processOutput;
|
cmProcessOutput processOutput;
|
||||||
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
||||||
std::unique_ptr<cmUVStreamReadHandle> errorHandle;
|
std::unique_ptr<cmUVStreamReadHandle> errorHandle;
|
||||||
if (!this->Reporter.Passthru) {
|
if (!this->Reporter.Passthru) {
|
||||||
auto beginRead = [&chain, &processOutput](
|
auto beginRead =
|
||||||
cm::uv_pipe_ptr& pipe, int stream, std::ostream& out,
|
[&processOutput](uv_stream_t* stream, std::ostream& out,
|
||||||
cmsys::ofstream& file, bool& haveData, bool& finished,
|
cmsys::ofstream& file, bool& haveData, bool& finished,
|
||||||
int id) -> std::unique_ptr<cmUVStreamReadHandle> {
|
int id) -> std::unique_ptr<cmUVStreamReadHandle> {
|
||||||
pipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(pipe, stream);
|
|
||||||
finished = false;
|
finished = false;
|
||||||
return cmUVStreamRead(
|
return cmUVStreamRead(
|
||||||
pipe,
|
stream,
|
||||||
[&processOutput, &out, &file, id, &haveData](std::vector<char> data) {
|
[&processOutput, &out, &file, id, &haveData](std::vector<char> data) {
|
||||||
std::string strdata;
|
std::string strdata;
|
||||||
processOutput.DecodeText(data.data(), data.size(), strdata, id);
|
processOutput.DecodeText(data.data(), data.size(), strdata, id);
|
||||||
@@ -270,9 +265,9 @@ void cmCTestLaunch::RunChild()
|
|||||||
finished = true;
|
finished = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
outputHandle = beginRead(outPipe, chain.OutputStream(), std::cout, fout,
|
outputHandle = beginRead(chain.OutputStream(), std::cout, fout,
|
||||||
this->HaveOut, outFinished, 1);
|
this->HaveOut, outFinished, 1);
|
||||||
errorHandle = beginRead(errPipe, chain.ErrorStream(), std::cerr, ferr,
|
errorHandle = beginRead(chain.ErrorStream(), std::cerr, ferr,
|
||||||
this->HaveErr, errFinished, 2);
|
this->HaveErr, errFinished, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
#include <cm/memory>
|
#include <cm/memory>
|
||||||
|
|
||||||
#include <cm3p/uv.h>
|
|
||||||
|
|
||||||
#include "cmCTest.h"
|
#include "cmCTest.h"
|
||||||
#include "cmCTestBuildCommand.h"
|
#include "cmCTestBuildCommand.h"
|
||||||
#include "cmCTestConfigureCommand.h"
|
#include "cmCTestConfigureCommand.h"
|
||||||
@@ -33,7 +31,6 @@
|
|||||||
#include "cmStateDirectory.h"
|
#include "cmStateDirectory.h"
|
||||||
#include "cmStateSnapshot.h"
|
#include "cmStateSnapshot.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmUVHandlePtr.h"
|
|
||||||
#include "cmUVProcessChain.h"
|
#include "cmUVProcessChain.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
@@ -107,20 +104,14 @@ int cmCTestScriptHandler::ExecuteScript(std::string const& total_script_arg)
|
|||||||
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
|
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
|
||||||
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
|
.SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
|
||||||
auto process = builder.Start();
|
auto process = builder.Start();
|
||||||
cm::uv_pipe_ptr outPipe;
|
|
||||||
outPipe.init(process.GetLoop(), 0);
|
|
||||||
uv_pipe_open(outPipe, process.OutputStream());
|
|
||||||
cm::uv_pipe_ptr errPipe;
|
|
||||||
errPipe.init(process.GetLoop(), 0);
|
|
||||||
uv_pipe_open(errPipe, process.ErrorStream());
|
|
||||||
|
|
||||||
std::vector<char> out;
|
std::vector<char> out;
|
||||||
std::vector<char> err;
|
std::vector<char> err;
|
||||||
std::string line;
|
std::string line;
|
||||||
cmSystemTools::WaitForLineResult pipe;
|
cmSystemTools::WaitForLineResult pipe;
|
||||||
while ((pipe = cmSystemTools::WaitForLine(&process.GetLoop(), outPipe,
|
while ((pipe = cmSystemTools::WaitForLine(
|
||||||
errPipe, line, out, err)) !=
|
&process.GetLoop(), process.OutputStream(), process.ErrorStream(),
|
||||||
cmSystemTools::WaitForLineResult::None) {
|
line, out, err)) != cmSystemTools::WaitForLineResult::None) {
|
||||||
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||||
"Output: " << line << "\n");
|
"Output: " << line << "\n");
|
||||||
if (pipe == cmSystemTools::WaitForLineResult::STDERR) {
|
if (pipe == cmSystemTools::WaitForLineResult::STDERR) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ bool cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool::GetFileInfo(
|
|||||||
static cmsys::RegularExpression const neededRegex("^ *NEEDED *([^\n]*)$");
|
static cmsys::RegularExpression const neededRegex("^ *NEEDED *([^\n]*)$");
|
||||||
static cmsys::RegularExpression const rpathRegex("^ *RPATH *([^\n]*)$");
|
static cmsys::RegularExpression const rpathRegex("^ *RPATH *([^\n]*)$");
|
||||||
static cmsys::RegularExpression const runpathRegex("^ *RUNPATH *([^\n]*)$");
|
static cmsys::RegularExpression const runpathRegex("^ *RUNPATH *([^\n]*)$");
|
||||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
cmUVIStream output(process.OutputStream());
|
||||||
while (std::getline(output, line)) {
|
while (std::getline(output, line)) {
|
||||||
cmsys::RegularExpressionMatch match;
|
cmsys::RegularExpressionMatch match;
|
||||||
if (neededRegex.find(line.c_str(), match)) {
|
if (neededRegex.find(line.c_str(), match)) {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo(
|
|||||||
"^ *path (.*) \\(offset [0-9]+\\)$");
|
"^ *path (.*) \\(offset [0-9]+\\)$");
|
||||||
static cmsys::RegularExpression const nameRegex(
|
static cmsys::RegularExpression const nameRegex(
|
||||||
"^ *name (.*) \\(offset [0-9]+\\)$");
|
"^ *name (.*) \\(offset [0-9]+\\)$");
|
||||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
cmUVIStream output(process.OutputStream());
|
||||||
while (std::getline(output, line)) {
|
while (std::getline(output, line)) {
|
||||||
cmsys::RegularExpressionMatch cmdMatch;
|
cmsys::RegularExpressionMatch cmdMatch;
|
||||||
if (rpathRegex.find(line.c_str(), cmdMatch)) {
|
if (rpathRegex.find(line.c_str(), cmdMatch)) {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ bool cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool::GetFileInfo(
|
|||||||
std::string line;
|
std::string line;
|
||||||
static cmsys::RegularExpression const regex(
|
static cmsys::RegularExpression const regex(
|
||||||
"^ ([^\n]*\\.[Dd][Ll][Ll])\r$");
|
"^ ([^\n]*\\.[Dd][Ll][Ll])\r$");
|
||||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
cmUVIStream output(process.OutputStream());
|
||||||
while (std::getline(output, line)) {
|
while (std::getline(output, line)) {
|
||||||
cmsys::RegularExpressionMatch match;
|
cmsys::RegularExpressionMatch match;
|
||||||
if (regex.find(line.c_str(), match)) {
|
if (regex.find(line.c_str(), match)) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ bool cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool::GetFileInfo(
|
|||||||
std::string line;
|
std::string line;
|
||||||
static cmsys::RegularExpression const regex(
|
static cmsys::RegularExpression const regex(
|
||||||
"^[\t ]*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])$");
|
"^[\t ]*DLL Name: ([^\n]*\\.[Dd][Ll][Ll])$");
|
||||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
cmUVIStream output(process.OutputStream());
|
||||||
while (cmSystemTools::GetLineFromStream(output, line)) {
|
while (cmSystemTools::GetLineFromStream(output, line)) {
|
||||||
cmsys::RegularExpressionMatch match;
|
cmsys::RegularExpressionMatch match;
|
||||||
if (regex.find(line.c_str(), match)) {
|
if (regex.find(line.c_str(), match)) {
|
||||||
|
|||||||
@@ -921,9 +921,7 @@ bool cmCTest::RunMakeCommand(std::string const& command, std::string& output,
|
|||||||
builder.SetWorkingDirectory(dir);
|
builder.SetWorkingDirectory(dir);
|
||||||
}
|
}
|
||||||
auto chain = builder.Start();
|
auto chain = builder.Start();
|
||||||
cm::uv_pipe_ptr outputStream;
|
uv_stream_t* outputStream = chain.OutputStream();
|
||||||
outputStream.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(outputStream, chain.OutputStream());
|
|
||||||
|
|
||||||
// Initialize tick's
|
// Initialize tick's
|
||||||
std::string::size_type tick = 0;
|
std::string::size_type tick = 0;
|
||||||
@@ -3294,19 +3292,14 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
|
|||||||
|
|
||||||
std::vector<char> tempOutput;
|
std::vector<char> tempOutput;
|
||||||
bool outFinished = false;
|
bool outFinished = false;
|
||||||
cm::uv_pipe_ptr outStream;
|
|
||||||
std::vector<char> tempError;
|
std::vector<char> tempError;
|
||||||
bool errFinished = false;
|
bool errFinished = false;
|
||||||
cm::uv_pipe_ptr errStream;
|
|
||||||
cmProcessOutput processOutput(encoding);
|
cmProcessOutput processOutput(encoding);
|
||||||
auto startRead = [this, &chain, &processOutput](
|
auto startRead = [this, &processOutput](
|
||||||
cm::uv_pipe_ptr& pipe, int stream,
|
uv_stream_t* stream, std::vector<char>& temp,
|
||||||
std::vector<char>& temp,
|
|
||||||
bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
|
bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
|
||||||
pipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(pipe, stream);
|
|
||||||
return cmUVStreamRead(
|
return cmUVStreamRead(
|
||||||
pipe,
|
stream,
|
||||||
[this, &temp, &processOutput](std::vector<char> data) {
|
[this, &temp, &processOutput](std::vector<char> data) {
|
||||||
cm::append(temp, data);
|
cm::append(temp, data);
|
||||||
if (this->Impl->ExtraVerbose) {
|
if (this->Impl->ExtraVerbose) {
|
||||||
@@ -3317,10 +3310,8 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
|
|||||||
},
|
},
|
||||||
[&finished]() { finished = true; });
|
[&finished]() { finished = true; });
|
||||||
};
|
};
|
||||||
auto outputHandle =
|
auto outputHandle = startRead(chain.OutputStream(), tempOutput, outFinished);
|
||||||
startRead(outStream, chain.OutputStream(), tempOutput, outFinished);
|
auto errorHandle = startRead(chain.ErrorStream(), tempError, errFinished);
|
||||||
auto errorHandle =
|
|
||||||
startRead(errStream, chain.ErrorStream(), tempError, errFinished);
|
|
||||||
while (!timedOut && !(outFinished && errFinished)) {
|
while (!timedOut && !(outFinished && errFinished)) {
|
||||||
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
uv_run(&chain.GetLoop(), UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,12 +326,14 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|||||||
// Read the process output.
|
// Read the process output.
|
||||||
struct ReadData
|
struct ReadData
|
||||||
{
|
{
|
||||||
|
uv_stream_t* Stream = nullptr;
|
||||||
bool Finished = false;
|
bool Finished = false;
|
||||||
std::vector<char> Output;
|
std::vector<char> Output;
|
||||||
cm::uv_pipe_ptr Stream;
|
|
||||||
};
|
};
|
||||||
ReadData outputData;
|
ReadData outputData;
|
||||||
ReadData errorData;
|
ReadData errorData;
|
||||||
|
outputData.Stream = chain.OutputStream();
|
||||||
|
errorData.Stream = chain.ErrorStream();
|
||||||
cmPolicies::PolicyStatus const cmp0176 =
|
cmPolicies::PolicyStatus const cmp0176 =
|
||||||
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0176);
|
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0176);
|
||||||
cmProcessOutput::Encoding encoding =
|
cmProcessOutput::Encoding encoding =
|
||||||
@@ -353,9 +355,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|||||||
std::string strdata;
|
std::string strdata;
|
||||||
|
|
||||||
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
||||||
if (chain.OutputStream() >= 0) {
|
if (outputData.Stream) {
|
||||||
outputData.Stream.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(outputData.Stream, chain.OutputStream());
|
|
||||||
outputHandle = cmUVStreamRead(
|
outputHandle = cmUVStreamRead(
|
||||||
outputData.Stream,
|
outputData.Stream,
|
||||||
[&arguments, &processOutput, &outputData,
|
[&arguments, &processOutput, &outputData,
|
||||||
@@ -377,9 +377,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
|
|||||||
outputData.Finished = true;
|
outputData.Finished = true;
|
||||||
}
|
}
|
||||||
std::unique_ptr<cmUVStreamReadHandle> errorHandle;
|
std::unique_ptr<cmUVStreamReadHandle> errorHandle;
|
||||||
if (chain.ErrorStream() >= 0) {
|
if (errorData.Stream) {
|
||||||
errorData.Stream.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(errorData.Stream, chain.ErrorStream());
|
|
||||||
errorHandle = cmUVStreamRead(
|
errorHandle = cmUVStreamRead(
|
||||||
errorData.Stream,
|
errorData.Stream,
|
||||||
[&arguments, &processOutput, &errorData,
|
[&arguments, &processOutput, &errorData,
|
||||||
|
|||||||
@@ -201,10 +201,8 @@ void InstallScriptRunner::start(cm::uv_loop_ptr& loop,
|
|||||||
.SetExternalLoop(*loop)
|
.SetExternalLoop(*loop)
|
||||||
.SetMergedBuiltinStreams();
|
.SetMergedBuiltinStreams();
|
||||||
this->chain = cm::make_unique<cmUVProcessChain>(builder.Start());
|
this->chain = cm::make_unique<cmUVProcessChain>(builder.Start());
|
||||||
this->pipe.init(this->chain->GetLoop(), 0);
|
|
||||||
uv_pipe_open(this->pipe, this->chain->OutputStream());
|
|
||||||
this->streamHandler = cmUVStreamRead(
|
this->streamHandler = cmUVStreamRead(
|
||||||
this->pipe,
|
this->chain->OutputStream(),
|
||||||
[this](std::vector<char> data) {
|
[this](std::vector<char> data) {
|
||||||
std::string strdata;
|
std::string strdata;
|
||||||
cmProcessOutput(cmProcessOutput::Auto)
|
cmProcessOutput(cmProcessOutput::Auto)
|
||||||
|
|||||||
@@ -8,10 +8,13 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "cmUVHandlePtr.h"
|
|
||||||
#include "cmUVProcessChain.h"
|
#include "cmUVProcessChain.h"
|
||||||
#include "cmUVStream.h"
|
#include "cmUVStream.h"
|
||||||
|
|
||||||
|
namespace cm {
|
||||||
|
class uv_loop_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
class cmInstrumentation;
|
class cmInstrumentation;
|
||||||
|
|
||||||
class cmInstallScriptHandler
|
class cmInstallScriptHandler
|
||||||
@@ -42,7 +45,6 @@ public:
|
|||||||
std::string name;
|
std::string name;
|
||||||
std::unique_ptr<cmUVProcessChain> chain;
|
std::unique_ptr<cmUVProcessChain> chain;
|
||||||
std::unique_ptr<cmUVStreamReadHandle> streamHandler;
|
std::unique_ptr<cmUVStreamReadHandle> streamHandler;
|
||||||
cm::uv_pipe_ptr pipe;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
|
|||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
static cmsys::RegularExpression const regex("^([^\t:]*):");
|
static cmsys::RegularExpression const regex("^([^\t:]*):");
|
||||||
cmUVPipeIStream output(process.GetLoop(), process.OutputStream());
|
cmUVIStream output(process.OutputStream());
|
||||||
while (std::getline(output, line)) {
|
while (std::getline(output, line)) {
|
||||||
cmsys::RegularExpressionMatch match;
|
cmsys::RegularExpressionMatch match;
|
||||||
if (regex.find(line.c_str(), match)) {
|
if (regex.find(line.c_str(), match)) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ cm::optional<Json::Value> cmParsePlist(std::string const& filename)
|
|||||||
|
|
||||||
Json::Reader reader;
|
Json::Reader reader;
|
||||||
Json::Value value;
|
Json::Value value;
|
||||||
cmUVPipeIStream outputStream(chain.GetLoop(), chain.OutputStream());
|
cmUVIStream outputStream(chain.OutputStream());
|
||||||
if (!reader.parse(outputStream, value)) {
|
if (!reader.parse(outputStream, value)) {
|
||||||
return cm::nullopt;
|
return cm::nullopt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include <cm3p/uv.h>
|
#include <cm3p/uv.h>
|
||||||
|
|
||||||
#include "cmProcessOutput.h"
|
#include "cmProcessOutput.h"
|
||||||
#include "cmUVHandlePtr.h"
|
|
||||||
#include "cmUVStream.h"
|
#include "cmUVStream.h"
|
||||||
|
|
||||||
std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
|
std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
|
||||||
@@ -24,11 +23,8 @@ std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
|
|||||||
auto chain = builder.Start();
|
auto chain = builder.Start();
|
||||||
|
|
||||||
std::string strdata;
|
std::string strdata;
|
||||||
cm::uv_pipe_ptr outputPipe;
|
|
||||||
outputPipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(outputPipe, chain.OutputStream());
|
|
||||||
auto outputHandle = cmUVStreamRead(
|
auto outputHandle = cmUVStreamRead(
|
||||||
outputPipe,
|
chain.OutputStream(),
|
||||||
[&out, &processOutput, &strdata](std::vector<char> data) {
|
[&out, &processOutput, &strdata](std::vector<char> data) {
|
||||||
if (out) {
|
if (out) {
|
||||||
processOutput.DecodeText(data.data(), data.size(), strdata, 1);
|
processOutput.DecodeText(data.data(), data.size(), strdata, 1);
|
||||||
@@ -38,11 +34,8 @@ std::vector<cmUVProcessChain::Status> cmProcessTools::RunProcess(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&out]() { out = nullptr; });
|
[&out]() { out = nullptr; });
|
||||||
cm::uv_pipe_ptr errorPipe;
|
|
||||||
errorPipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(errorPipe, chain.ErrorStream());
|
|
||||||
auto errorHandle = cmUVStreamRead(
|
auto errorHandle = cmUVStreamRead(
|
||||||
errorPipe,
|
chain.ErrorStream(),
|
||||||
[&err, &processOutput, &strdata](std::vector<char> data) {
|
[&err, &processOutput, &strdata](std::vector<char> data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
processOutput.DecodeText(data.data(), data.size(), strdata, 2);
|
processOutput.DecodeText(data.data(), data.size(), strdata, 2);
|
||||||
|
|||||||
@@ -896,9 +896,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
|
|||||||
|
|
||||||
std::vector<char> tempStdOut;
|
std::vector<char> tempStdOut;
|
||||||
std::vector<char> tempStdErr;
|
std::vector<char> tempStdErr;
|
||||||
cm::uv_pipe_ptr outStream;
|
|
||||||
bool outFinished = true;
|
bool outFinished = true;
|
||||||
cm::uv_pipe_ptr errStream;
|
|
||||||
bool errFinished = true;
|
bool errFinished = true;
|
||||||
cmProcessOutput processOutput(encoding);
|
cmProcessOutput processOutput(encoding);
|
||||||
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
std::unique_ptr<cmUVStreamReadHandle> outputHandle;
|
||||||
@@ -906,21 +904,14 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
|
|||||||
if (outputflag != OUTPUT_PASSTHROUGH &&
|
if (outputflag != OUTPUT_PASSTHROUGH &&
|
||||||
(captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
|
(captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
|
||||||
auto startRead =
|
auto startRead =
|
||||||
[&outputflag, &processOutput,
|
[&outputflag, &processOutput](
|
||||||
&chain](cm::uv_pipe_ptr& pipe, int stream, std::string* captureStd,
|
uv_stream_t* stream, std::string* captureStd,
|
||||||
std::vector<char>& tempStd, int id,
|
std::vector<char>& tempStd, int id,
|
||||||
void (*outputFunc)(std::string const&),
|
void (*outputFunc)(std::string const&),
|
||||||
bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
|
bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
|
||||||
if (stream < 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe.init(chain.GetLoop(), 0);
|
|
||||||
uv_pipe_open(pipe, stream);
|
|
||||||
|
|
||||||
finished = false;
|
finished = false;
|
||||||
return cmUVStreamRead(
|
return cmUVStreamRead(
|
||||||
pipe,
|
stream,
|
||||||
[outputflag, &processOutput, captureStd, &tempStd, id,
|
[outputflag, &processOutput, captureStd, &tempStd, id,
|
||||||
outputFunc](std::vector<char> data) {
|
outputFunc](std::vector<char> data) {
|
||||||
// Translate NULL characters in the output into valid text.
|
// Translate NULL characters in the output into valid text.
|
||||||
@@ -951,13 +942,11 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
outputHandle =
|
outputHandle = startRead(chain.OutputStream(), captureStdOut, tempStdOut,
|
||||||
startRead(outStream, chain.OutputStream(), captureStdOut, tempStdOut, 1,
|
1, cmSystemTools::Stdout, outFinished);
|
||||||
cmSystemTools::Stdout, outFinished);
|
if (chain.ErrorStream()) {
|
||||||
if (chain.ErrorStream() >= 0) {
|
errorHandle = startRead(chain.ErrorStream(), captureStdErr, tempStdErr,
|
||||||
errorHandle =
|
2, cmSystemTools::Stderr, errFinished);
|
||||||
startRead(errStream, chain.ErrorStream(), captureStdErr, tempStdErr, 2,
|
|
||||||
cmSystemTools::Stderr, errFinished);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ struct cmUVProcessChain::InternalData
|
|||||||
{
|
{
|
||||||
struct StreamData
|
struct StreamData
|
||||||
{
|
{
|
||||||
int BuiltinStream = -1;
|
cm::uv_pipe_ptr BuiltinStream;
|
||||||
uv_stdio_container_t Stdio;
|
uv_stdio_container_t Stdio;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -233,16 +233,22 @@ bool cmUVProcessChain::InternalData::Prepare(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputData.BuiltinStream = pipeFd[0];
|
if (outputData.BuiltinStream.init(*this->Loop, 0) < 0) {
|
||||||
outputData.Stdio.flags = UV_INHERIT_FD;
|
return false;
|
||||||
outputData.Stdio.data.fd = pipeFd[1];
|
}
|
||||||
|
if (uv_pipe_open(outputData.BuiltinStream, pipeFd[0]) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->TempOutputPipe.init(*this->Loop, 0) < 0) {
|
if (this->TempOutputPipe.init(*this->Loop, 0) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (uv_pipe_open(this->TempOutputPipe, outputData.Stdio.data.fd) < 0) {
|
if (uv_pipe_open(this->TempOutputPipe, pipeFd[1]) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputData.Stdio.flags = UV_INHERIT_FD;
|
||||||
|
outputData.Stdio.data.fd = pipeFd[1];
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case cmUVProcessChainBuilder::External:
|
case cmUVProcessChainBuilder::External:
|
||||||
@@ -269,19 +275,24 @@ bool cmUVProcessChain::InternalData::Prepare(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorData.BuiltinStream = pipeFd[0];
|
if (errorData.BuiltinStream.init(*this->Loop, 0) < 0) {
|
||||||
errorData.Stdio.flags = UV_INHERIT_FD;
|
return false;
|
||||||
errorData.Stdio.data.fd = pipeFd[1];
|
}
|
||||||
|
if (uv_pipe_open(errorData.BuiltinStream, pipeFd[0]) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->TempErrorPipe.init(*this->Loop, 0) < 0) {
|
if (this->TempErrorPipe.init(*this->Loop, 0) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (uv_pipe_open(this->TempErrorPipe, errorData.Stdio.data.fd) < 0) {
|
if (uv_pipe_open(this->TempErrorPipe, pipeFd[1]) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorData.Stdio.flags = UV_INHERIT_FD;
|
||||||
|
errorData.Stdio.data.fd = pipeFd[1];
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
}
|
|
||||||
|
|
||||||
case cmUVProcessChainBuilder::External:
|
case cmUVProcessChainBuilder::External:
|
||||||
errorData.Stdio.flags = UV_INHERIT_FD;
|
errorData.Stdio.flags = UV_INHERIT_FD;
|
||||||
@@ -437,12 +448,12 @@ uv_loop_t& cmUVProcessChain::GetLoop()
|
|||||||
return *this->Data->Loop;
|
return *this->Data->Loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmUVProcessChain::OutputStream()
|
uv_stream_t* cmUVProcessChain::OutputStream()
|
||||||
{
|
{
|
||||||
return this->Data->OutputStreamData.BuiltinStream;
|
return this->Data->OutputStreamData.BuiltinStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmUVProcessChain::ErrorStream()
|
uv_stream_t* cmUVProcessChain::ErrorStream()
|
||||||
{
|
{
|
||||||
return this->Data->ErrorStreamData.BuiltinStream;
|
return this->Data->ErrorStreamData.BuiltinStream;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,8 @@ public:
|
|||||||
uv_loop_t& GetLoop();
|
uv_loop_t& GetLoop();
|
||||||
|
|
||||||
// FIXME: Add stdin support
|
// FIXME: Add stdin support
|
||||||
int OutputStream();
|
uv_stream_t* OutputStream();
|
||||||
int ErrorStream();
|
uv_stream_t* ErrorStream();
|
||||||
|
|
||||||
bool Valid() const;
|
bool Valid() const;
|
||||||
bool Wait(uint64_t milliseconds = 0);
|
bool Wait(uint64_t milliseconds = 0);
|
||||||
|
|||||||
@@ -2210,7 +2210,7 @@ int cmcmd::RunPreprocessor(std::vector<std::string> const& command,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (process.GetStatus(0).ExitStatus != 0) {
|
if (process.GetStatus(0).ExitStatus != 0) {
|
||||||
cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
|
cmUVIStream errorStream(process.ErrorStream());
|
||||||
std::cerr << errorStream.rdbuf();
|
std::cerr << errorStream.rdbuf();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -2335,7 +2335,7 @@ int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (process.GetStatus(0).ExitStatus != 0) {
|
if (process.GetStatus(0).ExitStatus != 0) {
|
||||||
cmUVPipeIStream errorStream(process.GetLoop(), process.ErrorStream());
|
cmUVIStream errorStream(process.ErrorStream());
|
||||||
std::cerr << errorStream.rdbuf();
|
std::cerr << errorStream.rdbuf();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,17 +306,17 @@ bool testUVProcessChainBuiltin(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->OutputStream() < 0) {
|
if (!chain->OutputStream()) {
|
||||||
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chain->ErrorStream() < 0) {
|
if (!chain->ErrorStream()) {
|
||||||
std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
|
std::cout << "ErrorStream() was invalid, expecting valid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream output(chain->GetLoop(), chain->OutputStream());
|
cmUVIStream output(chain->OutputStream());
|
||||||
cmUVPipeIStream error(chain->GetLoop(), chain->ErrorStream());
|
cmUVIStream error(chain->ErrorStream());
|
||||||
|
|
||||||
if (!checkOutput(output, error)) {
|
if (!checkOutput(output, error)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -338,16 +338,16 @@ bool testUVProcessChainBuiltinMerged(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->OutputStream() < 0) {
|
if (!chain->OutputStream()) {
|
||||||
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
std::cout << "OutputStream() was invalid, expecting valid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chain->ErrorStream() >= 0) {
|
if (chain->ErrorStream()) {
|
||||||
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream mergedStream(chain->GetLoop(), chain->OutputStream());
|
cmUVIStream mergedStream(chain->OutputStream());
|
||||||
|
|
||||||
std::string merged = getInput(mergedStream);
|
std::string merged = getInput(mergedStream);
|
||||||
auto qemuErrorPos = merged.find("qemu:");
|
auto qemuErrorPos = merged.find("qemu:");
|
||||||
@@ -407,11 +407,11 @@ bool testUVProcessChainExternal(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->OutputStream() >= 0) {
|
if (chain->OutputStream()) {
|
||||||
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chain->ErrorStream() >= 0) {
|
if (chain->ErrorStream()) {
|
||||||
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -455,11 +455,11 @@ bool testUVProcessChainNone(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain->OutputStream() >= 0) {
|
if (chain->OutputStream()) {
|
||||||
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
std::cout << "OutputStream() was valid, expecting invalid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (chain->ErrorStream() >= 0) {
|
if (chain->ErrorStream()) {
|
||||||
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
std::cout << "ErrorStream() was valid, expecting invalid" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -482,7 +482,7 @@ bool testUVProcessChainCwdUnchanged(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
|
cmUVIStream output(chain.OutputStream());
|
||||||
auto cwd = getInput(output);
|
auto cwd = getInput(output);
|
||||||
if (!cmHasLiteralSuffix(cwd, "/Tests/CMakeLib")) {
|
if (!cmHasLiteralSuffix(cwd, "/Tests/CMakeLib")) {
|
||||||
std::cout << "Working directory was \"" << cwd
|
std::cout << "Working directory was \"" << cwd
|
||||||
@@ -509,7 +509,7 @@ bool testUVProcessChainCwdChanged(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream output(chain.GetLoop(), chain.OutputStream());
|
cmUVIStream output(chain.OutputStream());
|
||||||
auto cwd = getInput(output);
|
auto cwd = getInput(output);
|
||||||
if (!cmHasLiteralSuffix(cwd, "/Tests")) {
|
if (!cmHasLiteralSuffix(cwd, "/Tests")) {
|
||||||
std::cout << "Working directory was \"" << cwd
|
std::cout << "Working directory was \"" << cwd
|
||||||
@@ -644,7 +644,7 @@ bool testUVProcessChainInputFile(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream stream(chain.GetLoop(), chain.OutputStream());
|
cmUVIStream stream(chain.OutputStream());
|
||||||
std::string output = getInput(stream);
|
std::string output = getInput(stream);
|
||||||
if (output != "HELO WRD!") {
|
if (output != "HELO WRD!") {
|
||||||
std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
|
std::cout << "Output was \"" << output << "\", expected \"HELO WRD!\""
|
||||||
@@ -695,7 +695,7 @@ bool testUVProcessChainExternalLoop(char const* helperCommand)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmUVPipeIStream stream(chain.GetLoop(), chain.OutputStream());
|
cmUVIStream stream(chain.OutputStream());
|
||||||
std::string output = getInput(stream);
|
std::string output = getInput(stream);
|
||||||
if (output != "HELLO world!") {
|
if (output != "HELLO world!") {
|
||||||
std::cout << "Output was \"" << output << "\", expected \"HELLO world!\""
|
std::cout << "Output was \"" << output << "\", expected \"HELLO world!\""
|
||||||
|
|||||||
Reference in New Issue
Block a user