libutil: handle all rename errors in moveFile

what the actual fuck. swallowing all errors *except* EXDEV is not okay.
renames do not do this, so moves should not do it either. luckily we do
not use moveFile anywhere except the store path registration code. this
may or may not have caused problems in the past. probably nobody knows.

Change-Id: I2b0255a5703983cbd129abc3219c11ac7171fd12
This commit is contained in:
eldritch horrors
2026-06-05 18:26:21 +00:00
parent e108432cb7
commit 6cd8fcd9d8
2 changed files with 38 additions and 11 deletions
+26
View File
@@ -1,3 +1,4 @@
#include "lix/libstore/temporary-dir.hh"
#include "lix/libutil/c-calls.hh"
#include "lix/libutil/file-system.hh"
#include "lix/libutil/processes.hh"
@@ -210,6 +211,31 @@ namespace nix {
ASSERT_FALSE(pathExists("/schnitzel/darmstadt/pommes"));
}
/* ----------------------------------------------------------------------------
* moveFile
* --------------------------------------------------------------------------*/
TEST(moveFile, handlesErrors)
{
auto tmpDir = createTempDir();
AutoDelete _delete(tmpDir);
auto source = tmpDir + "/source";
auto target = tmpDir + "/target";
// xdev should cause copies, everything else must throw. this is a small selection.
ASSERT_THROW(moveFile(source, target), Error); // ENOENT
createDirs(source);
createSymlink(target, target);
ASSERT_THROW(moveFile(source, target), Error); // ENOTDIR
ASSERT_THROW(moveFile(target, source), Error); // EISDIR
ASSERT_THROW(moveFile(target + "/foo", source), Error); // ELOOP
deletePath(target);
createDirs(target + "/snafu");
ASSERT_THROW(moveFile(source, target), Error); // ENOTEMPTY or EEXIST
}
/* ----------------------------------------------------------------------------
* AutoCloseFD::guessOrInventPath
* --------------------------------------------------------------------------*/