diff --git a/src/libutil/include/nix/util/processes.hh b/src/libutil/include/nix/util/processes.hh index 141079e743d..81e6a2b83cd 100644 --- a/src/libutil/include/nix/util/processes.hh +++ b/src/libutil/include/nix/util/processes.hh @@ -35,6 +35,10 @@ class Pid #endif public: Pid(); + Pid(const Pid &) = delete; + Pid(Pid && other) noexcept; + Pid & operator=(const Pid &) = delete; + Pid & operator=(Pid && other) noexcept; #ifndef _WIN32 Pid(pid_t pid); void operator=(pid_t pid); @@ -53,6 +57,18 @@ public: void setKillSignal(int signal); pid_t release(); #endif + + friend void swap(Pid & lhs, Pid & rhs) noexcept + { + using std::swap; +#ifndef _WIN32 + swap(lhs.pid, rhs.pid); + swap(lhs.separatePG, rhs.separatePG); + swap(lhs.killSignal, rhs.killSignal); +#else + swap(lhs.pid, rhs.pid); +#endif + } }; #ifndef _WIN32 diff --git a/src/libutil/meson.build b/src/libutil/meson.build index f91605de932..33d7c6f567c 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -156,6 +156,7 @@ sources = [ config_priv_h ] + files( 'pos-table.cc', 'position.cc', 'posix-source-accessor.cc', + 'processes.cc', 'serialise.cc', 'signature/local-keys.cc', 'signature/signer.cc', diff --git a/src/libutil/processes.cc b/src/libutil/processes.cc new file mode 100644 index 00000000000..a9ce2b52121 --- /dev/null +++ b/src/libutil/processes.cc @@ -0,0 +1,11 @@ +#include "nix/util/processes.hh" + +namespace nix { + +Pid & Pid::operator=(Pid && other) noexcept +{ + swap(*this, other); + return *this; +} + +} // namespace nix diff --git a/src/libutil/unix/processes.cc b/src/libutil/unix/processes.cc index 66423f01198..2393da55d4a 100644 --- a/src/libutil/unix/processes.cc +++ b/src/libutil/unix/processes.cc @@ -35,6 +35,14 @@ namespace nix { Pid::Pid() {} +Pid::Pid(Pid && other) noexcept + : pid(other.pid) + , separatePG(other.separatePG) + , killSignal(other.killSignal) +{ + other.release(); +} + Pid::Pid(pid_t pid) : pid(pid) { @@ -113,7 +121,12 @@ void Pid::setKillSignal(int signal) pid_t Pid::release() { pid_t p = pid; + /* We use the move assignment operator rather than setting the individual fields so we aren't duplicating the + default values from the header, which would be hard to keep in sync. If we just used the assignment operator + without manually resetting pid first it would kill that process, however, so we do manually reset that one field. + */ pid = -1; + *this = Pid(); return p; } diff --git a/src/libutil/windows/processes.cc b/src/libutil/windows/processes.cc index 1946e8b1fad..135583ad028 100644 --- a/src/libutil/windows/processes.cc +++ b/src/libutil/windows/processes.cc @@ -33,6 +33,11 @@ using namespace nix::windows; Pid::Pid() {} +Pid::Pid(Pid && other) noexcept + : pid(std::move(other.pid)) +{ +} + Pid::Pid(AutoCloseFD pid) : pid(std::move(pid)) {