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());
}
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<int> 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);
+23 -1
View File
@@ -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<int> wait() const noexcept;
private:
/**
* If `true`, don't terminate the process
*/
bool is_moved_ = false;
pid_t pid_ = 0;
};
using StringResult =