diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 8fbb54dd30de..47d0127a322d 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -795,7 +795,7 @@ void NixRepl::loadFiles() loadedFiles.clear(); for (auto & i : old) { - notice("Loading '%1%'...", i); + notice("Loading %1%...", PathFmt(i)); loadFile(i); } diff --git a/src/libexpr/eval-profiler.cc b/src/libexpr/eval-profiler.cc index e9dc1e021eac..8a7490cda48e 100644 --- a/src/libexpr/eval-profiler.cc +++ b/src/libexpr/eval-profiler.cc @@ -139,7 +139,7 @@ class SampleStack : public EvalProfiler , profileFd([&]() { AutoCloseFD fd = toDescriptor(open(profileFile.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0660)); if (!fd) - throw SysError("opening file %s", profileFile); + throw SysError("opening file %s", PathFmt(profileFile)); return fd; }()) , posCache(state) diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 7e091ef1071e..0d2f6e921cc7 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -489,11 +489,11 @@ void InputScheme::clone( const Settings & settings, Store & store, const Input & input, const std::filesystem::path & destDir) const { if (std::filesystem::exists(destDir)) - throw Error("cannot clone into existing path %s", destDir); + throw Error("cannot clone into existing path %s", PathFmt(destDir)); auto [accessor, input2] = getAccessor(settings, store, input); - Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s' to %s...", input2.to_string(), destDir)); + Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s' to %s...", input2.to_string(), PathFmt(destDir))); RestoreSink sink(/*startFsync=*/false); sink.dstPath = destDir; diff --git a/src/libfetchers/git-lfs-fetch.cc b/src/libfetchers/git-lfs-fetch.cc index e2b2c2e7dda7..ec495c33556d 100644 --- a/src/libfetchers/git-lfs-fetch.cc +++ b/src/libfetchers/git-lfs-fetch.cc @@ -273,7 +273,7 @@ void Fetch::fetch( + "/" + pointer->oid; std::filesystem::path cachePath = cacheDir / key; if (pathExists(cachePath)) { - debug("using cache entry %s -> %s", key, cachePath); + debug("using cache entry %s -> %s", key, PathFmt(cachePath)); sink(readFile(cachePath)); return; } @@ -301,7 +301,7 @@ void Fetch::fetch( sizeCallback(size); downloadToSink(ourl, authHeader, sink, sha256, size); - debug("creating cache entry %s -> %s", key, cachePath); + debug("creating cache entry %s -> %s", key, PathFmt(cachePath)); if (!pathExists(cachePath.parent_path())) createDirs(cachePath.parent_path()); writeFile(cachePath, sink.s); diff --git a/src/libfetchers/git-utils.cc b/src/libfetchers/git-utils.cc index d0c9494e3e3e..160bc8f04ddb 100644 --- a/src/libfetchers/git-utils.cc +++ b/src/libfetchers/git-utils.cc @@ -209,14 +209,14 @@ static void initRepoAtomically(std::filesystem::path & path, GitRepo::Options op return; if (!options.create) - throw Error("Git repository %s does not exist.", path); + throw Error("Git repository %s does not exist.", PathFmt(path)); std::filesystem::path tmpDir = createTempDir(path.parent_path()); AutoDelete delTmpDir(tmpDir, true); Repository tmpRepo; if (git_repository_init(Setter(tmpRepo), tmpDir.string().c_str(), options.bare)) - throw Error("creating Git repository %s: %s", path, git_error_last()->message); + throw Error("creating Git repository %s: %s", PathFmt(path), git_error_last()->message); try { std::filesystem::rename(tmpDir, path); } catch (std::filesystem::filesystem_error & e) { @@ -226,7 +226,7 @@ static void initRepoAtomically(std::filesystem::path & path, GitRepo::Options op || e.code() == std::errc::directory_not_empty) { return; } else - throw SysError("moving temporary git repository from %s to %s", tmpDir, path); + throw SysError("moving temporary git repository from %s to %s", PathFmt(tmpDir), PathFmt(path)); } // we successfully moved the repository, so the temporary directory no longer exists. delTmpDir.cancel(); @@ -266,7 +266,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this initRepoAtomically(path, options); if (git_repository_open(Setter(repo), path.string().c_str())) - throw Error("opening Git repository %s: %s", path, git_error_last()->message); + throw Error("opening Git repository %s: %s", PathFmt(path), git_error_last()->message); ObjectDb odb; if (options.packfilesOnly) { diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 3bdb38b91ebb..ed6a0d71e1f6 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -72,10 +72,10 @@ std::optional readHead(const std::filesystem::path & path) if (const auto parseResult = git::parseLsRemoteLine(line); parseResult && parseResult->reference == "HEAD") { switch (parseResult->kind) { case git::LsRemoteRefLine::Kind::Symbolic: - debug("resolved HEAD ref '%s' for repo '%s'", parseResult->target, path); + debug("resolved HEAD ref '%s' for repo %s", parseResult->target, PathFmt(path)); break; case git::LsRemoteRefLine::Kind::Object: - debug("resolved HEAD rev '%s' for repo '%s'", parseResult->target, path); + debug("resolved HEAD rev '%s' for repo %s", parseResult->target, PathFmt(path)); break; } return parseResult->target; @@ -753,9 +753,10 @@ struct GitInputScheme : InputScheme "\n" "git -C %2% add \"%1%\"", path.rel(), - repoPath); + PathFmt(repoPath)); else - return RestrictedPathError("Path '%s' does not exist in Git repository %s.", path.rel(), repoPath); + return RestrictedPathError( + "Path '%s' does not exist in Git repository %s.", path.rel(), PathFmt(repoPath)); }; } @@ -848,7 +849,7 @@ struct GitInputScheme : InputScheme if (!input.getRev()) setWriteTime(localRefFile, now, now); } catch (Error & e) { - warn("could not update mtime for file %s: %s", localRefFile, e.info().msg); + warn("could not update mtime for file %s: %s", PathFmt(localRefFile), e.info().msg); } if (!originalRef && !storeCachedHead(repoUrl.to_string(), shallow, ref)) warn("could not update cached head '%s' for '%s'", ref, repoInfo.locationToArg()); diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index de2652ef72e8..efce0390450a 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -154,7 +154,7 @@ struct PathInputScheme : InputScheme time_t mtime = 0; if (!storePath || storePath->name() != "source" || !store.isValidPath(*storePath)) { - Activity act(*logger, lvlTalkative, actUnknown, fmt("copying %s to the store", absPath)); + Activity act(*logger, lvlTalkative, actUnknown, fmt("copying %s to the store", PathFmt(absPath))); // FIXME: try to substitute storePath. auto src = sinkToSource( [&](Sink & sink) { mtime = dumpPathAndGetMtime(absPath.string(), sink, defaultPathFilter); }); diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc index 94e232fa70c6..34091823f8a1 100644 --- a/src/libfetchers/tarball.cc +++ b/src/libfetchers/tarball.cc @@ -121,14 +121,15 @@ static DownloadTarballResult downloadTarball_( url); } if (!exists(localPath)) { - throw Error("tarball '%s' does not exist.", localPath); + throw Error("tarball %s does not exist.", PathFmt(localPath)); } if (is_directory(localPath)) { if (exists(localPath / ".git")) { throw Error( - "tarball '%s' is a git repository, not a tarball. Please use `git+file` as the scheme.", localPath); + "tarball %s is a git repository, not a tarball. Please use `git+file` as the scheme.", + PathFmt(localPath)); } - throw Error("tarball '%s' is a directory, not a file.", localPath); + throw Error("tarball %s is a directory, not a file.", PathFmt(localPath)); } } diff --git a/src/libflake/flake.cc b/src/libflake/flake.cc index 7fd5e0c065e6..be3b667d2da3 100644 --- a/src/libflake/flake.cc +++ b/src/libflake/flake.cc @@ -850,11 +850,11 @@ lockFlake(const Settings & settings, EvalState & state, const FlakeRef & topRef, auto s = chomp(diff); if (lockFileExists) { if (s.empty()) - warn("updating lock file %s", outputLockFilePath); + warn("updating lock file %s", PathFmt(outputLockFilePath)); else - warn("updating lock file %s:\n%s", outputLockFilePath, s); + warn("updating lock file %s:\n%s", PathFmt(outputLockFilePath), s); } else - warn("creating lock file %s: \n%s", outputLockFilePath, s); + warn("creating lock file %s: \n%s", PathFmt(outputLockFilePath), s); std::optional commitMessage = std::nullopt; diff --git a/src/libmain/plugin.cc b/src/libmain/plugin.cc index 713d7bc426a1..ff8c8201184e 100644 --- a/src/libmain/plugin.cc +++ b/src/libmain/plugin.cc @@ -95,7 +95,7 @@ void initPlugins() #ifndef _WIN32 // TODO implement via DLL loading on Windows void * handle = dlopen(file.c_str(), RTLD_LAZY | RTLD_LOCAL); if (!handle) - throw Error("could not dynamically open plugin file '%s': %s", file, dlerror()); + throw Error("could not dynamically open plugin file %s: %s", PathFmt(file), dlerror()); /* Older plugins use a statically initialized object to run their code. Newer plugins can also export nix_plugin_entry() */ @@ -103,7 +103,7 @@ void initPlugins() if (nix_plugin_entry) nix_plugin_entry(); #else - throw Error("could not dynamically open plugin file '%s'", file); + throw Error("could not dynamically open plugin file %s", PathFmt(file)); #endif } } diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index ad1caae2b644..913dfa54d523 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -304,7 +304,7 @@ void printVersion(const std::string & programName) std::cout << "System type: " << settings.thisSystem << "\n"; std::cout << "Additional system types: " << concatStringsSep(", ", settings.extraPlatforms.get()) << "\n"; std::cout << "Features: " << concatStringsSep(", ", cfg) << "\n"; - std::cout << "System configuration file: " << (settings.nixConfDir / "nix.conf") << "\n"; + std::cout << "System configuration file: " << (settings.nixConfDir / "nix.conf").string() << "\n"; std::cout << "User configuration files: " << concatStringsSep(":", settings.nixUserConfFiles) << "\n"; std::cout << "Store directory: " << settings.nixStore << "\n"; std::cout << "State directory: " << settings.nixStateDir << "\n"; diff --git a/src/libstore/build/derivation-building-goal.cc b/src/libstore/build/derivation-building-goal.cc index 7af793809b9a..fa5ae823baf3 100644 --- a/src/libstore/build/derivation-building-goal.cc +++ b/src/libstore/build/derivation-building-goal.cc @@ -721,7 +721,7 @@ Goal::Co DerivationBuildingGoal::buildLocally( worker.store.toStorePath(i.second.source.string()).first, closure); } catch (InvalidPath & e) { } catch (Error & e) { - e.addTrace({}, "while processing sandbox path '%s'", i.second.source); + e.addTrace({}, "while processing sandbox path %s", PathFmt(i.second.source)); throw; } for (auto & i : closure) { diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 8033d1202da8..b587f6904382 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -187,9 +187,9 @@ LocalStore::LocalStore(ref config) while (path != root) { if (std::filesystem::is_symlink(path)) throw Error( - "the path '%1%' is a symlink; " + "the path %1% is a symlink; " "this is not allowed for the Nix store and its parent directories", - path); + PathFmt(path)); path = path.parent_path(); } } @@ -1301,15 +1301,16 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) for (auto & link : DirectoryIterator{linksDir}) { checkInterrupt(); auto name = link.path().filename(); - printMsg(lvlTalkative, "checking contents of %s", name); + printMsg(lvlTalkative, "checking contents of %s", PathFmt(name)); std::string hash = hashPath(makeFSSourceAccessor(link.path()), FileIngestionMethod::NixArchive, HashAlgorithm::SHA256) .first.to_string(HashFormat::Nix32, false); if (hash != name.string()) { - printError("link %s was modified! expected hash %s, got '%s'", link.path(), name, hash); + printError( + "link %s was modified! expected hash %s, got '%s'", PathFmt(link.path()), name.string(), hash); if (repair) { std::filesystem::remove(link.path()); - printInfo("removed link %s", link.path()); + printInfo("removed link %s", PathFmt(link.path())); } else { errors = true; } diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index d1e858300277..58111b61a69b 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -178,7 +178,7 @@ void LocalStore::optimisePath_( .hash; }))) { // XXX: Consider overwriting linkPath with our valid version. - warn("removing corrupted link %s", linkPath); + warn("removing corrupted link %s", PathFmt(linkPath)); warn( "There may be more corrupted paths." "\nYou should run `nix-store --verify --check-contents --repair` to fix them all"); @@ -201,8 +201,10 @@ void LocalStore::optimisePath_( /* On ext4, that probably means the directory index is full. When that happens, it's fine to ignore it: we just effectively disable deduplication of this - file. */ - printInfo("cannot link %s to '%s': %s", linkPath, path, strerror(errno)); + file. + TODO: Get rid of errno, use error code. + */ + printInfo("cannot link %s to '%s': %s", PathFmt(linkPath), path, strerror(errno)); return; } @@ -216,11 +218,11 @@ void LocalStore::optimisePath_( auto stLink = lstat(linkPath.string()); if (st.st_ino == stLink.st_ino) { - debug("'%1%' is already linked to %2%", path, linkPath); + debug("%1% is already linked to %2%", PathFmt(path), PathFmt(linkPath)); return; } - printMsg(lvlTalkative, "linking '%1%' to %2%", path, linkPath); + printMsg(lvlTalkative, "linking %1% to %2%", PathFmt(path), PathFmt(linkPath)); /* Make the containing directory writable, but only if it's not the store itself (we don't want or need to mess with its @@ -245,7 +247,7 @@ void LocalStore::optimisePath_( systems). This is likely to happen with empty files. Just shrug and ignore. */ if (st.st_size) - printInfo("%1% has maximum number of links", linkPath); + printInfo("%1% has maximum number of links", PathFmt(linkPath)); return; } throw; @@ -259,14 +261,14 @@ void LocalStore::optimisePath_( std::error_code ec; remove(tempLink, ec); /* Clean up after ourselves. */ if (ec) - printError("unable to unlink %1%: %2%", tempLink, ec.message()); + printError("unable to unlink %1%: %2%", PathFmt(tempLink), ec.message()); } if (e.code() == std::errc::too_many_links) { /* Some filesystems generate too many links on the rename, rather than on the original link. (Probably it temporarily increases the st_nlink field before decreasing it again.) */ - debug("%s has reached maximum number of links", linkPath); + debug("%s has reached maximum number of links", PathFmt(linkPath)); return; } throw; diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 22d3f8f8973c..983ba4e41563 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -103,7 +103,7 @@ static void removeFile(const std::filesystem::path & path) try { std::filesystem::remove(path); } catch (std::filesystem::filesystem_error & e) { - throw SysError("removing file '%1%'", path); + throw SysError("removing file %1%", PathFmt(path)); } } @@ -141,7 +141,7 @@ void deleteGenerations( auto [gens, curGen] = findGenerations(profile); if (gensToDelete.count(*curGen)) - throw Error("cannot delete current version of profile %1%'", profile); + throw Error("cannot delete current version of profile %1%", PathFmt(profile)); for (auto & i : gens) { if (!gensToDelete.count(i.number)) @@ -282,7 +282,7 @@ void switchGeneration(const std::filesystem::path & profile, std::optional(chrootParentDir); - printMsg(lvlChatty, "setting up chroot environment in %1%", chrootParentDir); + printMsg(lvlChatty, "setting up chroot environment in %1%", PathFmt(chrootParentDir)); if (mkdir(chrootParentDir.c_str(), 0700) == -1) - throw SysError("cannot create %s", chrootRootDir); + throw SysError("cannot create %s", PathFmt(chrootRootDir)); chrootRootDir = chrootParentDir / "root"; if (mkdir(chrootRootDir.c_str(), buildUser && buildUser->getUIDCount() != 1 ? 0755 : 0750) == -1) - throw SysError("cannot create %1%", chrootRootDir); + throw SysError("cannot create %1%", PathFmt(chrootRootDir)); if (buildUser && chown( chrootRootDir.c_str(), buildUser->getUIDCount() != 1 ? buildUser->getUID() : 0, buildUser->getGID()) == -1) - throw SysError("cannot change ownership of %1%", chrootRootDir); + throw SysError("cannot change ownership of %1%", PathFmt(chrootRootDir)); /* Create a writable /tmp in the chroot. Many builders need this. (Of course they should really respect $TMPDIR @@ -122,7 +122,7 @@ struct ChrootDerivationBuilder : virtual DerivationBuilderImpl chmod_(chrootStoreDir, 01775); if (buildUser && chown(chrootStoreDir.c_str(), 0, buildUser->getGID()) == -1) - throw SysError("cannot change ownership of %1%", chrootStoreDir); + throw SysError("cannot change ownership of %1%", PathFmt(chrootStoreDir)); pathsInChroot = getPathsInSandbox(); @@ -193,7 +193,7 @@ struct ChrootDerivationBuilder : virtual DerivationBuilderImpl if (pathExists(target)) { // There is a similar debug message in doBind, so only run it in this block to not have double messages. - debug("bind-mounting %s -> %s", target, source); + debug("bind-mounting %s -> %s", PathFmt(target), PathFmt(source)); throw Error("store path '%s' already exists in the sandbox", store.printStorePath(path)); } diff --git a/src/libstore/unix/build/darwin-derivation-builder.cc b/src/libstore/unix/build/darwin-derivation-builder.cc index eba96225abe4..36de96e9414f 100644 --- a/src/libstore/unix/build/darwin-derivation-builder.cc +++ b/src/libstore/unix/build/darwin-derivation-builder.cc @@ -137,9 +137,9 @@ struct DarwinDerivationBuilder : DerivationBuilderImpl if (i.first != i.second.source) throw Error( - "can't map '%1%' to '%2%': mismatched impure paths not supported on Darwin", - i.first, - i.second.source); + "can't map %1% to %2%: mismatched impure paths not supported on Darwin", + PathFmt(i.first), + PathFmt(i.second.source)); std::string path = i.first; auto optSt = maybeLstat(path.c_str()); diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index aeaabf959025..8e5dc0a721da 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -570,7 +570,7 @@ SingleDrvOutputs DerivationBuilderImpl::unprepareBuild() static void chmod_(const std::filesystem::path & path, mode_t mode) { if (chmod(path.c_str(), mode) == -1) - throw SysError("setting permissions on %s", path); + throw SysError("setting permissions on %s", PathFmt(path)); } /* Move/rename path 'src' to 'dst'. Temporarily make 'src' writable if @@ -690,7 +690,7 @@ static void checkNotWorldWritable(std::filesystem::path path) while (true) { auto st = lstat(path); if (st.st_mode & S_IWOTH) - throw Error("Path %s is world-writable or a symlink. That's not allowed for security.", path); + throw Error("Path %s is world-writable or a symlink. That's not allowed for security.", PathFmt(path)); if (path == path.parent_path()) break; path = path.parent_path(); @@ -730,7 +730,7 @@ std::optional DerivationBuilderImpl::startBuild() POSIX semantics.*/ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)}; if (!tmpDirFd) - throw SysError("failed to open the build temporary directory descriptor %1%", tmpDir); + throw SysError("failed to open the build temporary directory descriptor %1%", PathFmt(tmpDir)); chownToBuilder(tmpDirFd.get(), tmpDir); @@ -796,7 +796,8 @@ std::optional DerivationBuilderImpl::startBuild() if (needsHashRewrite() && pathExists(homeDir)) throw Error( - "home directory %1% exists; please remove it to assure purity of builds without sandboxing", homeDir); + "home directory %1% exists; please remove it to assure purity of builds without sandboxing", + PathFmt(homeDir)); /* Fire up a Nix daemon to process recursive Nix calls from the builder. */ @@ -1219,7 +1220,7 @@ void DerivationBuilderImpl::chownToBuilder(const std::filesystem::path & path) if (!buildUser) return; if (chown(path.c_str(), buildUser->getUID(), buildUser->getGID()) == -1) - throw SysError("cannot change ownership of %1%", path); + throw SysError("cannot change ownership of %1%", PathFmt(path)); } void DerivationBuilderImpl::chownToBuilder(int fd, const std::filesystem::path & path) @@ -1227,7 +1228,7 @@ void DerivationBuilderImpl::chownToBuilder(int fd, const std::filesystem::path & if (!buildUser) return; if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1) - throw SysError("cannot change ownership of file %1%", path); + throw SysError("cannot change ownership of file %1%", PathFmt(path)); } void DerivationBuilderImpl::writeBuilderFile(const std::string & name, std::string_view contents) @@ -1236,7 +1237,7 @@ void DerivationBuilderImpl::writeBuilderFile(const std::string & name, std::stri AutoCloseFD fd{ openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)}; if (!fd) - throw SysError("creating file %s", path); + throw SysError("creating file %s", PathFmt(path)); writeFile(fd, path, contents); chownToBuilder(fd.get(), path); } @@ -1278,7 +1279,7 @@ void DerivationBuilderImpl::runChild(RunChildArgs args) enterChroot(); if (chdir(tmpDirInSandbox().c_str()) == -1) - throw SysError("changing into %1%", tmpDir); + throw SysError("changing into %1%", PathFmt(tmpDir)); /* Close all other file descriptors. */ unix::closeExtraFDs(); @@ -1440,10 +1441,10 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() if (!optSt) throw BuildError( BuildResult::Failure::OutputRejected, - "builder for '%s' failed to produce output path for output '%s' at '%s'", + "builder for '%s' failed to produce output path for output '%s' at %s", store.printStorePath(drvPath), outputName, - actualPath); + PathFmt(actualPath)); struct stat & st = *optSt; #ifndef __CYGWIN__ @@ -1455,8 +1456,8 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() || (buildUser && st.st_uid != buildUser->getUID())) throw BuildError( BuildResult::Failure::OutputRejected, - "suspicious ownership or permission on '%s' for output '%s'; rejecting this build output", - actualPath, + "suspicious ownership or permission on %s for output '%s'; rejecting this build output", + PathFmt(actualPath), outputName); #endif @@ -1475,7 +1476,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() if (discardReferences) debug("discarding references of output '%s'", outputName); else { - debug("scanning for references for output '%s' in temp location %s", outputName, actualPath); + debug("scanning for references for output '%s' in temp location %s", outputName, PathFmt(actualPath)); /* Pass blank Sink as we are not ready to hash data at this stage. */ NullSink blank; @@ -1571,7 +1572,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() auto rewriteOutput = [&](const StringMap & rewrites) { /* Apply hash rewriting if necessary. */ if (!rewrites.empty()) { - debug("rewriting hashes in %1%; cross fingers", actualPath); + debug("rewriting hashes in %1%; cross fingers", PathFmt(actualPath)); /* FIXME: Is this actually streaming? */ auto source = sinkToSource([&](Sink & nextSink) { @@ -1619,15 +1620,17 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() auto st = get(outputStats, outputName); if (!st) throw BuildError( - BuildResult::Failure::OutputRejected, "output path %1% without valid stats info", actualPath); + BuildResult::Failure::OutputRejected, + "output path %1% without valid stats info", + PathFmt(actualPath)); if (outputHash.method.getFileIngestionMethod() == FileIngestionMethod::Flat) { /* The output path should be a regular file without execute permission. */ if (!S_ISREG(st->st_mode) || (st->st_mode & S_IXUSR) != 0) throw BuildError( BuildResult::Failure::OutputRejected, - "output path '%1%' should be a non-executable regular file " + "output path %1% should be a non-executable regular file " "since recursive hashing is not enabled (one of outputHashMode={flat,text} is true)", - actualPath); + PathFmt(actualPath)); } rewriteOutput(outputRewrites); /* FIXME optimize and deduplicate with addToStore */ @@ -1925,7 +1928,7 @@ void DerivationBuilderImpl::cleanupBuild(bool force) /* Don't keep temporary directories for builtins because they might have privileged stuff (like a copy of netrc). */ if (settings.keepFailed && !force && !drv.isBuiltin()) { - printError("note: keeping build directory %s", tmpDir); + printError("note: keeping build directory %s", PathFmt(tmpDir)); chmod(topTmpDir.c_str(), 0755); chmod(tmpDir.c_str(), 0755); } else diff --git a/src/libstore/unix/build/external-derivation-builder.cc b/src/libstore/unix/build/external-derivation-builder.cc index 35421c9977db..9e11c1c0a922 100644 --- a/src/libstore/unix/build/external-derivation-builder.cc +++ b/src/libstore/unix/build/external-derivation-builder.cc @@ -88,7 +88,7 @@ struct ExternalDerivationBuilder : DerivationBuilderImpl args.insert(args.end(), jsonFile); if (chdir(tmpDir.c_str()) == -1) - throw SysError("changing into %1%", tmpDir); + throw SysError("changing into %1%", PathFmt(tmpDir)); chownToBuilder(topTmpDir); @@ -97,7 +97,7 @@ struct ExternalDerivationBuilder : DerivationBuilderImpl debug("executing external builder: %s", concatStringsSep(" ", args)); execv(externalBuilder.program.c_str(), stringsToCharPtrs(args).data()); - throw SysError("executing %s", externalBuilder.program); + throw SysError("executing %s", PathFmt(externalBuilder.program)); } catch (...) { handleChildException(true); _exit(1); diff --git a/src/libstore/unix/build/hook-instance.cc b/src/libstore/unix/build/hook-instance.cc index 9dc9fae29a89..af9249487070 100644 --- a/src/libstore/unix/build/hook-instance.cc +++ b/src/libstore/unix/build/hook-instance.cc @@ -69,7 +69,7 @@ HookInstance::HookInstance() execv(buildHook.native().c_str(), stringsToCharPtrs(args).data()); - throw SysError("executing '%s'", buildHook); + throw SysError("executing %s", PathFmt(buildHook)); }); pid.setSeparatePG(true); diff --git a/src/libstore/unix/build/linux-derivation-builder.cc b/src/libstore/unix/build/linux-derivation-builder.cc index 795cac24dc81..a6000d4fb1ab 100644 --- a/src/libstore/unix/build/linux-derivation-builder.cc +++ b/src/libstore/unix/build/linux-derivation-builder.cc @@ -125,11 +125,11 @@ static void setupSeccomp() static void doBind(const std::filesystem::path & source, const std::filesystem::path & target, bool optional = false) { - debug("bind mounting %1% to %2%", source, target); + debug("bind mounting %1% to %2%", PathFmt(source), PathFmt(target)); auto bindMount = [&]() { if (mount(source.c_str(), target.c_str(), "", MS_BIND | MS_REC, 0) == -1) - throw SysError("bind mount from %1% to %2% failed", source, target); + throw SysError("bind mount from %1% to %2% failed", PathFmt(source), PathFmt(target)); }; auto maybeSt = maybeLstat(source); @@ -137,7 +137,7 @@ static void doBind(const std::filesystem::path & source, const std::filesystem:: if (optional) return; else - throw SysError("getting attributes of path %1%", source); + throw SysError("getting attributes of path %1%", PathFmt(source)); } auto st = *maybeSt; @@ -231,7 +231,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu throw Error("cannot determine the cgroups file system"); auto rootCgroupPath = *cgroupFS / getRootCgroup().rel(); if (!pathExists(rootCgroupPath)) - throw Error("expected cgroup directory '%s'", rootCgroupPath); + throw Error("expected cgroup directory %s", PathFmt(rootCgroupPath)); static std::atomic counter{0}; @@ -239,7 +239,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu / (buildUser ? fmt("nix-build-uid-%d", buildUser->getUID()) : fmt("nix-build-pid-%d-%d", getpid(), counter++)); - debug("using cgroup %s", *cgroup); + debug("using cgroup %s", PathFmt(*cgroup)); /* When using a build user, record the cgroup we used for that user so that if we got interrupted previously, we can kill @@ -269,7 +269,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu if (cgroup) { if (mkdir(cgroup->c_str(), 0755) != 0) - throw SysError("creating cgroup %s", *cgroup); + throw SysError("creating cgroup %s", PathFmt(*cgroup)); chownToBuilder(*cgroup); chownToBuilder(*cgroup / "cgroup.procs"); chownToBuilder(*cgroup / "cgroup.threads"); @@ -493,7 +493,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu /* Bind-mount chroot directory to itself, to treat it as a different filesystem from /, as needed for pivot_root. */ if (mount(chrootRootDir.c_str(), chrootRootDir.c_str(), 0, MS_BIND, 0) == -1) - throw SysError("unable to bind mount %1%", chrootRootDir); + throw SysError("unable to bind mount %1%", PathFmt(chrootRootDir)); /* Bind-mount the sandbox's Nix store onto itself so that we can mark it as a "shared" subtree, allowing bind @@ -506,10 +506,10 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu std::filesystem::path chrootStoreDir = chrootRootDir / std::filesystem::path(store.storeDir).relative_path(); if (mount(chrootStoreDir.c_str(), chrootStoreDir.c_str(), 0, MS_BIND, 0) == -1) - throw SysError("unable to bind mount the Nix store", chrootStoreDir); + throw SysError("unable to bind mount the Nix store at %1%", PathFmt(chrootStoreDir)); if (mount(0, chrootStoreDir.c_str(), 0, MS_SHARED, 0) == -1) - throw SysError("unable to make %s shared", chrootStoreDir); + throw SysError("unable to make %s shared", PathFmt(chrootStoreDir)); /* Set up a nearly empty /dev, unless the user asked to bind-mount the host /dev. */ @@ -663,16 +663,16 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu /* Do the chroot(). */ if (chdir(chrootRootDir.c_str()) == -1) - throw SysError("cannot change directory to %1%", chrootRootDir); + throw SysError("cannot change directory to %1%", PathFmt(chrootRootDir)); if (mkdir("real-root", 0500) == -1) throw SysError("cannot create real-root directory"); if (pivot_root(".", "real-root") == -1) - throw SysError("cannot pivot old root directory onto %1%", chrootRootDir / "real-root"); + throw SysError("cannot pivot old root directory onto %1%", PathFmt(chrootRootDir / "real-root")); if (chroot(".") == -1) - throw SysError("cannot change root directory to %1%", chrootRootDir); + throw SysError("cannot change root directory to %1%", PathFmt(chrootRootDir)); if (umount2("real-root", MNT_DETACH) == -1) throw SysError("cannot unmount real root filesystem"); diff --git a/src/libstore/unix/pathlocks.cc b/src/libstore/unix/pathlocks.cc index 6117b82c8922..6a58864ce224 100644 --- a/src/libstore/unix/pathlocks.cc +++ b/src/libstore/unix/pathlocks.cc @@ -19,7 +19,7 @@ AutoCloseFD openLockFile(const std::filesystem::path & path, bool create) fd = open(path.c_str(), O_CLOEXEC | O_RDWR | (create ? O_CREAT : 0), 0600); if (!fd && (create || errno != ENOENT)) - throw SysError("opening lock file %1%", path); + throw SysError("opening lock file %1%", PathFmt(path)); return fd; } @@ -83,7 +83,7 @@ bool PathLocks::lockPaths(const std::set & paths, const s checkInterrupt(); std::filesystem::path lockPath = path + ".lock"; - debug("locking path %1%", path); + debug("locking path %1%", PathFmt(path)); AutoCloseFD fd; @@ -106,19 +106,19 @@ bool PathLocks::lockPaths(const std::set & paths, const s } } - debug("lock acquired on %1%", lockPath); + debug("lock acquired on %1%", PathFmt(lockPath)); /* Check that the lock file hasn't become stale (i.e., hasn't been unlinked). */ struct stat st; if (fstat(fd.get(), &st) == -1) - throw SysError("statting lock file %1%", lockPath); + throw SysError("statting lock file %1%", PathFmt(lockPath)); if (st.st_size != 0) /* This lock file has been unlinked, so we're holding a lock on a deleted file. This means that other processes may create and acquire a lock on `lockPath', and proceed. So we must retry. */ - debug("open lock file %1% has become stale", lockPath); + debug("open lock file %1% has become stale", PathFmt(lockPath)); else break; } @@ -137,9 +137,9 @@ void PathLocks::unlock() deleteLockFile(i.second, i.first); if (close(i.first) == -1) - printError("error (ignored): cannot close lock file on %1%", i.second); + printError("error (ignored): cannot close lock file on %1%", PathFmt(i.second)); - debug("lock released on %1%", i.second); + debug("lock released on %1%", PathFmt(i.second)); } fds.clear(); diff --git a/src/libstore/windows/pathlocks.cc b/src/libstore/windows/pathlocks.cc index e37b1e15b562..9f51e49897ef 100644 --- a/src/libstore/windows/pathlocks.cc +++ b/src/libstore/windows/pathlocks.cc @@ -17,7 +17,7 @@ void deleteLockFile(const std::filesystem::path & path, Descriptor desc) int exit = DeleteFileW(path.c_str()); if (exit == 0) - warn("%s: &s", path, std::to_string(GetLastError())); + warn("%s: %s", PathFmt(path), std::to_string(GetLastError())); } void PathLocks::unlock() @@ -27,9 +27,9 @@ void PathLocks::unlock() deleteLockFile(i.second, i.first); if (CloseHandle(i.first) == -1) - printError("error (ignored): cannot close lock file on %1%", i.second); + printError("error (ignored): cannot close lock file on %1%", PathFmt(i.second)); - debug("lock released on %1%", i.second); + debug("lock released on %1%", PathFmt(i.second)); } fds.clear(); @@ -46,7 +46,7 @@ AutoCloseFD openLockFile(const std::filesystem::path & path, bool create) FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS, NULL); if (desc.get() == INVALID_HANDLE_VALUE) - warn("%s: %s", path, std::to_string(GetLastError())); + warn("%s: %s", PathFmt(path), std::to_string(GetLastError())); return desc; } @@ -110,7 +110,7 @@ bool PathLocks::lockPaths(const std::set & paths, const s checkInterrupt(); std::filesystem::path lockPath = path; lockPath += L".lock"; - debug("locking path %1%", path); + debug("locking path %1%", PathFmt(path)); AutoCloseFD fd; @@ -127,13 +127,13 @@ bool PathLocks::lockPaths(const std::set & paths, const s } } - debug("lock acquired on %1%", lockPath); + debug("lock acquired on %1%", PathFmt(lockPath)); struct _stat st; if (_fstat(fromDescriptorReadOnly(fd.get()), &st) == -1) - throw SysError("statting lock file %1%", lockPath); + throw SysError("statting lock file %1%", PathFmt(lockPath)); if (st.st_size != 0) - debug("open lock file %1% has become stale", lockPath); + debug("open lock file %1% has become stale", PathFmt(lockPath)); else break; } diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index df7b2fbab784..0049d45343d4 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -42,7 +42,7 @@ DirectoryIterator::DirectoryIterator(const std::filesystem::path & p) } catch (const std::filesystem::filesystem_error & e) { // **Catch filesystem_error and throw SysError** // Adapt the error message as needed for SysError - throw SysError("cannot read directory %s", p); + throw SysError("cannot read directory %s", PathFmt(p)); } } @@ -55,7 +55,7 @@ DirectoryIterator & DirectoryIterator::operator++() // Try to get path info if possible, might fail if iterator is bad try { if (it_ != std::filesystem::directory_iterator{}) { - throw SysError("cannot read directory past %s: %s", it_->path(), ec.message()); + throw SysError("cannot read directory past %s: %s", PathFmt(it_->path()), ec.message()); } } catch (...) { throw SysError("cannot read directory"); @@ -264,7 +264,7 @@ std::string readFile(const std::filesystem::path & path) { AutoCloseFD fd = openFileReadonly(path); if (!fd) - throw NativeSysError("opening file %1%", path); + throw NativeSysError("opening file %1%", PathFmt(path)); return readFile(fd.get()); } @@ -396,7 +396,7 @@ void recursiveSync(const Path & path) } else if (std::filesystem::is_regular_file(st)) { AutoCloseFD fd = toDescriptor(open(entry.path().string().c_str(), O_RDONLY, 0)); if (!fd) - throw SysError("opening file '%1%'", entry.path()); + throw SysError("opening file %1%", PathFmt(entry.path())); fd.fsync(); } } @@ -407,7 +407,7 @@ void recursiveSync(const Path & path) for (auto dir = dirsToFsync.rbegin(); dir != dirsToFsync.rend(); ++dir) { AutoCloseFD fd = toDescriptor(open(dir->string().c_str(), O_RDONLY, 0)); if (!fd) - throw SysError("opening directory '%1%'", *dir); + throw SysError("opening directory %1%", PathFmt(*dir)); fd.fsync(); } } @@ -533,12 +533,12 @@ std::filesystem::path createTempDir(const std::filesystem::path & tmpRoot, const "wheel", then "tar" will fail to unpack archives that have the setgid bit set on directories. */ if (chown(tmpDir.c_str(), (uid_t) -1, getegid()) != 0) - throw SysError("setting group of directory '%1%'", tmpDir); + throw SysError("setting group of directory %1%", PathFmt(tmpDir)); #endif return tmpDir; } if (errno != EEXIST) - throw SysError("creating directory '%1%'", tmpDir); + throw SysError("creating directory %1%", PathFmt(tmpDir)); } } @@ -557,7 +557,7 @@ AutoCloseFD createAnonymousTempFile() FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, /*hTemplateFile=*/nullptr); if (!fd) - throw windows::WinError("creating temporary file %1%", path); + throw windows::WinError("creating temporary file %1%", PathFmt(path)); #else # ifdef O_TMPFILE static std::atomic_flag tmpfileUnsupported{}; @@ -626,7 +626,7 @@ void replaceSymlink(const std::filesystem::path & target, const std::filesystem: } catch (std::filesystem::filesystem_error & e) { if (e.code() == std::errc::file_exists) continue; - throw SysError("creating symlink %1% -> %2%", tmp, target); + throw SysError("creating symlink %1% -> %2%", PathFmt(tmp), PathFmt(target)); } try { @@ -634,7 +634,7 @@ void replaceSymlink(const std::filesystem::path & target, const std::filesystem: } catch (std::filesystem::filesystem_error & e) { if (e.code() == std::errc::file_exists) continue; - throw SysError("renaming %1% to %2%", tmp, link); + throw SysError("renaming %1% to %2%", PathFmt(tmp), PathFmt(link)); } break; @@ -667,7 +667,7 @@ void copyFile(const std::filesystem::path & from, const std::filesystem::path & copyFile(entry, to / entry.path().filename(), andDelete); } } else { - throw Error("file %s has an unsupported type", from); + throw Error("file %s has an unsupported type", PathFmt(from)); } setWriteTime(to, lstat(from.string().c_str())); @@ -735,7 +735,7 @@ std::filesystem::path makeParentCanonical(const std::filesystem::path & rawPath) } return std::filesystem::canonical(parent) / path.filename(); } catch (std::filesystem::filesystem_error & e) { - throw SysError("canonicalising parent path of '%1%'", path); + throw SysError("canonicalising parent path of %1%", PathFmt(path)); } } diff --git a/src/libutil/fs-sink.cc b/src/libutil/fs-sink.cc index c0ad1aae54d5..f0924cff703b 100644 --- a/src/libutil/fs-sink.cc +++ b/src/libutil/fs-sink.cc @@ -87,7 +87,7 @@ void RestoreSink::createDirectory(const CanonPath & path, DirectoryCreatedCallba unix::openFileEnsureBeneathNoSymlinks(dirFd.get(), path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (!dirSink.dirFd) - throw SysError("opening directory '%s'", dirSink.dstPath.string()); + throw SysError("opening directory %s", PathFmt(dirSink.dstPath)); callback(dirSink, CanonPath::root); } @@ -101,10 +101,10 @@ void RestoreSink::createDirectory(const CanonPath & path) if (dirFd) { if (path.isRoot()) /* Trying to create a directory that we already have a file descriptor for. */ - throw Error("path '%s' already exists", p.string()); + throw Error("path %s already exists", PathFmt(p)); if (::mkdirat(dirFd.get(), path.rel_c_str(), 0777) == -1) - throw SysError("creating directory '%s'", p.string()); + throw SysError("creating directory %s", PathFmt(p)); return; } @@ -121,7 +121,7 @@ void RestoreSink::createDirectory(const CanonPath & path) directory. */ dirFd = open(p.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); if (!dirFd) - throw SysError("creating directory '%1%'", p.string()); + throw SysError("creating directory %1%", PathFmt(p)); } #endif }; @@ -179,7 +179,7 @@ void RestoreSink::createRegularFile(const CanonPath & path, std::function '%2%'", p.string(), target); + throw SysError("creating symlink from %1% -> '%2%'", PathFmt(p), target); return; } #endif diff --git a/src/libutil/include/nix/util/fmt.hh b/src/libutil/include/nix/util/fmt.hh index f32a0b62b50a..97fff2cf62a2 100644 --- a/src/libutil/include/nix/util/fmt.hh +++ b/src/libutil/include/nix/util/fmt.hh @@ -3,6 +3,7 @@ #include #include +#include #include "nix/util/ansicolor.hh" namespace nix { @@ -27,6 +28,8 @@ inline void formatHelper(F & f) template inline void formatHelper(F & f, const T & x, const Args &... args) { + static_assert(!std::is_same_v, std::filesystem::path>); + static_assert(!(std::is_same_v, std::filesystem::path> || ...)); // Interpolate one argument and then recurse. formatHelper(f % x, args...); } @@ -103,12 +106,37 @@ struct Magenta const T & value; }; +/** + * All std::filesystem::path values must be wrapped in this class when formatting via HintFmt + * or fmt(). This avoids accidentail double-quoting due to the standard operator<< implementation + * for std::filesystem::path. + */ +struct PathFmt +{ + explicit PathFmt(const std::filesystem::path & p) + { +#ifdef _WIN32 + auto s = p.u8string(); + value = std::string(reinterpret_cast(s.data()), s.size()); +#else + value = p.string(); +#endif + } + + std::string value; +}; + template std::ostream & operator<<(std::ostream & out, const Magenta & y) { return out << ANSI_WARNING << y.value << ANSI_NORMAL; } +inline std::ostream & operator<<(std::ostream & out, const PathFmt & y) +{ + return out << "\"" << y.value << "\""; +} + /** * Values wrapped in this class are printed without coloring. * @@ -175,10 +203,13 @@ public: HintFmt(boost::format && fmt, const Args &... args) : fmt(std::move(fmt)) { + static_assert(!(std::is_same_v, std::filesystem::path> || ...)); setExceptions(fmt); formatHelper(*this, args...); } + HintFmt & operator%(const std::filesystem::path & value) = delete; + template HintFmt & operator%(const T & value) { diff --git a/src/libutil/linux/cgroup.cc b/src/libutil/linux/cgroup.cc index e9fc5646e95f..3253d286194f 100644 --- a/src/libutil/linux/cgroup.cc +++ b/src/libutil/linux/cgroup.cc @@ -40,7 +40,7 @@ StringMap getCgroups(const std::filesystem::path & cgroupFile) static std::regex regex("([0-9]+):([^:]*):(.*)"); std::smatch match; if (!std::regex_match(line, match, regex)) - throw Error("invalid line '%s' in '%s'", line, cgroupFile); + throw Error("invalid line '%s' in %s", line, PathFmt(cgroupFile)); std::string name = hasPrefix(std::string(match[2]), "name=") ? std::string(match[2], 5) : match[2]; cgroups.insert_or_assign(name, match[3]); @@ -84,7 +84,7 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu auto procsFile = cgroup / "cgroup.procs"; if (!pathExists(procsFile)) - throw Error("'%s' is not a cgroup", cgroup); + throw Error("%s is not a cgroup", PathFmt(cgroup)); /* Use the fast way to kill every process in a cgroup, if available. */ @@ -112,7 +112,7 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu break; if (round > 20) - throw Error("cannot kill cgroup '%s'", cgroup); + throw Error("cannot kill cgroup %s", PathFmt(cgroup)); for (auto & pid_s : pids) { pid_t pid; @@ -130,12 +130,12 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu } // FIXME: pid wraparound if (kill(pid, SIGKILL) == -1 && errno != ESRCH) - throw SysError("killing member %d of cgroup '%s'", pid, cgroup); + throw SysError("killing member %d of cgroup %s", pid, PathFmt(cgroup)); } auto sleep = std::chrono::milliseconds((int) std::pow(2.0, std::min(round, 10))); if (sleep.count() > 100) - printError("waiting for %d ms for cgroup '%s' to become empty", sleep.count(), cgroup); + printError("waiting for %d ms for cgroup %s to become empty", sleep.count(), PathFmt(cgroup)); std::this_thread::sleep_for(sleep); round++; } @@ -145,7 +145,7 @@ static CgroupStats destroyCgroup(const std::filesystem::path & cgroup, bool retu stats = getCgroupStats(cgroup); if (rmdir(cgroup.c_str()) == -1) - throw SysError("deleting cgroup %s", cgroup); + throw SysError("deleting cgroup %s", PathFmt(cgroup)); return stats; } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 8f7ec2d294ed..1aab24041b24 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -360,7 +360,7 @@ std::unique_ptr makeJSONLogger(const std::filesystem::path & path, bool ? connect(path) : toDescriptor(open(path.string().c_str(), O_CREAT | O_APPEND | O_WRONLY, 0644)); if (!fd) - throw SysError("opening log file %1%", path); + throw SysError("opening log file %1%", PathFmt(path)); return std::make_unique(std::move(fd), includeNixPrefix); } diff --git a/src/libutil/nar-accessor.cc b/src/libutil/nar-accessor.cc index abdb1671e005..d67c5ecd13cc 100644 --- a/src/libutil/nar-accessor.cc +++ b/src/libutil/nar-accessor.cc @@ -166,7 +166,7 @@ GetNarBytes seekableGetNarBytes(const std::filesystem::path & path) { AutoCloseFD fd = openFileReadonly(path); if (!fd) - throw NativeSysError("opening NAR cache file %s", path); + throw NativeSysError("opening NAR cache file %s", PathFmt(path)); return [inner = seekableGetNarBytes(fd.get()), fd = make_ref(std::move(fd))]( uint64_t offset, uint64_t length, Sink & sink) { return inner(offset, length, sink); }; diff --git a/src/libutil/unix/file-system.cc b/src/libutil/unix/file-system.cc index cebcc4fab2d9..b374696c1013 100644 --- a/src/libutil/unix/file-system.cc +++ b/src/libutil/unix/file-system.cc @@ -56,7 +56,7 @@ void setWriteTime( }, }; if (utimensat(AT_FDCWD, path.c_str(), times, AT_SYMLINK_NOFOLLOW) == -1) - throw SysError("changing modification time of %s (using `utimensat`)", path); + throw SysError("changing modification time of %s (using `utimensat`)", PathFmt(path)); #else struct timeval times[2] = { { @@ -114,7 +114,7 @@ static void _deletePath( if (fstatat(parentfd, name.c_str(), &st, AT_SYMLINK_NOFOLLOW) == -1) { if (errno == ENOENT) return; - throw SysError("getting status of %1%", path); + throw SysError("getting status of %1%", PathFmt(path)); } if (!S_ISDIR(st.st_mode)) { @@ -148,18 +148,18 @@ static void _deletePath( try { unix::fchmodatTryNoFollow(parentfd, CanonPath(name), st.st_mode | PERM_MASK); } catch (SysError & e) { - e.addTrace({}, "while making directory %1% accessible for deletion", path); + e.addTrace({}, "while making directory %1% accessible for deletion", PathFmt(path)); if (e.errNo == EOPNOTSUPP) - e.addTrace({}, "%1% is now a symlink, expected directory", path); + e.addTrace({}, "%1% is now a symlink, expected directory", PathFmt(path)); throw; } int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW); if (fd == -1) - throw SysError("opening directory %1%", path); + throw SysError("opening directory %1%", PathFmt(path)); AutoCloseDir dir(fdopendir(fd)); if (!dir) - throw SysError("opening directory %1%", path); + throw SysError("opening directory %1%", PathFmt(path)); struct dirent * dirent; while (errno = 0, dirent = readdir(dir.get())) { /* sic */ @@ -170,7 +170,7 @@ static void _deletePath( _deletePath(dirfd(dir.get()), path / childName, bytesFreed, ex MOUNTEDPATHS_ARG); } if (errno) - throw SysError("reading directory %1%", path); + throw SysError("reading directory %1%", PathFmt(path)); } int flags = S_ISDIR(st.st_mode) ? AT_REMOVEDIR : 0; @@ -178,7 +178,7 @@ static void _deletePath( if (errno == ENOENT) return; try { - throw SysError("cannot unlink %1%", path); + throw SysError("cannot unlink %1%", PathFmt(path)); } catch (...) { if (!ex) ex = std::current_exception(); @@ -197,7 +197,7 @@ static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFree if (!dirfd) { if (errno == ENOENT) return; - throw SysError("opening directory %s", path.parent_path()); + throw SysError("opening directory %s", PathFmt(path.parent_path())); } std::exception_ptr ex; diff --git a/src/libutil/windows/file-system.cc b/src/libutil/windows/file-system.cc index eb7e12fc9d85..32474dd967fe 100644 --- a/src/libutil/windows/file-system.cc +++ b/src/libutil/windows/file-system.cc @@ -14,7 +14,7 @@ void setWriteTime( // doesn't support access time just modification time. // // System clock vs File clock issues also make that annoying. - warn("Changing file times is not yet implemented on Windows, path is %s", path); + warn("Changing file times is not yet implemented on Windows, path is %s", PathFmt(path)); } Descriptor openDirectory(const std::filesystem::path & path) @@ -55,7 +55,7 @@ void deletePath(const std::filesystem::path & path) std::error_code ec; std::filesystem::remove_all(path, ec); if (ec && ec != std::errc::no_such_file_or_directory) - throw SysError(ec.default_error_condition().value(), "recursively deleting %1%", path); + throw SysError(ec.default_error_condition().value(), "recursively deleting %1%", PathFmt(path)); } void deletePath(const std::filesystem::path & path, uint64_t & bytesFreed) diff --git a/src/libutil/windows/processes.cc b/src/libutil/windows/processes.cc index 597be27f0a32..1946e8b1fad6 100644 --- a/src/libutil/windows/processes.cc +++ b/src/libutil/windows/processes.cc @@ -52,7 +52,7 @@ void Pid::operator=(AutoCloseFD pid) } // TODO: Implement (not needed for process spawning yet) -int Pid::kill() +int Pid::kill(bool allowInterrupts) { assert(pid.get() != INVALID_DESCRIPTOR); @@ -61,7 +61,7 @@ int Pid::kill() throw UnimplementedError("Pid::kill unimplemented"); } -int Pid::wait() +int Pid::wait(bool allowInterrupts) { // https://github.com/nix-windows/nix/blob/windows-meson/src/libutil/util.cc#L1938 assert(pid.get() != INVALID_DESCRIPTOR); diff --git a/src/nix/cat.cc b/src/nix/cat.cc index 83dabdb76773..c78c04e10295 100644 --- a/src/nix/cat.cc +++ b/src/nix/cat.cc @@ -80,7 +80,7 @@ struct CmdCatNar : StoreCommand, MixCat { AutoCloseFD fd = openFileReadonly(narPath); if (!fd) - throw NativeSysError("opening NAR file %s", narPath); + throw NativeSysError("opening NAR file %s", PathFmt(narPath)); auto source = FdSource{fd.get()}; struct CatRegularFileSink : NullFileSystemObjectSink diff --git a/src/nix/develop.cc b/src/nix/develop.cc index 68ff3fcf9655..22d012eb9883 100644 --- a/src/nix/develop.cc +++ b/src/nix/develop.cc @@ -684,7 +684,7 @@ struct CmdDevelop : Common, MixEnvironment // https://github.com/NixOS/nix/issues/5873 script += fmt("SHELL=\"%s\"\n", shell); if (foundInteractive) - script += fmt("PATH=\"%s${PATH:+:$PATH}\"\n", std::filesystem::path(shell).parent_path()); + script += fmt("PATH=\"%s${PATH:+:$PATH}\"\n", std::filesystem::path(shell).parent_path().string()); writeFull(rcFileFd.get(), script); #ifdef _WIN32 // TODO re-enable on Windows @@ -703,7 +703,7 @@ struct CmdDevelop : Common, MixEnvironment auto sourcePath = installableFlake->getLockedFlake()->flake.resolvedRef.input.getSourcePath(); if (sourcePath) { if (chdir(sourcePath->c_str()) == -1) { - throw SysError("chdir to %s failed", *sourcePath); + throw SysError("chdir to %s failed", PathFmt(*sourcePath)); } } } diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 688aa77e070e..32bd9124d12b 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -955,7 +955,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand from2, st.typeString()); changedFiles.push_back(to2); - notice("wrote: %s", to2); + notice("wrote: %s", PathFmt(to2)); } }(templateDir, flakeDir); diff --git a/src/nix/formatter.cc b/src/nix/formatter.cc index 2c0b5c62b39c..08f0b5f053ea 100644 --- a/src/nix/formatter.cc +++ b/src/nix/formatter.cc @@ -145,7 +145,7 @@ struct CmdFormatterBuild : MixFormatter, MixOutLinkByDefault auto buildables = unresolvedApp.build(evalStore, store); createOutLinksMaybe(buildables, store); - logger->cout("%s", app.program); + logger->cout("%s", app.program.string()); }; }; diff --git a/src/nix/ls.cc b/src/nix/ls.cc index 9918132a6fff..0199feda7c4b 100644 --- a/src/nix/ls.cc +++ b/src/nix/ls.cc @@ -152,7 +152,7 @@ struct CmdLsNar : Command, MixLs { AutoCloseFD fd = openFileReadonly(narPath); if (!fd) - throw NativeSysError("opening NAR file %s", narPath); + throw NativeSysError("opening NAR file %s", PathFmt(narPath)); auto source = FdSource{fd.get()}; list(makeLazyNarAccessor(source, seekableGetNarBytes(fd.get())), CanonPath{path}); } diff --git a/src/nix/prefetch.cc b/src/nix/prefetch.cc index d494b0986864..315312ce636f 100644 --- a/src/nix/prefetch.cc +++ b/src/nix/prefetch.cc @@ -114,7 +114,7 @@ std::tuple prefetchFile( AutoCloseFD fd = toDescriptor(open(tmpFile.string().c_str(), O_WRONLY | O_CREAT | O_EXCL, mode)); if (!fd) - throw SysError("creating temporary file '%s'", tmpFile); + throw SysError("creating temporary file %s", PathFmt(tmpFile)); FdSink sink(fd.get()); diff --git a/src/nix/profile.cc b/src/nix/profile.cc index 822c8046eb8a..0c3d3a8e6425 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -140,7 +140,7 @@ struct ProfileManifest sOriginalUrl = "originalUrl"; break; default: - throw Error("profile manifest '%s' has unsupported version %d", manifestPath, version); + throw Error("profile manifest %s has unsupported version %d", PathFmt(manifestPath), version); } auto elems = json["elements"]; diff --git a/src/nix/run.cc b/src/nix/run.cc index 324b736a6a5b..528e19597565 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -222,9 +222,9 @@ void chrootHelper(int argc, char ** argv) auto st = entry.symlink_status(); if (std::filesystem::is_directory(st)) { if (mkdir(dst.c_str(), 0700) == -1) - throw SysError("creating directory '%s'", dst); + throw SysError("creating directory %s", PathFmt(dst)); if (mount(src.c_str(), dst.c_str(), "", MS_BIND | MS_REC, 0) == -1) - throw SysError("mounting '%s' on '%s'", src, dst); + throw SysError("mounting %s on %s", PathFmt(src), PathFmt(dst)); } else if (std::filesystem::is_symlink(st)) createSymlink(readLink(src), dst); } @@ -235,7 +235,7 @@ void chrootHelper(int argc, char ** argv) Finally freeCwd([&]() { free(cwd); }); if (chroot(tmpDir.c_str()) == -1) - throw SysError("chrooting into '%s'", tmpDir); + throw SysError("chrooting into %s", PathFmt(tmpDir)); if (chdir(cwd) == -1) throw SysError("chdir to '%s' in chroot", cwd); diff --git a/src/nix/unix/daemon.cc b/src/nix/unix/daemon.cc index 67918537db0d..74f14a7a08fe 100644 --- a/src/nix/unix/daemon.cc +++ b/src/nix/unix/daemon.cc @@ -335,7 +335,7 @@ static void daemonLoop(std::optional forceTrustClientOpt) throw Error("cannot determine the cgroups file system"); auto rootCgroupPath = *cgroupFS / rootCgroup.rel(); if (!pathExists(rootCgroupPath)) - throw Error("expected cgroup directory '%s'", rootCgroupPath); + throw Error("expected cgroup directory %s", PathFmt(rootCgroupPath)); auto daemonCgroupPath = rootCgroupPath + "/nix-daemon"; // Create new sub-cgroup for the daemon. if (mkdir(daemonCgroupPath.c_str(), 0755) != 0 && errno != EEXIST) diff --git a/src/nix/upgrade-nix.cc b/src/nix/upgrade-nix.cc index f26613bf899e..ae1fe2b37d89 100644 --- a/src/nix/upgrade-nix.cc +++ b/src/nix/upgrade-nix.cc @@ -67,7 +67,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand if (profileDir == "") profileDir = getProfileDir(store); - printInfo("upgrading Nix in profile %s", profileDir); + printInfo("upgrading Nix in profile %s", PathFmt(profileDir)); auto storePath = getLatestNix(store); @@ -100,7 +100,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand *logger, lvlInfo, actUnknown, - fmt("installing '%s' into profile %s...", store->printStorePath(storePath), profileDir)); + fmt("installing '%s' into profile %s...", store->printStorePath(storePath), PathFmt(profileDir))); // FIXME: don't call an external process. runProgram( @@ -120,7 +120,7 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand throw Error("couldn't figure out how Nix is installed, so I can't upgrade it"); const auto & where = whereOpt->parent_path(); - printInfo("found Nix in %s", where); + printInfo("found Nix in %s", PathFmt(where)); if (hasPrefix(where.string(), "/run/current-system")) throw Error("Nix on NixOS must be upgraded via 'nixos-rebuild'"); @@ -132,17 +132,17 @@ struct CmdUpgradeNix : MixDryRun, StoreCommand && std::filesystem::is_symlink(profileDir)) profileDir = readLink(profileDir.string()); - printInfo("found profile %s", profileDir); + printInfo("found profile %s", PathFmt(profileDir)); Path userEnv = canonPath(profileDir.string(), true); if (std::filesystem::exists(profileDir / "manifest.json")) throw Error( "directory %s is managed by 'nix profile' and currently cannot be upgraded by 'nix upgrade-nix'", - profileDir); + PathFmt(profileDir)); if (!std::filesystem::exists(profileDir / "manifest.nix")) - throw Error("directory %s does not appear to be part of a Nix profile", profileDir); + throw Error("directory %s does not appear to be part of a Nix profile", PathFmt(profileDir)); if (!store->isValidPath(store->parseStorePath(userEnv))) throw Error("directory '%s' is not in the Nix store", userEnv); diff --git a/tests/functional/nars.sh b/tests/functional/nars.sh index 2925177c5c9f..68bd191a2543 100755 --- a/tests/functional/nars.sh +++ b/tests/functional/nars.sh @@ -114,7 +114,7 @@ if (( unicodeTestCode == 1 )); then # If the command failed (MacOS or ZFS + normalization), checks that it failed # with the expected "already exists" error, and that this is the same # behavior as `touch` - echo "$unicodeTestOut" | grepQuiet "creating directory '.*/out/â': File exists" + echo "$unicodeTestOut" | grepQuiet "creating directory \".*/out/â\": File exists" (( touchFilesCount == 1 )) elif (( unicodeTestCode == 0 )); then