libstore: replace unlink() with std::filesystem::remove()

This commit is contained in:
Amaan Qureshi
2026-02-25 15:11:50 -05:00
parent 16f10c1321
commit b8caabe25f
6 changed files with 41 additions and 17 deletions

View File

@@ -79,8 +79,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
auto target = canonPath(dstFile, true).string();
if (!S_ISDIR(lstat(target).st_mode))
throw Error("collision between %1% and non-directory %2%", PathFmt(srcFile), PathFmt(target));
if (unlink(dstFile.c_str()) == -1)
throw SysError("unlinking %1%", PathFmt(dstFile));
try {
std::filesystem::remove(dstFile);
} catch (std::filesystem::filesystem_error & e) {
throw SystemError(e.code(), "unlinking %s", PathFmt(dstFile));
}
if (mkdir(
dstFile.c_str()
#ifndef _WIN32 // TODO abstract mkdir perms for Windows
@@ -107,8 +110,11 @@ static void createLinks(State & state, const Path & srcDir, const Path & dstDir,
throw BuildEnvFileConflictError(readLink(dstFile).string(), srcFile, priority);
if (prevPriority < priority)
continue;
if (unlink(dstFile.c_str()) == -1)
throw SysError("unlinking %1%", PathFmt(dstFile));
try {
std::filesystem::remove(dstFile);
} catch (std::filesystem::filesystem_error & e) {
throw SystemError(e.code(), "unlinking %s", PathFmt(dstFile));
}
} else if (S_ISDIR(dstSt.st_mode))
throw Error("collision between non-directory '%1%' and directory '%2%'", srcFile, dstFile);
}

View File

@@ -54,10 +54,13 @@ void LocalStore::createTempRootsFile()
return;
while (1) {
if (pathExists(fnTempRoots))
if (pathExists(fnTempRoots)) {
/* It *must* be stale, since there can be no two
processes with the same pid. */
unlink(fnTempRoots.string().c_str());
/* The error code of std::filesystem::remove() is intentionally ignored. */
std::error_code ec;
std::filesystem::remove(fnTempRoots, ec);
}
*fdTempRoots = openLockFile(fnTempRoots, true);
@@ -190,7 +193,9 @@ void LocalStore::findTempRoots(Roots & tempRoots, bool censor)
we don't care about its temporary roots. */
if (lockFile(fd.get(), ltWrite, false)) {
printInfo("removing stale temporary roots file '%1%'", path);
unlink(path.c_str());
/* The error code of std::filesystem::remove() is intentionally ignored. */
std::error_code ec;
std::filesystem::remove(path, ec);
writeFull(fd.get(), "d");
continue;
}
@@ -247,7 +252,9 @@ void LocalStore::findRoots(const Path & path, std::filesystem::file_type type, R
if (!pathExists(target)) {
if (isInDir(path, std::filesystem::path{config->stateDir.get()} / gcRootsDir / "auto")) {
printInfo("removing stale link from '%1%' to '%2%'", path, target);
unlink(path.c_str());
/* The error code of std::filesystem::remove() is intentionally ignored. */
std::error_code ec;
std::filesystem::remove(path, ec);
}
} else {
if (!std::filesystem::is_symlink(target))
@@ -782,8 +789,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
printMsg(lvlTalkative, "deleting unused link '%1%'", path);
if (unlink(path.c_str()) == -1)
throw SysError("deleting '%1%'", path);
try {
std::filesystem::remove(path);
} catch (std::filesystem::filesystem_error & e) {
throw SystemError(e.code(), "deleting %s", PathFmt(path));
}
/* Do not account for deleted file here. Rely on deletePath()
accounting. */

View File

@@ -450,7 +450,9 @@ LocalStore::~LocalStore()
auto fdTempRoots(_fdTempRoots.lock());
if (*fdTempRoots) {
fdTempRoots->close();
unlink(fnTempRoots.string().c_str());
/* The error code of std::filesystem::remove() is intentionally ignored. */
std::error_code ec;
std::filesystem::remove(fnTempRoots, ec);
}
} catch (...) {
ignoreExceptionInDestructor();

View File

@@ -31,10 +31,12 @@ void deleteLockFile(const std::filesystem::path & path, Descriptor desc)
races. Write a (meaningless) token to the file to indicate to
other processes waiting on this lock that the lock is stale
(deleted). */
unlink(path.c_str());
std::error_code ec;
std::filesystem::remove(path, ec);
writeFull(desc, "d");
/* Note that the result of unlink() is ignored; removing the lock
file is an optimisation, not a necessity. */
/* Note that the error code of std::filesystem::remove() is
intentionally ignored; removing the lock file is an optimisation,
not a necessity. */
}
bool lockFile(Descriptor desc, LockType lockType, bool wait)

View File

@@ -587,7 +587,8 @@ AutoCloseFD createAnonymousTempFile()
if (!fd2)
throw SysError("creating temporary file %s", PathFmt(path));
fd = std::move(fd2);
unlink(requireCString(path)); /* We only care about the file descriptor. */
std::error_code ec;
std::filesystem::remove(path, ec); /* We only care about the file descriptor. */
#endif
return fd;

View File

@@ -192,8 +192,11 @@ static void update(const StringSet & channelNames)
if (lstat(nixDefExpr.c_str(), &st) == 0) {
if (S_ISLNK(st.st_mode))
// old-skool ~/.nix-defexpr
if (unlink(nixDefExpr.c_str()) == -1)
throw SysError("unlinking %1%", PathFmt(nixDefExpr));
try {
std::filesystem::remove(nixDefExpr);
} catch (std::filesystem::filesystem_error & e) {
throw SystemError(e.code(), "unlinking %s", PathFmt(nixDefExpr));
}
} else if (errno != ENOENT) {
throw SysError("getting status of %1%", PathFmt(nixDefExpr));
}