about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--third_party/nix/src/build-remote/build-remote.cc8
-rw-r--r--third_party/nix/src/libmain/shared.cc2
-rw-r--r--third_party/nix/src/libstore/binary-cache-store.cc43
-rw-r--r--third_party/nix/src/libstore/build.cc60
-rw-r--r--third_party/nix/src/libstore/download.cc39
-rw-r--r--third_party/nix/src/libstore/gc.cc9
-rw-r--r--third_party/nix/src/libstore/http-binary-cache-store.cc30
-rw-r--r--third_party/nix/src/libstore/local-store.cc8
-rw-r--r--third_party/nix/src/libstore/misc.cc122
-rw-r--r--third_party/nix/src/libstore/pathlocks.cc4
-rw-r--r--third_party/nix/src/libstore/remote-fs-accessor.cc2
-rw-r--r--third_party/nix/src/libstore/ssh.cc8
-rw-r--r--third_party/nix/src/libstore/store-api.cc96
-rw-r--r--third_party/nix/src/libutil/archive.cc5
-rw-r--r--third_party/nix/src/libutil/archive.hh2
-rw-r--r--third_party/nix/src/libutil/args.hh3
-rw-r--r--third_party/nix/src/libutil/config.hh7
-rw-r--r--third_party/nix/src/libutil/finally.hh2
-rw-r--r--third_party/nix/src/libutil/hash.cc2
-rw-r--r--third_party/nix/src/libutil/hash.hh8
-rw-r--r--third_party/nix/src/libutil/json.hh16
-rw-r--r--third_party/nix/src/libutil/lazy.hh2
-rw-r--r--third_party/nix/src/libutil/lru-cache.hh2
-rw-r--r--third_party/nix/src/libutil/pool.hh2
-rw-r--r--third_party/nix/src/libutil/ref.hh2
-rw-r--r--third_party/nix/src/libutil/serialise.hh19
-rw-r--r--third_party/nix/src/libutil/sync.hh6
-rw-r--r--third_party/nix/src/libutil/thread-pool.hh2
-rw-r--r--third_party/nix/src/libutil/types.hh8
-rw-r--r--third_party/nix/src/libutil/util.cc30
-rw-r--r--third_party/nix/src/libutil/util.hh26
-rw-r--r--third_party/nix/src/nix-build/nix-build.cc2
-rw-r--r--third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc4
-rw-r--r--third_party/nix/src/nix/repl.cc4
34 files changed, 311 insertions, 274 deletions
diff --git a/third_party/nix/src/build-remote/build-remote.cc b/third_party/nix/src/build-remote/build-remote.cc
index 60878e2e6eb8..00bd833ac38e 100644
--- a/third_party/nix/src/build-remote/build-remote.cc
+++ b/third_party/nix/src/build-remote/build-remote.cc
@@ -109,8 +109,8 @@ static int _main(int argc, char* argv[]) {
       mkdir(currentLoad.c_str(), 0777);
 
       while (true) {
-        bestSlotLock = -1;
-        AutoCloseFD lock = openLockFile(currentLoad + "/main-lock", true);
+        bestSlotLock = AutoCloseFD(-1);
+        AutoCloseFD lock(openLockFile(currentLoad + "/main-lock", true));
         lockFile(lock.get(), ltWrite, true);
 
         bool rightType = false;
@@ -177,7 +177,7 @@ static int _main(int argc, char* argv[]) {
 
         futimens(bestSlotLock.get(), nullptr);
 
-        lock = -1;
+        lock = AutoCloseFD(-1);
 
         try {
           DLOG(INFO) << "connecting to '" << bestMachine->storeUri << "'";
@@ -240,7 +240,7 @@ static int _main(int argc, char* argv[]) {
                 substitute);
     }
 
-    uploadLock = -1;
+    uploadLock = AutoCloseFD(-1);
 
     BasicDerivation drv(
         readDerivation(store->realStoreDir + "/" + baseNameOf(drvPath)));
diff --git a/third_party/nix/src/libmain/shared.cc b/third_party/nix/src/libmain/shared.cc
index 348b91ab55e9..542dc25957a4 100644
--- a/third_party/nix/src/libmain/shared.cc
+++ b/third_party/nix/src/libmain/shared.cc
@@ -360,7 +360,7 @@ RunPager::RunPager() {
 
 RunPager::~RunPager() {
   try {
-    if (pid != -1) {
+    if (pid != Pid(-1)) {
       std::cout.flush();
       close(STDOUT_FILENO);
       pid.wait();
diff --git a/third_party/nix/src/libstore/binary-cache-store.cc b/third_party/nix/src/libstore/binary-cache-store.cc
index d38db375edb9..91da7e22659d 100644
--- a/third_party/nix/src/libstore/binary-cache-store.cc
+++ b/third_party/nix/src/libstore/binary-cache-store.cc
@@ -80,13 +80,14 @@ void BinaryCacheStore::getFile(
 
 void BinaryCacheStore::getFile(const std::string& path, Sink& sink) {
   std::promise<std::shared_ptr<std::string>> promise;
-  getFile(path, {[&](std::future<std::shared_ptr<std::string>> result) {
-            try {
-              promise.set_value(result.get());
-            } catch (...) {
-              promise.set_exception(std::current_exception());
-            }
-          }});
+  getFile(path, Callback<std::shared_ptr<std::string>>{
+                    [&](std::future<std::shared_ptr<std::string>> result) {
+                      try {
+                        promise.set_value(result.get());
+                      } catch (...) {
+                        promise.set_exception(std::current_exception());
+                      }
+                    }});
   auto data = promise.get_future().get();
   sink(reinterpret_cast<unsigned char*>(data->data()), data->size());
 }
@@ -280,23 +281,25 @@ void BinaryCacheStore::queryPathInfoUncached(
 
   auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
 
-  getFile(narInfoFile, {[=](std::future<std::shared_ptr<std::string>> fut) {
-            try {
-              auto data = fut.get();
+  getFile(narInfoFile,
+          Callback<std::shared_ptr<std::string>>(
+              [=](std::future<std::shared_ptr<std::string>> fut) {
+                try {
+                  auto data = fut.get();
 
-              if (!data) {
-                return (*callbackPtr)(nullptr);
-              }
+                  if (!data) {
+                    return (*callbackPtr)(nullptr);
+                  }
 
-              stats.narInfoRead++;
+                  stats.narInfoRead++;
 
-              (*callbackPtr)(std::shared_ptr<ValidPathInfo>(
-                  std::make_shared<NarInfo>(*this, *data, narInfoFile)));
+                  (*callbackPtr)(std::shared_ptr<ValidPathInfo>(
+                      std::make_shared<NarInfo>(*this, *data, narInfoFile)));
 
-            } catch (...) {
-              callbackPtr->rethrow();
-            }
-          }});
+                } catch (...) {
+                  callbackPtr->rethrow();
+                }
+              }));
 }
 
 Path BinaryCacheStore::addToStore(const std::string& name, const Path& srcPath,
diff --git a/third_party/nix/src/libstore/build.cc b/third_party/nix/src/libstore/build.cc
index 83aea3899ec7..3dce1566535d 100644
--- a/third_party/nix/src/libstore/build.cc
+++ b/third_party/nix/src/libstore/build.cc
@@ -574,8 +574,8 @@ UserLock::UserLock() {
     }
 
     try {
-      AutoCloseFD fd =
-          open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
+      AutoCloseFD fd(
+          open(fnUserLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600));
       if (!fd) {
         throw SysError(format("opening user lock '%1%'") % fnUserLock);
       }
@@ -698,8 +698,8 @@ HookInstance::HookInstance() {
   });
 
   pid.setSeparatePG(true);
-  fromHook.writeSide = -1;
-  toHook.readSide = -1;
+  fromHook.writeSide = AutoCloseFD(-1);
+  toHook.readSide = AutoCloseFD(-1);
 
   sink = FdSink(toHook.writeSide.get());
   std::map<std::string, Config::SettingInfo> settings;
@@ -712,8 +712,8 @@ HookInstance::HookInstance() {
 
 HookInstance::~HookInstance() {
   try {
-    toHook.writeSide = -1;
-    if (pid != -1) {
+    toHook.writeSide = AutoCloseFD(-1);
+    if (pid != Pid(-1)) {
       pid.kill();
     }
   } catch (...) {
@@ -1056,7 +1056,7 @@ DerivationGoal::~DerivationGoal() {
 inline bool DerivationGoal::needsHashRewrite() { return !useChroot; }
 
 void DerivationGoal::killChild() {
-  if (pid != -1) {
+  if (pid != Pid(-1)) {
     worker.childTerminated(this);
 
     if (buildUser) {
@@ -1066,14 +1066,14 @@ void DerivationGoal::killChild() {
          it won't be killed, and we'll potentially lock up in
          pid.wait().  So also send a conventional kill to the
          child. */
-      ::kill(-pid, SIGKILL); /* ignore the result */
+      ::kill(-static_cast<pid_t>(pid), SIGKILL); /* ignore the result */
       buildUser->kill();
       pid.wait();
     } else {
       pid.kill();
     }
 
-    assert(pid == -1);
+    assert(pid == Pid(-1));
   }
 
   hook.reset();
@@ -1572,10 +1572,10 @@ void DerivationGoal::buildDone() {
 
   /* Close the read side of the logger pipe. */
   if (hook) {
-    hook->builderOut.readSide = -1;
-    hook->fromHook.readSide = -1;
+    hook->builderOut.readSide = AutoCloseFD(-1);
+    hook->fromHook.readSide = AutoCloseFD(-1);
   } else {
-    builderOut.readSide = -1;
+    builderOut.readSide = AutoCloseFD(-1);
   }
 
   /* Close the log file. */
@@ -1830,7 +1830,7 @@ HookReply DerivationGoal::tryBuildHook() {
   hook->sink << missingPaths;
 
   hook->sink = FdSink();
-  hook->toHook.writeSide = -1;
+  hook->toHook.writeSide = AutoCloseFD(-1);
 
   /* Create the log file and pipe. */
   Path logFile = openLogFile();
@@ -2268,7 +2268,7 @@ void DerivationGoal::startBuilder() {
   /* Create a pipe to get the output of the builder. */
   // builderOut.create();
 
-  builderOut.readSide = posix_openpt(O_RDWR | O_NOCTTY);
+  builderOut.readSide = AutoCloseFD(posix_openpt(O_RDWR | O_NOCTTY));
   if (!builderOut.readSide) {
     throw SysError("opening pseudoterminal master");
   }
@@ -2300,7 +2300,8 @@ void DerivationGoal::startBuilder() {
     throw SysError("unlocking pseudoterminal");
   }
 
-  builderOut.writeSide = open(slaveName.c_str(), O_RDWR | O_NOCTTY);
+  builderOut.writeSide =
+      AutoCloseFD(open(slaveName.c_str(), O_RDWR | O_NOCTTY));
   if (!builderOut.writeSide) {
     throw SysError("opening pseudoterminal slave");
   }
@@ -2364,7 +2365,7 @@ void DerivationGoal::startBuilder() {
 
     userNamespaceSync.create();
 
-    Pid helper = startProcess(
+    Pid helper(startProcess(
         [&]() {
           /* Drop additional groups here because we can't do it
              after we've created the new user namespace.  FIXME:
@@ -2421,7 +2422,7 @@ void DerivationGoal::startBuilder() {
           writeFull(builderOut.writeSide.get(), std::to_string(child) + "\n");
           _exit(0);
         },
-        options);
+        options));
 
     int res = helper.wait();
     if (res != 0 && settings.sandboxFallback) {
@@ -2432,7 +2433,7 @@ void DerivationGoal::startBuilder() {
       throw Error("unable to start build process");
     }
 
-    userNamespaceSync.readSide = -1;
+    userNamespaceSync.readSide = AutoCloseFD(-1);
 
     pid_t tmp;
     if (!absl::SimpleAtoi(readLine(builderOut.readSide.get()), &tmp)) {
@@ -2446,18 +2447,19 @@ void DerivationGoal::startBuilder() {
     uid_t hostUid = buildUser ? buildUser->getUID() : getuid();
     uid_t hostGid = buildUser ? buildUser->getGID() : getgid();
 
-    writeFile("/proc/" + std::to_string(pid) + "/uid_map",
+    writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/uid_map",
               (format("%d %d 1") % sandboxUid % hostUid).str());
 
-    writeFile("/proc/" + std::to_string(pid) + "/setgroups", "deny");
+    writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/setgroups",
+              "deny");
 
-    writeFile("/proc/" + std::to_string(pid) + "/gid_map",
+    writeFile("/proc/" + std::to_string(static_cast<pid_t>(pid)) + "/gid_map",
               (format("%d %d 1") % sandboxGid % hostGid).str());
 
     /* Signal the builder that we've updated its user
        namespace. */
     writeFull(userNamespaceSync.writeSide.get(), "1");
-    userNamespaceSync.writeSide = -1;
+    userNamespaceSync.writeSide = AutoCloseFD(-1);
 
   } else
 #endif
@@ -2468,7 +2470,7 @@ void DerivationGoal::startBuilder() {
 
   /* parent */
   pid.setSeparatePG(true);
-  builderOut.writeSide = -1;
+  builderOut.writeSide = AutoCloseFD(-1);
   worker.childStarted(shared_from_this(), {builderOut.readSide.get()}, true,
                       true);
 
@@ -2837,13 +2839,13 @@ void DerivationGoal::runChild() {
 
 #if __linux__
     if (useChroot) {
-      userNamespaceSync.writeSide = -1;
+      userNamespaceSync.writeSide = AutoCloseFD(-1);
 
       if (drainFD(userNamespaceSync.readSide.get()) != "1") {
         throw Error("user namespace initialisation failed");
       }
 
-      userNamespaceSync.readSide = -1;
+      userNamespaceSync.readSide = AutoCloseFD(-1);
 
       if (privateNetwork) {
         /* Initialise the loopback interface. */
@@ -3738,8 +3740,8 @@ Path DerivationGoal::openLogFile() {
   Path logFileName = fmt("%s/%s%s", dir, std::string(baseName, 2),
                          settings.compressLog ? ".bz2" : "");
 
-  fdLogFile =
-      open(logFileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666);
+  fdLogFile = AutoCloseFD(open(logFileName.c_str(),
+                               O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0666));
   if (!fdLogFile) {
     throw SysError(format("creating log file '%1%'") % logFileName);
   }
@@ -3765,7 +3767,7 @@ void DerivationGoal::closeLogFile() {
     logFileSink->flush();
   }
   logSink = logFileSink = nullptr;
-  fdLogFile = -1;
+  fdLogFile = AutoCloseFD(-1);
 }
 
 void DerivationGoal::deleteTmpDir(bool force) {
@@ -4163,7 +4165,7 @@ void SubstitutionGoal::tryToRun() {
   thr = std::thread([this]() {
     try {
       /* Wake up the worker loop when we're done. */
-      Finally updateStats([this]() { outPipe.writeSide = -1; });
+      Finally updateStats([this]() { outPipe.writeSide = AutoCloseFD(-1); });
 
       copyStorePath(ref<Store>(sub),
                     ref<Store>(worker.store.shared_from_this()), storePath,
diff --git a/third_party/nix/src/libstore/download.cc b/third_party/nix/src/libstore/download.cc
index 60a409d0dc4f..ee2ce8152dbc 100644
--- a/third_party/nix/src/libstore/download.cc
+++ b/third_party/nix/src/libstore/download.cc
@@ -744,13 +744,15 @@ ref<Downloader> makeDownloader() { return make_ref<CurlDownloader>(); }
 std::future<DownloadResult> Downloader::enqueueDownload(
     const DownloadRequest& request) {
   auto promise = std::make_shared<std::promise<DownloadResult>>();
-  enqueueDownload(request, {[promise](std::future<DownloadResult> fut) {
-                    try {
-                      promise->set_value(fut.get());
-                    } catch (...) {
-                      promise->set_exception(std::current_exception());
-                    }
-                  }});
+  enqueueDownload(
+      request,
+      Callback<DownloadResult>([promise](std::future<DownloadResult> fut) {
+        try {
+          promise->set_value(fut.get());
+        } catch (...) {
+          promise->set_exception(std::current_exception());
+        }
+      }));
   return promise->get_future();
 }
 
@@ -807,17 +809,18 @@ void Downloader::download(DownloadRequest&& request, Sink& sink) {
     state->avail.notify_one();
   };
 
-  enqueueDownload(request, {[_state](std::future<DownloadResult> fut) {
-                    auto state(_state->lock());
-                    state->quit = true;
-                    try {
-                      fut.get();
-                    } catch (...) {
-                      state->exc = std::current_exception();
-                    }
-                    state->avail.notify_one();
-                    state->request.notify_one();
-                  }});
+  enqueueDownload(request, Callback<DownloadResult>(
+                               [_state](std::future<DownloadResult> fut) {
+                                 auto state(_state->lock());
+                                 state->quit = true;
+                                 try {
+                                   fut.get();
+                                 } catch (...) {
+                                   state->exc = std::current_exception();
+                                 }
+                                 state->avail.notify_one();
+                                 state->request.notify_one();
+                               }));
 
   while (true) {
     checkInterrupt();
diff --git a/third_party/nix/src/libstore/gc.cc b/third_party/nix/src/libstore/gc.cc
index 596046e4f324..4f04e09a7555 100644
--- a/third_party/nix/src/libstore/gc.cc
+++ b/third_party/nix/src/libstore/gc.cc
@@ -35,8 +35,9 @@ AutoCloseFD LocalStore::openGCLock(LockType lockType) {
 
   DLOG(INFO) << "acquiring global GC lock " << fnGCLock;
 
-  AutoCloseFD fdGCLock =
-      open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
+  AutoCloseFD fdGCLock(
+      open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600));
+
   if (!fdGCLock) {
     throw SysError(format("opening global GC lock '%1%'") % fnGCLock);
   }
@@ -160,7 +161,7 @@ void LocalStore::addTempRoot(const Path& path) {
 
       state->fdTempRoots = openLockFile(fnTempRoots, true);
 
-      fdGCLock = -1;
+      fdGCLock = AutoCloseFD(-1);
 
       DLOG(INFO) << "acquiring read lock on " << fnTempRoots;
       lockFile(state->fdTempRoots.get(), ltRead, true);
@@ -886,7 +887,7 @@ void LocalStore::collectGarbage(const GCOptions& options, GCResults& results) {
   }
 
   /* Allow other processes to add to the store from here on. */
-  fdGCLock = -1;
+  fdGCLock = AutoCloseFD(-1);
   fds.clear();
 
   /* Delete the trash directory. */
diff --git a/third_party/nix/src/libstore/http-binary-cache-store.cc b/third_party/nix/src/libstore/http-binary-cache-store.cc
index 8ab07033b191..c713ac43c47a 100644
--- a/third_party/nix/src/libstore/http-binary-cache-store.cc
+++ b/third_party/nix/src/libstore/http-binary-cache-store.cc
@@ -135,20 +135,22 @@ class HttpBinaryCacheStore : public BinaryCacheStore {
         std::make_shared<decltype(callback)>(std::move(callback));
 
     getDownloader()->enqueueDownload(
-        request, {[callbackPtr, this](std::future<DownloadResult> result) {
-          try {
-            (*callbackPtr)(result.get().data);
-          } catch (DownloadError& e) {
-            if (e.error == Downloader::NotFound ||
-                e.error == Downloader::Forbidden) {
-              return (*callbackPtr)(std::shared_ptr<std::string>());
-            }
-            maybeDisable();
-            callbackPtr->rethrow();
-          } catch (...) {
-            callbackPtr->rethrow();
-          }
-        }});
+        request,
+        Callback<DownloadResult>{
+            [callbackPtr, this](std::future<DownloadResult> result) {
+              try {
+                (*callbackPtr)(result.get().data);
+              } catch (DownloadError& e) {
+                if (e.error == Downloader::NotFound ||
+                    e.error == Downloader::Forbidden) {
+                  return (*callbackPtr)(std::shared_ptr<std::string>());
+                }
+                maybeDisable();
+                callbackPtr->rethrow();
+              } catch (...) {
+                callbackPtr->rethrow();
+              }
+            }});
   }
 };
 
diff --git a/third_party/nix/src/libstore/local-store.cc b/third_party/nix/src/libstore/local-store.cc
index 5e3271a5f3cc..aca305e1a52f 100644
--- a/third_party/nix/src/libstore/local-store.cc
+++ b/third_party/nix/src/libstore/local-store.cc
@@ -135,8 +135,8 @@ LocalStore::LocalStore(const Params& params)
     struct stat st;
     if (stat(reservedPath.c_str(), &st) == -1 ||
         st.st_size != settings.reservedSize) {
-      AutoCloseFD fd =
-          open(reservedPath.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, 0600);
+      AutoCloseFD fd(
+          open(reservedPath.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, 0600));
       int res = -1;
 #if HAVE_POSIX_FALLOCATE
       res = posix_fallocate(fd.get(), 0, settings.reservedSize);
@@ -288,7 +288,7 @@ LocalStore::~LocalStore() {
   try {
     auto state(_state.lock());
     if (state->fdTempRoots) {
-      state->fdTempRoots = -1;
+      state->fdTempRoots = AutoCloseFD(-1);
       unlink(fnTempRoots.c_str());
     }
   } catch (...) {
@@ -1278,7 +1278,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) {
   PathSet validPaths;
   PathSet done;
 
-  fdGCLock = -1;
+  fdGCLock = AutoCloseFD(-1);
 
   for (auto& i : validPaths2) {
     verifyPath(i, store, done, validPaths, repair, errors);
diff --git a/third_party/nix/src/libstore/misc.cc b/third_party/nix/src/libstore/misc.cc
index 8a05d55accd0..44e67ada369c 100644
--- a/third_party/nix/src/libstore/misc.cc
+++ b/third_party/nix/src/libstore/misc.cc
@@ -38,74 +38,76 @@ void Store::computeFSClosure(const PathSet& startPaths, PathSet& paths_,
     }
 
     queryPathInfo(
-        path, {[&, path](std::future<ref<ValidPathInfo>> fut) {
-          // FIXME: calls to isValidPath() should be async
-
-          try {
-            auto info = fut.get();
-
-            if (flipDirection) {
-              PathSet referrers;
-              queryReferrers(path, referrers);
-              for (auto& ref : referrers) {
-                if (ref != path) {
-                  enqueue(ref);
-                }
-              }
+        path,
+        Callback<ref<ValidPathInfo>>(
+            [&, path](std::future<ref<ValidPathInfo>> fut) {
+              // FIXME: calls to isValidPath() should be async
+
+              try {
+                auto info = fut.get();
+
+                if (flipDirection) {
+                  PathSet referrers;
+                  queryReferrers(path, referrers);
+                  for (auto& ref : referrers) {
+                    if (ref != path) {
+                      enqueue(ref);
+                    }
+                  }
 
-              if (includeOutputs) {
-                for (auto& i : queryValidDerivers(path)) {
-                  enqueue(i);
-                }
-              }
+                  if (includeOutputs) {
+                    for (auto& i : queryValidDerivers(path)) {
+                      enqueue(i);
+                    }
+                  }
 
-              if (includeDerivers && isDerivation(path)) {
-                for (auto& i : queryDerivationOutputs(path)) {
-                  if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
-                    enqueue(i);
+                  if (includeDerivers && isDerivation(path)) {
+                    for (auto& i : queryDerivationOutputs(path)) {
+                      if (isValidPath(i) && queryPathInfo(i)->deriver == path) {
+                        enqueue(i);
+                      }
+                    }
+                  }
+
+                } else {
+                  for (auto& ref : info->references) {
+                    if (ref != path) {
+                      enqueue(ref);
+                    }
                   }
-                }
-              }
 
-            } else {
-              for (auto& ref : info->references) {
-                if (ref != path) {
-                  enqueue(ref);
+                  if (includeOutputs && isDerivation(path)) {
+                    for (auto& i : queryDerivationOutputs(path)) {
+                      if (isValidPath(i)) {
+                        enqueue(i);
+                      }
+                    }
+                  }
+
+                  if (includeDerivers && isValidPath(info->deriver)) {
+                    enqueue(info->deriver);
+                  }
                 }
-              }
 
-              if (includeOutputs && isDerivation(path)) {
-                for (auto& i : queryDerivationOutputs(path)) {
-                  if (isValidPath(i)) {
-                    enqueue(i);
+                {
+                  auto state(state_.lock());
+                  assert(state->pending);
+                  if (--state->pending == 0u) {
+                    done.notify_one();
                   }
                 }
-              }
-
-              if (includeDerivers && isValidPath(info->deriver)) {
-                enqueue(info->deriver);
-              }
-            }
-
-            {
-              auto state(state_.lock());
-              assert(state->pending);
-              if (--state->pending == 0u) {
-                done.notify_one();
-              }
-            }
-
-          } catch (...) {
-            auto state(state_.lock());
-            if (!state->exc) {
-              state->exc = std::current_exception();
-            }
-            assert(state->pending);
-            if (--state->pending == 0u) {
-              done.notify_one();
-            }
-          };
-        }});
+
+              } catch (...) {
+                auto state(state_.lock());
+                if (!state->exc) {
+                  state->exc = std::current_exception();
+                }
+                assert(state->pending);
+                if (--state->pending == 0u) {
+                  done.notify_one();
+                }
+              };
+            }));
   };
 
   for (auto& startPath : startPaths) {
diff --git a/third_party/nix/src/libstore/pathlocks.cc b/third_party/nix/src/libstore/pathlocks.cc
index 4b153856d283..8a874adbe913 100644
--- a/third_party/nix/src/libstore/pathlocks.cc
+++ b/third_party/nix/src/libstore/pathlocks.cc
@@ -15,9 +15,9 @@
 namespace nix {
 
 AutoCloseFD openLockFile(const Path& path, bool create) {
-  AutoCloseFD fd;
+  AutoCloseFD fd(
+      open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600));
 
-  fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600);
   if (!fd && (create || errno != ENOENT)) {
     throw SysError(format("opening lock file '%1%'") % path);
   }
diff --git a/third_party/nix/src/libstore/remote-fs-accessor.cc b/third_party/nix/src/libstore/remote-fs-accessor.cc
index d5b20288479c..4178030b55d6 100644
--- a/third_party/nix/src/libstore/remote-fs-accessor.cc
+++ b/third_party/nix/src/libstore/remote-fs-accessor.cc
@@ -70,7 +70,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path& path_) {
 
       auto narAccessor = makeLazyNarAccessor(
           listing, [cacheFile](uint64_t offset, uint64_t length) {
-            AutoCloseFD fd = open(cacheFile.c_str(), O_RDONLY | O_CLOEXEC);
+            AutoCloseFD fd(open(cacheFile.c_str(), O_RDONLY | O_CLOEXEC));
             if (!fd) {
               throw SysError("opening NAR cache file '%s'", cacheFile);
             }
diff --git a/third_party/nix/src/libstore/ssh.cc b/third_party/nix/src/libstore/ssh.cc
index 52fbe6425458..7d5fe6d10937 100644
--- a/third_party/nix/src/libstore/ssh.cc
+++ b/third_party/nix/src/libstore/ssh.cc
@@ -88,8 +88,8 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
       },
       options);
 
-  in.readSide = -1;
-  out.writeSide = -1;
+  in.readSide = AutoCloseFD(-1);
+  out.writeSide = AutoCloseFD(-1);
 
   conn->out = std::move(out.readSide);
   conn->in = std::move(in.writeSide);
@@ -104,7 +104,7 @@ Path SSHMaster::startMaster() {
 
   auto state(state_.lock());
 
-  if (state->sshMaster != -1) {
+  if (state->sshMaster != Pid(-1)) {
     return state->socketPath;
   }
 
@@ -142,7 +142,7 @@ Path SSHMaster::startMaster() {
       },
       options);
 
-  out.writeSide = -1;
+  out.writeSide = AutoCloseFD(-1);
 
   std::string reply;
   try {
diff --git a/third_party/nix/src/libstore/store-api.cc b/third_party/nix/src/libstore/store-api.cc
index 0ea6b1d62c34..d7ca54fa9a77 100644
--- a/third_party/nix/src/libstore/store-api.cc
+++ b/third_party/nix/src/libstore/store-api.cc
@@ -392,7 +392,10 @@ Path Store::computeStorePathForText(const std::string& name,
 }
 
 Store::Store(const Params& params)
-    : Config(params), state({(size_t)pathInfoCacheSize}) {}
+    : Config(params),
+      state(Sync<State>{
+          State{LRUCache<std::string, std::shared_ptr<ValidPathInfo>>(
+              (size_t)pathInfoCacheSize)}}) {}
 
 std::string Store::getUri() { return ""; }
 
@@ -446,13 +449,15 @@ bool Store::isValidPathUncached(const Path& path) {
 ref<const ValidPathInfo> Store::queryPathInfo(const Path& storePath) {
   std::promise<ref<ValidPathInfo>> promise;
 
-  queryPathInfo(storePath, {[&](std::future<ref<ValidPathInfo>> result) {
-                  try {
-                    promise.set_value(result.get());
-                  } catch (...) {
-                    promise.set_exception(std::current_exception());
-                  }
-                }});
+  queryPathInfo(
+      storePath,
+      Callback<ref<ValidPathInfo>>([&](std::future<ref<ValidPathInfo>> result) {
+        try {
+          promise.set_value(result.get());
+        } catch (...) {
+          promise.set_exception(std::current_exception());
+        }
+      }));
 
   return promise.get_future().get();
 }
@@ -503,31 +508,33 @@ void Store::queryPathInfo(const Path& storePath,
   auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
 
   queryPathInfoUncached(
-      storePath, {[this, storePath, hashPart, callbackPtr](
-                      std::future<std::shared_ptr<ValidPathInfo>> fut) {
-        try {
-          auto info = fut.get();
+      storePath,
+      Callback<std::shared_ptr<ValidPathInfo>>{
+          [this, storePath, hashPart,
+           callbackPtr](std::future<std::shared_ptr<ValidPathInfo>> fut) {
+            try {
+              auto info = fut.get();
 
-          if (diskCache) {
-            diskCache->upsertNarInfo(getUri(), hashPart, info);
-          }
+              if (diskCache) {
+                diskCache->upsertNarInfo(getUri(), hashPart, info);
+              }
 
-          {
-            auto state_(state.lock());
-            state_->pathInfoCache.upsert(hashPart, info);
-          }
+              {
+                auto state_(state.lock());
+                state_->pathInfoCache.upsert(hashPart, info);
+              }
 
-          if (!info || (info->path != storePath &&
-                        !storePathToName(storePath).empty())) {
-            stats.narInfoMissing++;
-            throw InvalidPath("path '%s' is not valid", storePath);
-          }
+              if (!info || (info->path != storePath &&
+                            !storePathToName(storePath).empty())) {
+                stats.narInfoMissing++;
+                throw InvalidPath("path '%s' is not valid", storePath);
+              }
 
-          (*callbackPtr)(ref<ValidPathInfo>(info));
-        } catch (...) {
-          callbackPtr->rethrow();
-        }
-      }});
+              (*callbackPtr)(ref<ValidPathInfo>(info));
+            } catch (...) {
+              callbackPtr->rethrow();
+            }
+          }});
 }
 
 PathSet Store::queryValidPaths(const PathSet& paths,
@@ -545,21 +552,22 @@ PathSet Store::queryValidPaths(const PathSet& paths,
 
   auto doQuery = [&](const Path& path) {
     checkInterrupt();
-    queryPathInfo(
-        path, {[path, &state_, &wakeup](std::future<ref<ValidPathInfo>> fut) {
-          auto state(state_.lock());
-          try {
-            auto info = fut.get();
-            state->valid.insert(path);
-          } catch (InvalidPath&) {
-          } catch (...) {
-            state->exc = std::current_exception();
-          }
-          assert(state->left);
-          if (--state->left == 0u) {
-            wakeup.notify_one();
-          }
-        }});
+    queryPathInfo(path, Callback<ref<ValidPathInfo>>(
+                            [path, &state_,
+                             &wakeup](std::future<ref<ValidPathInfo>> fut) {
+                              auto state(state_.lock());
+                              try {
+                                auto info = fut.get();
+                                state->valid.insert(path);
+                              } catch (InvalidPath&) {
+                              } catch (...) {
+                                state->exc = std::current_exception();
+                              }
+                              assert(state->left);
+                              if (--state->left == 0u) {
+                                wakeup.notify_one();
+                              }
+                            }));
   };
 
   for (auto& path : paths) {
diff --git a/third_party/nix/src/libutil/archive.cc b/third_party/nix/src/libutil/archive.cc
index 4489b7d2a8c5..e3233d9ee4cc 100644
--- a/third_party/nix/src/libutil/archive.cc
+++ b/third_party/nix/src/libutil/archive.cc
@@ -45,7 +45,7 @@ PathFilter defaultPathFilter = [](const Path& /*unused*/) { return true; };
 static void dumpContents(const Path& path, size_t size, Sink& sink) {
   sink << "contents" << size;
 
-  AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+  AutoCloseFD fd(open(path.c_str(), O_RDONLY | O_CLOEXEC));
   if (!fd) {
     throw SysError(format("opening file '%1%'") % path);
   }
@@ -334,7 +334,8 @@ struct RestoreSink : ParseSink {
 
   void createRegularFile(const Path& path) override {
     Path p = dstPath + path;
-    fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
+    fd = AutoCloseFD(
+        open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666));
     if (!fd) {
       throw SysError(format("creating file '%1%'") % p);
     }
diff --git a/third_party/nix/src/libutil/archive.hh b/third_party/nix/src/libutil/archive.hh
index 07f58b5f9433..194d31d078c4 100644
--- a/third_party/nix/src/libutil/archive.hh
+++ b/third_party/nix/src/libutil/archive.hh
@@ -62,7 +62,7 @@ struct ParseSink {
 struct TeeSink : ParseSink {
   TeeSource source;
 
-  TeeSink(Source& source) : source(source) {}
+  explicit TeeSink(Source& source) : source(source) {}
 };
 
 void parseDump(ParseSink& sink, Source& source);
diff --git a/third_party/nix/src/libutil/args.hh b/third_party/nix/src/libutil/args.hh
index 57720439bd03..bb1ef43912bb 100644
--- a/third_party/nix/src/libutil/args.hh
+++ b/third_party/nix/src/libutil/args.hh
@@ -65,7 +65,8 @@ class Args {
     Args& args;
     Flag::ptr flag;
     friend class Args;
-    FlagMaker(Args& args) : args(args), flag(std::make_shared<Flag>()){};
+    explicit FlagMaker(Args& args)
+        : args(args), flag(std::make_shared<Flag>()){};
 
    public:
     ~FlagMaker();
diff --git a/third_party/nix/src/libutil/config.hh b/third_party/nix/src/libutil/config.hh
index 027a6be2982a..81b1c80e0e97 100644
--- a/third_party/nix/src/libutil/config.hh
+++ b/third_party/nix/src/libutil/config.hh
@@ -16,7 +16,8 @@ class AbstractConfig {
  protected:
   StringMap unknownSettings;
 
-  AbstractConfig(const StringMap& initials = {}) : unknownSettings(initials) {}
+  explicit AbstractConfig(const StringMap& initials = {})
+      : unknownSettings(initials) {}
 
  public:
   virtual bool set(const std::string& name, const std::string& value) = 0;
@@ -74,7 +75,7 @@ class Config : public AbstractConfig {
   Settings _settings;
 
  public:
-  Config(const StringMap& initials = {}) : AbstractConfig(initials) {}
+  explicit Config(const StringMap& initials = {}) : AbstractConfig(initials) {}
 
   bool set(const std::string& name, const std::string& value) override;
 
@@ -218,7 +219,7 @@ struct GlobalConfig : public AbstractConfig {
   void convertToArgs(Args& args, const std::string& category) override;
 
   struct Register {
-    Register(Config* config);
+    explicit Register(Config* config);
   };
 };
 
diff --git a/third_party/nix/src/libutil/finally.hh b/third_party/nix/src/libutil/finally.hh
index 8d3083b6a3ac..2ead8661a6e7 100644
--- a/third_party/nix/src/libutil/finally.hh
+++ b/third_party/nix/src/libutil/finally.hh
@@ -8,6 +8,6 @@ class Finally {
   std::function<void()> fun;
 
  public:
-  Finally(std::function<void()> fun) : fun(fun) {}
+  explicit Finally(std::function<void()> fun) : fun(fun) {}
   ~Finally() { fun(); }
 };
diff --git a/third_party/nix/src/libutil/hash.cc b/third_party/nix/src/libutil/hash.cc
index a2d6713f04ff..ba61254392e0 100644
--- a/third_party/nix/src/libutil/hash.cc
+++ b/third_party/nix/src/libutil/hash.cc
@@ -387,7 +387,7 @@ Hash hashFile(HashType ht, const Path& path) {
   Hash hash(ht);
   start(ht, ctx);
 
-  AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
+  AutoCloseFD fd(open(path.c_str(), O_RDONLY | O_CLOEXEC));
   if (!fd) {
     throw SysError(format("opening file '%1%'") % path);
   }
diff --git a/third_party/nix/src/libutil/hash.hh b/third_party/nix/src/libutil/hash.hh
index 6fbeec5b47fb..8b52ac657e7f 100644
--- a/third_party/nix/src/libutil/hash.hh
+++ b/third_party/nix/src/libutil/hash.hh
@@ -42,14 +42,14 @@ struct Hash {
   Hash(){};
 
   /* Create a zero-filled hash object. */
-  Hash(HashType type) : type(type) { init(); };
+  explicit Hash(HashType type) : type(type) { init(); };
 
   /* Initialize the hash from a string representation, in the format
      "[<type>:]<base16|base32|base64>" or "<type>-<base64>" (a
      Subresource Integrity hash expression). If the 'type' argument
      is htUnknown, then the hash type must be specified in the
      string. */
-  Hash(std::string_view s, HashType type = htUnknown);
+  explicit Hash(std::string_view s, HashType type = htUnknown);
 
   /* Status-returning version of above constructor */
   static absl::StatusOr<Hash> deserialize(std::string_view s,
@@ -61,7 +61,7 @@ struct Hash {
   void init();
 
   /* Check whether a hash is set. */
-  operator bool() const { return type != htUnknown; }
+  explicit operator bool() const { return type != htUnknown; }
 
   /* Check whether two hash are equal. */
   bool operator==(const Hash& h2) const;
@@ -136,7 +136,7 @@ class HashSink : public BufferedSink {
   unsigned long long bytes;
 
  public:
-  HashSink(HashType ht);
+  explicit HashSink(HashType ht);
   HashSink(const HashSink& h);
   ~HashSink();
   void write(const unsigned char* data, size_t len);
diff --git a/third_party/nix/src/libutil/json.hh b/third_party/nix/src/libutil/json.hh
index a3843a8a8a7b..14d61d8a5716 100644
--- a/third_party/nix/src/libutil/json.hh
+++ b/third_party/nix/src/libutil/json.hh
@@ -29,7 +29,7 @@ class JSONWriter {
 
   JSONWriter(std::ostream& str, bool indent);
 
-  JSONWriter(JSONState* state);
+  explicit JSONWriter(JSONState* state);
 
   ~JSONWriter();
 
@@ -50,10 +50,11 @@ class JSONList : JSONWriter {
 
   void open();
 
-  JSONList(JSONState* state) : JSONWriter(state) { open(); }
+  explicit JSONList(JSONState* state) : JSONWriter(state) { open(); }
 
  public:
-  JSONList(std::ostream& str, bool indent = false) : JSONWriter(str, indent) {
+  explicit JSONList(std::ostream& str, bool indent = false)
+      : JSONWriter(str, indent) {
     open();
   }
 
@@ -80,12 +81,13 @@ class JSONObject : JSONWriter {
 
   void open();
 
-  JSONObject(JSONState* state) : JSONWriter(state) { open(); }
+  explicit JSONObject(JSONState* state) : JSONWriter(state) { open(); }
 
   void attr(const std::string& s);
 
  public:
-  JSONObject(std::ostream& str, bool indent = false) : JSONWriter(str, indent) {
+  explicit JSONObject(std::ostream& str, bool indent = false)
+      : JSONWriter(str, indent) {
     open();
   }
 
@@ -114,7 +116,7 @@ class JSONPlaceholder : JSONWriter {
   friend class JSONList;
   friend class JSONObject;
 
-  JSONPlaceholder(JSONState* state) : JSONWriter(state) {}
+  explicit JSONPlaceholder(JSONState* state) : JSONWriter(state) {}
 
   void assertValid() {
     assertActive();
@@ -122,7 +124,7 @@ class JSONPlaceholder : JSONWriter {
   }
 
  public:
-  JSONPlaceholder(std::ostream& str, bool indent = false)
+  explicit JSONPlaceholder(std::ostream& str, bool indent = false)
       : JSONWriter(str, indent) {}
 
   ~JSONPlaceholder() { assert(!first || std::uncaught_exception()); }
diff --git a/third_party/nix/src/libutil/lazy.hh b/third_party/nix/src/libutil/lazy.hh
index b564b481fc38..5c6ff5d8df6a 100644
--- a/third_party/nix/src/libutil/lazy.hh
+++ b/third_party/nix/src/libutil/lazy.hh
@@ -25,7 +25,7 @@ class Lazy {
   std::exception_ptr ex;
 
  public:
-  Lazy(Init init) : init(init) {}
+  explicit Lazy(Init init) : init(init) {}
 
   const T& operator()() {
     std::call_once(done, [&]() {
diff --git a/third_party/nix/src/libutil/lru-cache.hh b/third_party/nix/src/libutil/lru-cache.hh
index f6fcdaf82ebd..1832c542449e 100644
--- a/third_party/nix/src/libutil/lru-cache.hh
+++ b/third_party/nix/src/libutil/lru-cache.hh
@@ -27,7 +27,7 @@ class LRUCache {
   LRU lru;
 
  public:
-  LRUCache(size_t capacity) : capacity(capacity) {}
+  explicit LRUCache(size_t capacity) : capacity(capacity) {}
 
   /* Insert or upsert an item in the cache. */
   void upsert(const Key& key, const Value& value) {
diff --git a/third_party/nix/src/libutil/pool.hh b/third_party/nix/src/libutil/pool.hh
index e3ea8cad5734..b5c3c4b5c43f 100644
--- a/third_party/nix/src/libutil/pool.hh
+++ b/third_party/nix/src/libutil/pool.hh
@@ -53,7 +53,7 @@ class Pool {
   std::condition_variable wakeup;
 
  public:
-  Pool(
+  explicit Pool(
       size_t max = std::numeric_limits<size_t>::max(),
       const Factory& factory = []() { return make_ref<R>(); },
       const Validator& validator = [](ref<R> r) { return true; })
diff --git a/third_party/nix/src/libutil/ref.hh b/third_party/nix/src/libutil/ref.hh
index 063e6b327c22..3c375491fd0b 100644
--- a/third_party/nix/src/libutil/ref.hh
+++ b/third_party/nix/src/libutil/ref.hh
@@ -9,7 +9,7 @@ namespace nix {
 /* A simple non-nullable reference-counted pointer. Actually a wrapper
    around std::shared_ptr that prevents non-null constructions. */
 template <typename T>
-class ref {
+class ref {  // TODO(tazjin): rename to brainworm_ref or something
  private:
   std::shared_ptr<T> p;
 
diff --git a/third_party/nix/src/libutil/serialise.hh b/third_party/nix/src/libutil/serialise.hh
index bbfbe16a016c..c6d1d814dbdd 100644
--- a/third_party/nix/src/libutil/serialise.hh
+++ b/third_party/nix/src/libutil/serialise.hh
@@ -23,7 +23,7 @@ struct BufferedSink : Sink {
   size_t bufSize, bufPos;
   std::unique_ptr<unsigned char[]> buffer;
 
-  BufferedSink(size_t bufSize = 32 * 1024)
+  explicit BufferedSink(size_t bufSize = 32 * 1024)
       : bufSize(bufSize), bufPos(0), buffer(nullptr) {}
 
   void operator()(const unsigned char* data, size_t len) override;
@@ -59,7 +59,7 @@ struct BufferedSource : Source {
   size_t bufSize, bufPosIn, bufPosOut;
   std::unique_ptr<unsigned char[]> buffer;
 
-  BufferedSource(size_t bufSize = 32 * 1024)
+  explicit BufferedSource(size_t bufSize = 32 * 1024)
       : bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(nullptr) {}
 
   size_t read(unsigned char* data, size_t len) override;
@@ -78,7 +78,7 @@ struct FdSink : BufferedSink {
   size_t written = 0;
 
   FdSink() : fd(-1) {}
-  FdSink(int fd) : fd(fd) {}
+  explicit FdSink(int fd) : fd(fd) {}
   FdSink(FdSink&&) = default;
 
   FdSink& operator=(FdSink&& s) {
@@ -106,7 +106,7 @@ struct FdSource : BufferedSource {
   size_t read = 0;
 
   FdSource() : fd(-1) {}
-  FdSource(int fd) : fd(fd) {}
+  explicit FdSource(int fd) : fd(fd) {}
   FdSource(FdSource&&) = default;
 
   FdSource& operator=(FdSource&& s) {
@@ -129,7 +129,7 @@ struct FdSource : BufferedSource {
 struct StringSink : Sink {
   ref<std::string> s;
   StringSink() : s(make_ref<std::string>()){};
-  StringSink(ref<std::string> s) : s(s){};
+  explicit StringSink(ref<std::string> s) : s(s){};
   void operator()(const unsigned char* data, size_t len) override;
 };
 
@@ -137,7 +137,7 @@ struct StringSink : Sink {
 struct StringSource : Source {
   const std::string& s;
   size_t pos;
-  StringSource(const std::string& _s) : s(_s), pos(0) {}
+  explicit StringSource(const std::string& _s) : s(_s), pos(0) {}
   size_t read(unsigned char* data, size_t len) override;
 };
 
@@ -145,7 +145,8 @@ struct StringSource : Source {
 struct TeeSource : Source {
   Source& orig;
   ref<std::string> data;
-  TeeSource(Source& orig) : orig(orig), data(make_ref<std::string>()) {}
+  explicit TeeSource(Source& orig)
+      : orig(orig), data(make_ref<std::string>()) {}
   size_t read(unsigned char* data, size_t len) {
     size_t n = orig.read(data, len);
     this->data->append((const char*)data, n);
@@ -186,7 +187,7 @@ struct LambdaSink : Sink {
 
   lambda_t lambda;
 
-  LambdaSink(const lambda_t& lambda) : lambda(lambda) {}
+  explicit LambdaSink(const lambda_t& lambda) : lambda(lambda) {}
 
   virtual void operator()(const unsigned char* data, size_t len) {
     lambda(data, len);
@@ -199,7 +200,7 @@ struct LambdaSource : Source {
 
   lambda_t lambda;
 
-  LambdaSource(const lambda_t& lambda) : lambda(lambda) {}
+  explicit LambdaSource(const lambda_t& lambda) : lambda(lambda) {}
 
   size_t read(unsigned char* data, size_t len) override {
     return lambda(data, len);
diff --git a/third_party/nix/src/libutil/sync.hh b/third_party/nix/src/libutil/sync.hh
index b79d1176b9f3..ef640d5b56ef 100644
--- a/third_party/nix/src/libutil/sync.hh
+++ b/third_party/nix/src/libutil/sync.hh
@@ -31,15 +31,15 @@ class Sync {
 
  public:
   Sync() {}
-  Sync(const T& data) : data(data) {}
-  Sync(T&& data) noexcept : data(std::move(data)) {}
+  explicit Sync(const T& data) : data(data) {}
+  explicit Sync(T&& data) noexcept : data(std::move(data)) {}
 
   class Lock {
    private:
     Sync* s;
     std::unique_lock<M> lk;
     friend Sync;
-    Lock(Sync* s) : s(s), lk(s->mutex) {}
+    explicit Lock(Sync* s) : s(s), lk(s->mutex) {}
 
    public:
     Lock(Lock&& l) : s(l.s) { abort(); }
diff --git a/third_party/nix/src/libutil/thread-pool.hh b/third_party/nix/src/libutil/thread-pool.hh
index 48888c0688c9..0efc4c1bfc67 100644
--- a/third_party/nix/src/libutil/thread-pool.hh
+++ b/third_party/nix/src/libutil/thread-pool.hh
@@ -17,7 +17,7 @@ MakeError(ThreadPoolShutDown, Error);
    (lambdas). */
 class ThreadPool {
  public:
-  ThreadPool(size_t maxThreads = 0);
+  explicit ThreadPool(size_t maxThreads = 0);
 
   ~ThreadPool();
 
diff --git a/third_party/nix/src/libutil/types.hh b/third_party/nix/src/libutil/types.hh
index b8e7a3c9d5c7..bf95206d0824 100644
--- a/third_party/nix/src/libutil/types.hh
+++ b/third_party/nix/src/libutil/types.hh
@@ -27,7 +27,7 @@ using boost::format;
    for all variadic arguments but ignoring the result. */
 struct nop {
   template <typename... T>
-  nop(T...) {}
+  explicit nop(T...) {}
 };
 
 struct FormatOrString {
@@ -69,11 +69,11 @@ class BaseError : public std::exception {
   unsigned int status = 1;  // exit status
 
   template <typename... Args>
-  BaseError(unsigned int status, Args... args)
+  explicit BaseError(unsigned int status, Args... args)
       : err(fmt(args...)), status(status) {}
 
   template <typename... Args>
-  BaseError(Args... args) : err(fmt(args...)) {}
+  explicit BaseError(Args... args) : err(fmt(args...)) {}
 
 #ifdef EXCEPTION_NEEDS_THROW_SPEC
   ~BaseError() noexcept {};
@@ -100,7 +100,7 @@ class SysError : public Error {
   int errNo;
 
   template <typename... Args>
-  SysError(Args... args) : Error(addErrno(fmt(args...))) {}
+  explicit SysError(Args... args) : Error(addErrno(fmt(args...))) {}
 
  private:
   std::string addErrno(const std::string& s);
diff --git a/third_party/nix/src/libutil/util.cc b/third_party/nix/src/libutil/util.cc
index 67bde4ad4fe6..939b6361d13c 100644
--- a/third_party/nix/src/libutil/util.cc
+++ b/third_party/nix/src/libutil/util.cc
@@ -312,7 +312,7 @@ std::string readFile(int fd) {
 }
 
 std::string readFile(absl::string_view path, bool drain) {
-  AutoCloseFD fd = open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC);
+  AutoCloseFD fd(open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC));
   if (!fd) {
     throw SysError(format("opening file '%1%'") % path);
   }
@@ -321,7 +321,7 @@ std::string readFile(absl::string_view path, bool drain) {
 
 void readFile(absl::string_view path, Sink& sink) {
   // TODO(tazjin): use stdlib functions for this stuff
-  AutoCloseFD fd = open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC);
+  AutoCloseFD fd(open(std::string(path).c_str(), O_RDONLY | O_CLOEXEC));
   if (!fd) {
     throw SysError("opening file '%s'", path);
   }
@@ -329,8 +329,8 @@ void readFile(absl::string_view path, Sink& sink) {
 }
 
 void writeFile(const Path& path, const std::string& s, mode_t mode) {
-  AutoCloseFD fd =
-      open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
+  AutoCloseFD fd(
+      open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode));
   if (!fd) {
     throw SysError(format("opening file '%1%'") % path);
   }
@@ -338,8 +338,8 @@ void writeFile(const Path& path, const std::string& s, mode_t mode) {
 }
 
 void writeFile(const Path& path, Source& source, mode_t mode) {
-  AutoCloseFD fd =
-      open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode);
+  AutoCloseFD fd(
+      open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode));
   if (!fd) {
     throw SysError(format("opening file '%1%'") % path);
   }
@@ -790,8 +790,8 @@ void Pipe::create() {
   closeOnExec(fds[0]);
   closeOnExec(fds[1]);
 #endif
-  readSide = fds[0];
-  writeSide = fds[1];
+  readSide = AutoCloseFD(fds[0]);
+  writeSide = AutoCloseFD(fds[1]);
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -868,7 +868,7 @@ void killUser(uid_t uid) {
 
   ProcessOptions options;
 
-  Pid pid = startProcess(
+  Pid pid(startProcess(
       [&]() {
         if (setuid(uid) == -1) {
           throw SysError("setting uid");
@@ -888,7 +888,7 @@ void killUser(uid_t uid) {
 
         _exit(0);
       },
-      options);
+      options));
 
   int status = pid.wait();
   if (status != 0) {
@@ -1024,7 +1024,7 @@ void runProgram2(const RunOptions& options) {
   ProcessOptions processOptions;
 
   /* Fork. */
-  Pid pid = startProcess(
+  Pid pid(startProcess(
       [&]() {
         if (options.environment) {
           replaceEnv(*options.environment);
@@ -1070,9 +1070,9 @@ void runProgram2(const RunOptions& options) {
 
         throw SysError("executing '%1%'", options.program);
       },
-      processOptions);
+      processOptions));
 
-  out.writeSide = -1;
+  out.writeSide = AutoCloseFD(-1);
 
   std::thread writerThread;
 
@@ -1085,7 +1085,7 @@ void runProgram2(const RunOptions& options) {
   });
 
   if (source != nullptr) {
-    in.readSide = -1;
+    in.readSide = AutoCloseFD(-1);
     writerThread = std::thread([&]() {
       try {
         std::vector<unsigned char> buf(8 * 1024);
@@ -1102,7 +1102,7 @@ void runProgram2(const RunOptions& options) {
       } catch (...) {
         promise.set_exception(std::current_exception());
       }
-      in.writeSide = -1;
+      in.writeSide = AutoCloseFD(-1);
     });
   }
 
diff --git a/third_party/nix/src/libutil/util.hh b/third_party/nix/src/libutil/util.hh
index b5383b6e71f8..b6d726b46c01 100644
--- a/third_party/nix/src/libutil/util.hh
+++ b/third_party/nix/src/libutil/util.hh
@@ -167,11 +167,11 @@ class AutoDelete {
 
  public:
   AutoDelete();
-  AutoDelete(Path p, bool recursive = true);
+  explicit AutoDelete(Path p, bool recursive = true);
   ~AutoDelete();
   void cancel();
   void reset(const Path& p, bool recursive = true);
-  operator Path() const { return path; }
+  explicit operator Path() const { return path; }
 };
 
 class AutoCloseFD {
@@ -180,7 +180,7 @@ class AutoCloseFD {
 
  public:
   AutoCloseFD();
-  AutoCloseFD(int fd);
+  explicit AutoCloseFD(int fd);
   AutoCloseFD(const AutoCloseFD& fd) = delete;
   AutoCloseFD(AutoCloseFD&& that);
   ~AutoCloseFD();
@@ -210,16 +210,24 @@ class Pid {
 
  public:
   Pid();
-  Pid(pid_t pid);
+  explicit Pid(pid_t pid);
   ~Pid();
   void operator=(pid_t pid);
-  operator pid_t();
+  explicit operator pid_t();
   int kill();
   int wait();
 
   void setSeparatePG(bool separatePG);
   void setKillSignal(int signal);
   pid_t release();
+
+  friend bool operator==(const Pid& lhs, const Pid& rhs) {
+    return lhs.pid == rhs.pid;
+  }
+
+  friend bool operator!=(const Pid& lhs, const Pid& rhs) {
+    return !(lhs == rhs);
+  }
 };
 
 /* Kill all processes running under the specified uid by sending them
@@ -275,7 +283,8 @@ class ExecError : public Error {
   int status;
 
   template <typename... Args>
-  ExecError(int status, Args... args) : Error(args...), status(status) {}
+  explicit ExecError(int status, Args... args)
+      : Error(args...), status(status) {}
 };
 
 /* Convert a list of strings to a null-terminated vector of char
@@ -378,7 +387,7 @@ class Callback {
   std::atomic_flag done = ATOMIC_FLAG_INIT;
 
  public:
-  Callback(std::function<void(std::future<T>)> fun) : fun(fun) {}
+  explicit Callback(std::function<void(std::future<T>)> fun) : fun(fun) {}
 
   Callback(Callback&& callback) : fun(std::move(callback.fun)) {
     auto prev = callback.done.test_and_set();
@@ -449,7 +458,8 @@ template <typename T>
 struct MaintainCount {
   T& counter;
   long delta;
-  MaintainCount(T& counter, long delta = 1) : counter(counter), delta(delta) {
+  explicit MaintainCount(T& counter, long delta = 1)
+      : counter(counter), delta(delta) {
     counter += delta;
   }
   ~MaintainCount() { counter -= delta; }
diff --git a/third_party/nix/src/nix-build/nix-build.cc b/third_party/nix/src/nix-build/nix-build.cc
index 6d1dd80944ed..67cd8252f07e 100644
--- a/third_party/nix/src/nix-build/nix-build.cc
+++ b/third_party/nix/src/nix-build/nix-build.cc
@@ -146,7 +146,7 @@ static void _main(int argc, char** argv) {
   MyArgs myArgs(
       myName, [&](Strings::iterator& arg, const Strings::iterator& end) {
         if (*arg == "--help") {
-          deletePath(tmpDir);
+          deletePath(Path(tmpDir));
           showManPage(myName);
         }
 
diff --git a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc b/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc
index 66e7cff810f5..c718ef5f4781 100644
--- a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc
+++ b/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc
@@ -185,8 +185,8 @@ static int _main(int argc, char** argv) {
 
       /* Download the file. */
       {
-        AutoCloseFD fd =
-            open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+        AutoCloseFD fd(
+            open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600));
         if (!fd) {
           throw SysError("creating temporary file '%s'", tmpFile);
         }
diff --git a/third_party/nix/src/nix/repl.cc b/third_party/nix/src/nix/repl.cc
index 2607655f9b6b..b926d195aec1 100644
--- a/third_party/nix/src/nix/repl.cc
+++ b/third_party/nix/src/nix/repl.cc
@@ -394,10 +394,10 @@ static int runProgram(const std::string& program, const Strings& args) {
 
   Pid pid;
   pid = fork();
-  if (pid == -1) {
+  if (pid == Pid(-1)) {
     throw SysError("forking");
   }
-  if (pid == 0) {
+  if (pid == Pid(0)) {
     restoreAffinity();
     execvp(program.c_str(), stringsToCharPtrs(args2).data());
     _exit(1);