Terminate handles when they get dropped

This commit is contained in:
Robbert van der Helm
2022-04-11 15:24:27 +02:00
parent 1641fb2996
commit 1df7abfb2c
2 changed files with 51 additions and 4 deletions
+28 -3
View File
@@ -93,18 +93,43 @@ char* const* ProcessEnvironment::make_environ() const {
return const_cast<char* const*>(recreated_environ_.data()); return const_cast<char* const*>(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 { bool Process::Handle::running() const noexcept {
return pid_running(pid); return pid_running(pid_);
} }
void Process::Handle::terminate() const noexcept { void Process::Handle::terminate() const noexcept {
kill(pid, SIGINT); kill(pid_, SIGINT);
wait(); wait();
} }
std::optional<int> Process::Handle::wait() const noexcept { std::optional<int> Process::Handle::wait() const noexcept {
int status = 0; int status = 0;
assert(waitpid(pid, &status, 0) > 0); assert(waitpid(pid_, &status, 0) > 0);
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
return WEXITSTATUS(status); return WEXITSTATUS(status);
+23 -1
View File
@@ -107,11 +107,25 @@ class Process {
* A handle to a running process. * A handle to a running process.
*/ */
class Handle { class Handle {
protected:
Handle(pid_t pid);
public: 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. * The process' ID.
*/ */
const pid_t pid; pid_t pid() const noexcept;
/** /**
* Whether the process is still running **and not a zombie**. * Whether the process is still running **and not a zombie**.
@@ -129,6 +143,14 @@ class Process {
* successfully. Returns a nullopt otherwise. * successfully. Returns a nullopt otherwise.
*/ */
std::optional<int> wait() const noexcept; std::optional<int> wait() const noexcept;
private:
/**
* If `true`, don't terminate the process
*/
bool is_moved_ = false;
pid_t pid_ = 0;
}; };
using StringResult = using StringResult =