diff --git a/src/common/process.cpp b/src/common/process.cpp index 6c5950e2..330440fe 100644 --- a/src/common/process.cpp +++ b/src/common/process.cpp @@ -93,18 +93,43 @@ char* const* ProcessEnvironment::make_environ() const { return const_cast(recreated_environ_.data()); } +Process::Handle::Handle(pid_t pid) : pid_(pid) {} + +Process::Handle::~Handle() { + if (!is_moved_) { + // If this function has already been called then that's okay + terminate(); + } +} + +Process::Handle::Handle(Handle&& o) noexcept : pid_(o.pid_) { + o.is_moved_ = true; +} + +Process::Handle& Process::Handle::operator=(Handle&& o) noexcept { + o.is_moved_ = true; + + pid_ = o.pid_; + + return *this; +} + +pid_t Process::Handle::pid() const noexcept { + return pid_; +} + bool Process::Handle::running() const noexcept { - return pid_running(pid); + return pid_running(pid_); } void Process::Handle::terminate() const noexcept { - kill(pid, SIGINT); + kill(pid_, SIGINT); wait(); } std::optional Process::Handle::wait() const noexcept { int status = 0; - assert(waitpid(pid, &status, 0) > 0); + assert(waitpid(pid_, &status, 0) > 0); if (WIFEXITED(status)) { return WEXITSTATUS(status); diff --git a/src/common/process.h b/src/common/process.h index 1b30b602..43ef993c 100644 --- a/src/common/process.h +++ b/src/common/process.h @@ -107,11 +107,25 @@ class Process { * A handle to a running process. */ class Handle { + protected: + Handle(pid_t pid); + public: + /** + * Terminates the process when it gets dropped. + */ + ~Handle(); + + Handle(const Handle&) = delete; + Handle& operator=(const Handle&) = delete; + + Handle(Handle&&) noexcept; + Handle& operator=(Handle&&) noexcept; + /** * The process' ID. */ - const pid_t pid; + pid_t pid() const noexcept; /** * Whether the process is still running **and not a zombie**. @@ -129,6 +143,14 @@ class Process { * successfully. Returns a nullopt otherwise. */ std::optional wait() const noexcept; + + private: + /** + * If `true`, don't terminate the process + */ + bool is_moved_ = false; + + pid_t pid_ = 0; }; using StringResult =