cmUVProcessChain: Open output streams automatically

Avoid repeating the logic at every call site.
This commit is contained in:
Brad King
2025-11-25 19:02:20 -05:00
parent ca0e9418f3
commit c94d70c345
20 changed files with 93 additions and 136 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
} }

View File

@@ -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) {

View File

@@ -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)) {

View File

@@ -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)) {

View File

@@ -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)) {

View File

@@ -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)) {

View File

@@ -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);
} }

View File

@@ -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,

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)) {

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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);
} }
} }

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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!\""