| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #pragma once | |
| #include "cmConfigure.h" // IWYU pragma: keep | |
| #include <array> | |
| #include <cstddef> // IWYU pragma: keep | |
| #include <cstdint> | |
| #include <cstdio> | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include <cm3p/uv.h> | |
| class cmUVProcessChain; | |
| class cmUVProcessChainBuilder | |
| { | |
| public: | |
| enum Stream | |
| { | |
| Stream_INPUT = 0, | |
| Stream_OUTPUT = 1, | |
| Stream_ERROR = 2, | |
| }; | |
| cmUVProcessChainBuilder(); | |
| cmUVProcessChainBuilder& AddCommand(std::vector<std::string> arguments); | |
| cmUVProcessChainBuilder& SetBuiltinLoop(); | |
| cmUVProcessChainBuilder& SetExternalLoop(uv_loop_t& loop); | |
| cmUVProcessChainBuilder& SetNoStream(Stream stdio); | |
| cmUVProcessChainBuilder& SetBuiltinStream(Stream stdio); | |
| cmUVProcessChainBuilder& SetMergedBuiltinStreams(); | |
| cmUVProcessChainBuilder& SetExternalStream(Stream stdio, int fd); | |
| cmUVProcessChainBuilder& SetExternalStream(Stream stdio, FILE* stream); | |
| cmUVProcessChainBuilder& SetWorkingDirectory(std::string dir); | |
| cmUVProcessChainBuilder& SetEnvironment(std::vector<std::string> env); | |
| cmUVProcessChainBuilder& SetDetached(); | |
| uv_loop_t* GetLoop() const; | |
| cmUVProcessChain Start() const; | |
| private: | |
| enum StdioType | |
| { | |
| None, | |
| Builtin, | |
| External, | |
| }; | |
| friend class cmUVProcessChain; | |
| struct StdioConfiguration | |
| { | |
| StdioType Type = None; | |
| int FileDescriptor = -1; | |
| }; | |
| struct ProcessConfiguration | |
| { | |
| std::vector<std::string> Arguments; | |
| }; | |
| std::array<StdioConfiguration, 3> Stdio; | |
| std::vector<ProcessConfiguration> Processes; | |
| std::string WorkingDirectory; | |
| std::vector<std::string> Environment; | |
| bool MergedBuiltinStreams = false; | |
| bool Detached = false; | |
| uv_loop_t* Loop = nullptr; | |
| }; | |
| class cmUVProcessChain | |
| { | |
| public: | |
| enum class ExceptionCode | |
| { | |
| None, | |
| Fault, | |
| Illegal, | |
| Interrupt, | |
| Numerical, | |
| Spawn, | |
| Other, | |
| }; | |
| struct Status | |
| { | |
| int SpawnResult; | |
| bool Finished; | |
| int64_t ExitStatus; | |
| int TermSignal; | |
| std::pair<ExceptionCode, std::string> GetException() const; | |
| }; | |
| cmUVProcessChain(cmUVProcessChain const& other) = delete; | |
| cmUVProcessChain(cmUVProcessChain&& other) noexcept; | |
| ~cmUVProcessChain(); | |
| cmUVProcessChain& operator=(cmUVProcessChain const& other) = delete; | |
| cmUVProcessChain& operator=(cmUVProcessChain&& other) noexcept; | |
| uv_loop_t& GetLoop(); | |
| // FIXME: Add stdin support | |
| uv_stream_t* OutputStream(); | |
| uv_stream_t* ErrorStream(); | |
| bool Valid() const; | |
| bool Wait(uint64_t milliseconds = 0); | |
| std::vector<Status const*> GetStatus() const; | |
| Status const& GetStatus(std::size_t index) const; | |
| bool Finished() const; | |
| /** Return a borrowed Windows process handle, valid until chain destruction | |
| even after the child exits, or nullptr if unavailable. */ | |
| void* GetNativeProcessHandle(std::size_t index) const; | |
| /** Terminate any remaining child processes. | |
| Call this only after exiting the event loop, and at most once. */ | |
| void Terminate(); | |
| private: | |
| friend class cmUVProcessChainBuilder; | |
| cmUVProcessChain(); | |
| struct InternalData; | |
| std::unique_ptr<InternalData> Data; | |
| }; |