summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx284
1 files changed, 109 insertions, 175 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 1f5333f..2bdc928 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -31,9 +31,6 @@
#include "cmProcessOutput.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
-#include "cmUVHandlePtr.h"
-#include "cmUVProcessChain.h"
-#include "cmUVStream.h"
#include "cmValue.h"
#if !defined(CMAKE_BOOTSTRAP)
@@ -62,14 +59,12 @@
#include <cassert>
#include <cctype>
#include <cerrno>
-#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iostream>
-#include <memory>
#include <sstream>
#include <utility>
#include <vector>
@@ -573,111 +568,85 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
const char* dir, OutputOption outputflag,
cmDuration timeout, Encoding encoding)
{
- cmUVProcessChainBuilder builder;
- builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, stdin)
- .AddCommand(command);
- if (dir) {
- builder.SetWorkingDirectory(dir);
+ std::vector<const char*> argv;
+ argv.reserve(command.size() + 1);
+ for (std::string const& cmd : command) {
+ argv.push_back(cmd.c_str());
+ }
+ argv.push_back(nullptr);
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, argv.data());
+ cmsysProcess_SetWorkingDirectory(cp, dir);
+ if (cmSystemTools::GetRunCommandHideConsole()) {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
}
if (outputflag == OUTPUT_PASSTHROUGH) {
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDOUT, 1);
+ cmsysProcess_SetPipeShared(cp, cmsysProcess_Pipe_STDERR, 1);
captureStdOut = nullptr;
captureStdErr = nullptr;
- builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, stdout)
- .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, stderr);
} else if (outputflag == OUTPUT_MERGE ||
(captureStdErr && captureStdErr == captureStdOut)) {
- builder.SetMergedBuiltinStreams();
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_MergeOutput, 1);
captureStdErr = nullptr;
- } else {
- builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
- .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR);
}
assert(!captureStdErr || captureStdErr != captureStdOut);
- auto chain = builder.Start();
- bool timedOut = false;
- cm::uv_timer_ptr timer;
- if (timeout.count()) {
- timer.init(chain.GetLoop(), &timedOut);
- timer.start(
- [](uv_timer_t* t) {
- auto* timedOutPtr = static_cast<bool*>(t->data);
- *timedOutPtr = true;
- },
- static_cast<uint64_t>(timeout.count() * 1000.0), 0);
- }
+ cmsysProcess_SetTimeout(cp, timeout.count());
+ cmsysProcess_Execute(cp);
std::vector<char> tempStdOut;
std::vector<char> tempStdErr;
- cm::uv_pipe_ptr outStream;
- bool outFinished = true;
- cm::uv_pipe_ptr errStream;
- bool errFinished = true;
+ char* data;
+ int length;
+ int pipe;
cmProcessOutput processOutput(encoding);
- std::unique_ptr<cmUVStreamReadHandle> outputHandle;
- std::unique_ptr<cmUVStreamReadHandle> errorHandle;
+ std::string strdata;
if (outputflag != OUTPUT_PASSTHROUGH &&
(captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) {
- auto startRead =
- [&outputflag, &processOutput,
- &chain](cm::uv_pipe_ptr& pipe, int stream, std::string* captureStd,
- std::vector<char>& tempStd, int id,
- void (*outputFunc)(const std::string&),
- bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> {
- if (stream < 0) {
- return nullptr;
- }
-
- pipe.init(chain.GetLoop(), 0);
- uv_pipe_open(pipe, stream);
-
- finished = false;
- return cmUVStreamRead(
- pipe,
- [outputflag, &processOutput, captureStd, &tempStd, id,
- outputFunc](std::vector<char> data) {
- // Translate NULL characters in the output into valid text.
- for (auto& c : data) {
- if (c == '\0') {
- c = ' ';
- }
- }
+ while ((pipe = cmsysProcess_WaitForData(cp, &data, &length, nullptr)) >
+ 0) {
+ // Translate NULL characters in the output into valid text.
+ for (int i = 0; i < length; ++i) {
+ if (data[i] == '\0') {
+ data[i] = ' ';
+ }
+ }
- if (outputflag != OUTPUT_NONE) {
- std::string strdata;
- processOutput.DecodeText(data.data(), data.size(), strdata, id);
- outputFunc(strdata);
- }
- if (captureStd) {
- cm::append(tempStd, data.data(), data.data() + data.size());
- }
- },
- [&finished, outputflag, &processOutput, id, outputFunc]() {
- finished = true;
- if (outputflag != OUTPUT_NONE) {
- std::string strdata;
- processOutput.DecodeText(std::string(), strdata, id);
- if (!strdata.empty()) {
- outputFunc(strdata);
- }
- }
- });
- };
+ if (pipe == cmsysProcess_Pipe_STDOUT) {
+ if (outputflag != OUTPUT_NONE) {
+ processOutput.DecodeText(data, length, strdata, 1);
+ cmSystemTools::Stdout(strdata);
+ }
+ if (captureStdOut) {
+ cm::append(tempStdOut, data, data + length);
+ }
+ } else if (pipe == cmsysProcess_Pipe_STDERR) {
+ if (outputflag != OUTPUT_NONE) {
+ processOutput.DecodeText(data, length, strdata, 2);
+ cmSystemTools::Stderr(strdata);
+ }
+ if (captureStdErr) {
+ cm::append(tempStdErr, data, data + length);
+ }
+ }
+ }
- outputHandle =
- startRead(outStream, chain.OutputStream(), captureStdOut, tempStdOut, 1,
- cmSystemTools::Stdout, outFinished);
- if (chain.OutputStream() != chain.ErrorStream()) {
- errorHandle =
- startRead(errStream, chain.ErrorStream(), captureStdErr, tempStdErr, 2,
- cmSystemTools::Stderr, errFinished);
+ if (outputflag != OUTPUT_NONE) {
+ processOutput.DecodeText(std::string(), strdata, 1);
+ if (!strdata.empty()) {
+ cmSystemTools::Stdout(strdata);
+ }
+ processOutput.DecodeText(std::string(), strdata, 2);
+ if (!strdata.empty()) {
+ cmSystemTools::Stderr(strdata);
+ }
}
}
- while (!timedOut && !(chain.Finished() && outFinished && errFinished)) {
- uv_run(&chain.GetLoop(), UV_RUN_ONCE);
- }
+ cmsysProcess_WaitForExit(cp, nullptr);
if (captureStdOut) {
captureStdOut->assign(tempStdOut.begin(), tempStdOut.end());
@@ -689,43 +658,48 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
}
bool result = true;
- if (timedOut) {
- const char* error_str = "Process terminated due to timeout\n";
+ if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
+ if (retVal) {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ } else {
+ if (cmsysProcess_GetExitValue(cp) != 0) {
+ result = false;
+ }
+ }
+ } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exception) {
+ const char* exception_str = cmsysProcess_GetExceptionString(cp);
+ if (outputflag != OUTPUT_NONE) {
+ std::cerr << exception_str << std::endl;
+ }
+ if (captureStdErr) {
+ captureStdErr->append(exception_str, strlen(exception_str));
+ } else if (captureStdOut) {
+ captureStdOut->append(exception_str, strlen(exception_str));
+ }
+ result = false;
+ } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) {
+ const char* error_str = cmsysProcess_GetErrorString(cp);
if (outputflag != OUTPUT_NONE) {
std::cerr << error_str << std::endl;
}
if (captureStdErr) {
captureStdErr->append(error_str, strlen(error_str));
+ } else if (captureStdOut) {
+ captureStdOut->append(error_str, strlen(error_str));
}
result = false;
- } else {
- auto const& status = chain.GetStatus(0);
- auto exception = status.GetException();
-
- switch (exception.first) {
- case cmUVProcessChain::ExceptionCode::None:
- if (retVal) {
- *retVal = static_cast<int>(status.ExitStatus);
- } else {
- if (status.ExitStatus != 0) {
- result = false;
- }
- }
- break;
- default: {
- if (outputflag != OUTPUT_NONE) {
- std::cerr << exception.second << std::endl;
- }
- if (captureStdErr) {
- captureStdErr->append(exception.second);
- } else if (captureStdOut) {
- captureStdOut->append(exception.second);
- }
- result = false;
- } break;
+ } else if (cmsysProcess_GetState(cp) == cmsysProcess_State_Expired) {
+ const char* error_str = "Process terminated due to timeout\n";
+ if (outputflag != OUTPUT_NONE) {
+ std::cerr << error_str << std::endl;
+ }
+ if (captureStdErr) {
+ captureStdErr->append(error_str, strlen(error_str));
}
+ result = false;
}
+ cmsysProcess_Delete(cp);
return result;
}
@@ -2239,10 +2213,9 @@ bool cmSystemTools::ListTar(const std::string& outFileName,
#endif
}
-cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
- uv_loop_t* loop, uv_stream_t* outPipe, uv_stream_t* errPipe,
- std::string& line, cmDuration timeout, std::vector<char>& out,
- std::vector<char>& err)
+int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
+ cmDuration timeout, std::vector<char>& out,
+ std::vector<char>& err)
{
line.clear();
auto outiter = out.begin();
@@ -2264,7 +2237,7 @@ cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
line.append(out.data(), length);
}
out.erase(out.begin(), outiter + 1);
- return WaitForLineResult::STDOUT;
+ return cmsysProcess_Pipe_STDOUT;
}
}
@@ -2282,66 +2255,33 @@ cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
line.append(err.data(), length);
}
err.erase(err.begin(), erriter + 1);
- return WaitForLineResult::STDERR;
+ return cmsysProcess_Pipe_STDERR;
}
}
// No newlines found. Wait for more data from the process.
- struct ReadData
- {
- uv_stream_t* Stream;
- std::vector<char> Buffer;
- bool Read = false;
- bool Finished = false;
- };
- auto startRead =
- [](uv_stream_t* stream,
- ReadData& data) -> std::unique_ptr<cmUVStreamReadHandle> {
- data.Stream = stream;
- return cmUVStreamRead(
- stream,
- [&data](std::vector<char> buf) {
- data.Buffer = std::move(buf);
- data.Read = true;
- uv_read_stop(data.Stream);
- },
- [&data]() { data.Finished = true; });
- };
- ReadData outData;
- auto outHandle = startRead(outPipe, outData);
- ReadData errData;
- auto errHandle = startRead(errPipe, errData);
-
- cm::uv_timer_ptr timer;
- bool timedOut = false;
- timer.init(*loop, &timedOut);
- timer.start(
- [](uv_timer_t* handle) {
- auto* timedOutPtr = static_cast<bool*>(handle->data);
- *timedOutPtr = true;
- },
- static_cast<uint64_t>(timeout.count() * 1000.0), 0);
-
- uv_run(loop, UV_RUN_ONCE);
- if (timedOut) {
+ int length;
+ char* data;
+ double timeoutAsDbl = timeout.count();
+ int pipe =
+ cmsysProcess_WaitForData(process, &data, &length, &timeoutAsDbl);
+ if (pipe == cmsysProcess_Pipe_Timeout) {
// Timeout has been exceeded.
- return WaitForLineResult::Timeout;
+ return pipe;
}
- if (outData.Read) {
- processOutput.DecodeText(outData.Buffer.data(), outData.Buffer.size(),
- strdata, 1);
+ if (pipe == cmsysProcess_Pipe_STDOUT) {
+ processOutput.DecodeText(data, length, strdata, 1);
// Append to the stdout buffer.
std::vector<char>::size_type size = out.size();
cm::append(out, strdata);
outiter = out.begin() + size;
- } else if (errData.Read) {
- processOutput.DecodeText(errData.Buffer.data(), errData.Buffer.size(),
- strdata, 2);
+ } else if (pipe == cmsysProcess_Pipe_STDERR) {
+ processOutput.DecodeText(data, length, strdata, 2);
// Append to the stderr buffer.
std::vector<char>::size_type size = err.size();
cm::append(err, strdata);
erriter = err.begin() + size;
- } else if (outData.Finished && errData.Finished) {
+ } else if (pipe == cmsysProcess_Pipe_None) {
// Both stdout and stderr pipes have broken. Return leftover data.
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
@@ -2358,20 +2298,14 @@ cmSystemTools::WaitForLineResult cmSystemTools::WaitForLine(
if (!out.empty()) {
line.append(out.data(), outiter - out.begin());
out.erase(out.begin(), out.end());
- return WaitForLineResult::STDOUT;
+ return cmsysProcess_Pipe_STDOUT;
}
if (!err.empty()) {
line.append(err.data(), erriter - err.begin());
err.erase(err.begin(), err.end());
- return WaitForLineResult::STDERR;
+ return cmsysProcess_Pipe_STDERR;
}
- return WaitForLineResult::None;
- }
- if (!outData.Finished) {
- uv_read_stop(outPipe);
- }
- if (!errData.Finished) {
- uv_read_stop(errPipe);
+ return cmsysProcess_Pipe_None;
}
}
}