From 8f1a26667e7c5aeac5522ae706cf511b2d725eaa Mon Sep 17 00:00:00 2001 From: siddhantCodes Date: Tue, 4 Jun 2024 19:35:40 +0530 Subject: [PATCH] add call to `checkInterrupt` in a bunch of places This brings back the old behaviour. We check for interrupts in places that may iterate over wide directories. --- src/libcmd/repl.cc | 1 + src/libstore/builtins/buildenv.cc | 2 ++ src/libstore/gc.cc | 5 ++++- src/libstore/globals.cc | 6 +++++- src/libstore/local-binary-cache-store.cc | 2 ++ src/libstore/local-store.cc | 2 ++ src/libstore/posix-fs-canonicalise.cc | 4 +++- src/libstore/profiles.cc | 2 ++ src/libutil/linux/cgroup.cc | 2 ++ src/libutil/posix-source-accessor.cc | 1 + src/libutil/unix/file-descriptor.cc | 1 + src/nix/flake.cc | 2 ++ src/nix/run.cc | 2 ++ 13 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index a069dd52c..603a543bc 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -260,6 +260,7 @@ StringSet NixRepl::completePrefix(const std::string & prefix) auto dir = std::string(cur, 0, slash); auto prefix2 = std::string(cur, slash + 1); for (auto & entry : std::filesystem::directory_iterator{dir == "" ? "/" : dir}) { + checkInterrupt(); auto name = entry.path().filename().string(); if (name[0] != '.' && hasPrefix(name, prefix2)) completions.insert(prev + entry.path().string()); diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index ab35c861d..0f7bcd99b 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -1,5 +1,6 @@ #include "buildenv.hh" #include "derivations.hh" +#include "signals.hh" #include #include @@ -30,6 +31,7 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, } for (const auto & ent : srcFiles) { + checkInterrupt(); auto name = ent.path().filename(); if (name.string()[0] == '.') /* not matched by glob */ diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 8286dff27..c6ecbd783 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -162,6 +162,7 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor) /* Read the `temproots' directory for per-process temporary root files. */ for (auto & i : std::filesystem::directory_iterator{tempRootsDir}) { + checkInterrupt(); auto name = i.path().filename().string(); if (name[0] == '.') { // Ignore hidden files. Some package managers (notably portage) create @@ -228,8 +229,10 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R type = std::filesystem::symlink_status(path).type(); if (type == std::filesystem::file_type::directory) { - for (auto & i : std::filesystem::directory_iterator{path}) + for (auto & i : std::filesystem::directory_iterator{path}) { + checkInterrupt(); findRoots(i.path().string(), i.symlink_status().type(), roots); + } } else if (type == std::filesystem::file_type::symlink) { diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index d9cab2fb8..88f899dbf 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -4,6 +4,7 @@ #include "args.hh" #include "abstract-setting-to-json.hh" #include "compute-levels.hh" +#include "signals.hh" #include #include @@ -346,14 +347,17 @@ void initPlugins() std::vector pluginFiles; try { auto ents = std::filesystem::directory_iterator{pluginFile}; - for (const auto & ent : ents) + for (const auto & ent : ents) { + checkInterrupt(); pluginFiles.emplace_back(ent.path()); + } } catch (std::filesystem::filesystem_error & e) { if (e.code() != std::errc::not_a_directory) throw; pluginFiles.emplace_back(pluginFile); } for (const auto & file : pluginFiles) { + checkInterrupt(); /* handle is purposefully leaked as there may be state in the DSO needed by the action of the plugin. */ #ifndef _WIN32 // TODO implement via DLL loading on Windows diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 87a6026f1..dde25937c 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -1,6 +1,7 @@ #include "binary-cache-store.hh" #include "globals.hh" #include "nar-info-disk-cache.hh" +#include "signals.hh" #include @@ -84,6 +85,7 @@ protected: StorePathSet paths; for (auto & entry : std::filesystem::directory_iterator{binaryCacheDir}) { + checkInterrupt(); auto name = entry.path().filename().string(); if (name.size() != 40 || !hasSuffix(name, ".narinfo")) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index dd06e5b65..cbe3c6fe8 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1407,6 +1407,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) printInfo("checking link hashes..."); for (auto & link : std::filesystem::directory_iterator{linksDir}) { + checkInterrupt(); auto name = link.path().filename(); printMsg(lvlTalkative, "checking contents of '%s'", name); PosixSourceAccessor accessor; @@ -1499,6 +1500,7 @@ LocalStore::VerificationResult LocalStore::verifyAllValidPaths(RepairFlag repair invalid states. */ for (auto & i : std::filesystem::directory_iterator{realStoreDir.to_string()}) { + checkInterrupt(); try { storePathsInStoreDir.insert({i.path().filename().string()}); } catch (BadStorePath &) { } diff --git a/src/libstore/posix-fs-canonicalise.cc b/src/libstore/posix-fs-canonicalise.cc index d8bae13f5..8cb13d810 100644 --- a/src/libstore/posix-fs-canonicalise.cc +++ b/src/libstore/posix-fs-canonicalise.cc @@ -144,13 +144,15 @@ static void canonicalisePathMetaData_( #endif if (S_ISDIR(st.st_mode)) { - for (auto & i : std::filesystem::directory_iterator{path}) + for (auto & i : std::filesystem::directory_iterator{path}) { + checkInterrupt(); canonicalisePathMetaData_( i.path().string(), #ifndef _WIN32 uidRange, #endif inodesSeen); + } } } diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index d0da96262..46efedfe3 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -1,4 +1,5 @@ #include "profiles.hh" +#include "signals.hh" #include "store-api.hh" #include "local-fs-store.hh" #include "users.hh" @@ -38,6 +39,7 @@ std::pair> findGenerations(Path pro auto profileName = std::string(baseNameOf(profile)); for (auto & i : std::filesystem::directory_iterator{profileDir}) { + checkInterrupt(); if (auto n = parseName(profileName, i.path().filename().string())) { auto path = i.path().string(); gens.push_back({ diff --git a/src/libutil/linux/cgroup.cc b/src/libutil/linux/cgroup.cc index ec4077478..140ff4566 100644 --- a/src/libutil/linux/cgroup.cc +++ b/src/libutil/linux/cgroup.cc @@ -1,4 +1,5 @@ #include "cgroup.hh" +#include "signals.hh" #include "util.hh" #include "file-system.hh" #include "finally.hh" @@ -65,6 +66,7 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu /* Otherwise, manually kill every process in the subcgroups and this cgroup. */ for (auto & entry : std::filesystem::directory_iterator{cgroup}) { + checkInterrupt(); if (entry.symlink_status().type() != std::filesystem::file_type::directory) continue; destroyCgroup(cgroup / entry.path().filename(), false); } diff --git a/src/libutil/posix-source-accessor.cc b/src/libutil/posix-source-accessor.cc index 225fc852c..bcf453cba 100644 --- a/src/libutil/posix-source-accessor.cc +++ b/src/libutil/posix-source-accessor.cc @@ -133,6 +133,7 @@ SourceAccessor::DirEntries PosixSourceAccessor::readDirectory(const CanonPath & assertNoSymlinks(path); DirEntries res; for (auto & entry : std::filesystem::directory_iterator{makeAbsPath(path)}) { + checkInterrupt(); auto type = [&]() -> std::optional { std::filesystem::file_type nativeType; try { diff --git a/src/libutil/unix/file-descriptor.cc b/src/libutil/unix/file-descriptor.cc index 84a33af81..a74f16ce1 100644 --- a/src/libutil/unix/file-descriptor.cc +++ b/src/libutil/unix/file-descriptor.cc @@ -125,6 +125,7 @@ void closeMostFDs(const std::set & exceptions) #if __linux__ try { for (auto & s : std::filesystem::directory_iterator{"/proc/self/fd"}) { + checkInterrupt(); auto fd = std::stoi(s.path().filename()); if (!exceptions.count(fd)) { debug("closing leaked FD %d", fd); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 78a8a55c3..feacdbcb3 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -7,6 +7,7 @@ #include "eval-settings.hh" #include "flake/flake.hh" #include "get-drvs.hh" +#include "signals.hh" #include "store-api.hh" #include "derivations.hh" #include "outputs-spec.hh" @@ -867,6 +868,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand createDirs(to); for (auto & entry : std::filesystem::directory_iterator{from}) { + checkInterrupt(); auto from2 = entry.path().string(); auto to2 = to + "/" + entry.path().filename().string(); auto st = lstat(from2); diff --git a/src/nix/run.cc b/src/nix/run.cc index cc999ddf4..1ecc83fba 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -3,6 +3,7 @@ #include "command-installable-value.hh" #include "common-args.hh" #include "shared.hh" +#include "signals.hh" #include "store-api.hh" #include "derivations.hh" #include "local-fs-store.hh" @@ -249,6 +250,7 @@ void chrootHelper(int argc, char * * argv) throw SysError("mounting '%s' on '%s'", realStoreDir, storeDir); for (auto entry : std::filesystem::directory_iterator{"/"}) { + checkInterrupt(); auto src = entry.path().string(); Path dst = tmpDir + "/" + entry.path().filename().string(); if (pathExists(dst)) continue;