#pragma once #include #include #include #include #include #include #include #include namespace izo { struct ProcessOptions { std::filesystem::path executable; std::vector arguments; std::filesystem::path workingDirectory; bool detached = false; bool captureOutput = false; bool pipeStdin = false; // Used by RunProcess. A negative value waits indefinitely. std::int64_t timeoutMs = -1; }; struct ProcessResult { bool started = false; std::uint32_t processId = 0; std::string errorMessage; explicit operator bool() const noexcept { return started; } }; ProcessResult LaunchProcess(const ProcessOptions& options); class Process { public: Process() = default; ~Process(); Process(Process&&) noexcept = default; Process& operator=(Process&& other) noexcept; Process(const Process&) = delete; Process& operator=(const Process&) = delete; explicit operator bool() const noexcept { return state_ != nullptr; } std::uint32_t Id() const noexcept; bool IsRunning() const; // Returns false if the timeout expires or this Process is invalid. bool Wait(std::int64_t timeoutMs = -1, std::string* errorMessage = nullptr); // Forcefully terminates the child process. bool Terminate(std::string* errorMessage = nullptr); std::optional ExitCode() const; bool WriteStdin(std::string_view data, std::string* errorMessage = nullptr); bool CloseStdin(std::string* errorMessage = nullptr); // Captured output is complete after Wait succeeds. std::string Stdout() const; std::string Stderr() const; private: struct State; explicit Process(std::shared_ptr state) : state_(std::move(state)) {} std::shared_ptr state_; friend Process StartProcess(const ProcessOptions&, std::string*); }; Process StartProcess(const ProcessOptions& options, std::string* errorMessage = nullptr); struct RunProcessResult { bool started = false; bool timedOut = false; int exitCode = -1; std::string stdoutText; std::string stderrText; std::string errorMessage; explicit operator bool() const noexcept { return started && !timedOut && exitCode == 0; } }; RunProcessResult RunProcess(const ProcessOptions& options); bool IsProcessRunning(std::uint32_t processId) noexcept; std::uint32_t GetCurrentProcessId() noexcept; std::uint32_t GetParentProcessId() noexcept; } // namespace izo