| 844 | } |
| 845 | |
| 846 | bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command, |
| 847 | std::string* captureStdOut, |
| 848 | std::string* captureStdErr, int* retVal, |
| 849 | char const* dir, OutputOption outputflag, |
| 850 | cmDuration timeout, Encoding encoding) |
| 851 | { |
| 852 | cmUVProcessChainBuilder builder; |
| 853 | builder.SetExternalStream(cmUVProcessChainBuilder::Stream_INPUT, stdin) |
| 854 | .AddCommand(command); |
| 855 | if (dir) { |
| 856 | builder.SetWorkingDirectory(dir); |
| 857 | } |
| 858 | |
| 859 | if (outputflag == OUTPUT_PASSTHROUGH) { |
| 860 | captureStdOut = nullptr; |
| 861 | captureStdErr = nullptr; |
| 862 | builder.SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT, stdout) |
| 863 | .SetExternalStream(cmUVProcessChainBuilder::Stream_ERROR, stderr); |
| 864 | } else if (outputflag == OUTPUT_MERGE || |
| 865 | (captureStdErr && captureStdErr == captureStdOut)) { |
| 866 | builder.SetMergedBuiltinStreams(); |
| 867 | captureStdErr = nullptr; |
| 868 | } else { |
| 869 | builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT) |
| 870 | .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR); |
| 871 | } |
| 872 | assert(!captureStdErr || captureStdErr != captureStdOut); |
| 873 | |
| 874 | auto chain = builder.Start(); |
| 875 | bool timedOut = false; |
| 876 | cm::uv_timer_ptr timer; |
| 877 | if (timeout.count()) { |
| 878 | timer.init(chain.GetLoop(), &timedOut); |
| 879 | timer.start( |
| 880 | [](uv_timer_t* t) { |
| 881 | auto* timedOutPtr = static_cast<bool*>(t->data); |
| 882 | *timedOutPtr = true; |
| 883 | }, |
| 884 | static_cast<uint64_t>(timeout.count() * 1000.0), 0, |
| 885 | cm::uv_update_time::yes); |
| 886 | } |
| 887 | |
| 888 | std::vector<char> tempStdOut; |
| 889 | std::vector<char> tempStdErr; |
| 890 | bool outFinished = true; |
| 891 | bool errFinished = true; |
| 892 | cmProcessOutput processOutput(encoding); |
| 893 | std::unique_ptr<cmUVStreamReadHandle> outputHandle; |
| 894 | std::unique_ptr<cmUVStreamReadHandle> errorHandle; |
| 895 | if (outputflag != OUTPUT_PASSTHROUGH && |
| 896 | (captureStdOut || captureStdErr || outputflag != OUTPUT_NONE)) { |
| 897 | auto startRead = |
| 898 | [&outputflag, &processOutput]( |
| 899 | uv_stream_t* stream, std::string* captureStd, |
| 900 | std::vector<char>& tempStd, int id, |
| 901 | void (*outputFunc)(std::string const&), |
| 902 | bool& finished) -> std::unique_ptr<cmUVStreamReadHandle> { |
| 903 | finished = false; |
nothing calls this directly
no test coverage detected