diff options
author | eldritch horrors <pennae@lix.systems> | 2024-04-05 21:02:04 +0200 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-06-23 11:52:49 +0000 |
commit | 3d155fc509e19354ba3798b1cc1b9cbcdb789c85 (patch) | |
tree | dc3dd72cd77e02e1aeb25d75c6e01bdf34041b28 /src/libutil/processes.cc | |
parent | b43a2e84c4b2fa7cb1167693652702e6dac95f53 (diff) |
libutil: give Pid proper resource semantics
copy-constructing or assigning from pid_t can easily lead to duplicate
Pid instances for the same process if a pid_t was used carelessly, and
Pid itself was copy-constructible. both could cause surprising results
such as killing processes twice (which could become very problemantic,
but luckily modern systems don't reuse PIDs all that quickly), or more
than one piece of the code believing it owns a process when neither do
Change-Id: Ifea7445f84200b34c1a1d0acc2cdffe0f01e20c6
Diffstat (limited to 'src/libutil/processes.cc')
-rw-r--r-- | src/libutil/processes.cc | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/src/libutil/processes.cc b/src/libutil/processes.cc index 3bb419e45..9c99f047c 100644 --- a/src/libutil/processes.cc +++ b/src/libutil/processes.cc @@ -35,23 +35,25 @@ Pid::Pid() } -Pid::Pid(pid_t pid) - : pid(pid) +Pid::Pid(Pid && other) : pid(other.pid), separatePG(other.separatePG), killSignal(other.killSignal) { + other.pid = -1; } -Pid::~Pid() noexcept(false) +Pid & Pid::operator=(Pid && other) { - if (pid != -1) kill(); + Pid tmp(std::move(other)); + std::swap(pid, tmp.pid); + std::swap(separatePG, tmp.separatePG); + std::swap(killSignal, tmp.killSignal); + return *this; } -void Pid::operator =(pid_t pid) +Pid::~Pid() noexcept(false) { - if (this->pid != -1 && this->pid != pid) kill(); - this->pid = pid; - killSignal = SIGKILL; // reset signal to default + if (pid != -1) kill(); } @@ -125,7 +127,7 @@ void killUser(uid_t uid) users to which the current process can send signals. So we fork a process, switch to uid, and send a mass kill. */ - Pid pid = startProcess([&]() { + Pid pid{startProcess([&]() { if (setuid(uid) == -1) throw SysError("setting uid"); @@ -147,7 +149,7 @@ void killUser(uid_t uid) } _exit(0); - }); + })}; int status = pid.wait(); if (status != 0) @@ -288,7 +290,7 @@ void runProgram2(const RunOptions & options) } /* Fork. */ - Pid pid = startProcess([&]() { + Pid pid{startProcess([&]() { if (options.environment) replaceEnv(*options.environment); if (options.standardOut && dup2(out.writeSide.get(), STDOUT_FILENO) == -1) @@ -322,7 +324,7 @@ void runProgram2(const RunOptions & options) execv(options.program.c_str(), stringsToCharPtrs(args_).data()); throw SysError("executing '%1%'", options.program); - }, processOptions); + }, processOptions)}; out.writeSide.close(); |