aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libutil/filesystem.cc15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/libutil/filesystem.cc b/src/libutil/filesystem.cc
index 33a8d81a6..cf99b848a 100644
--- a/src/libutil/filesystem.cc
+++ b/src/libutil/filesystem.cc
@@ -1,8 +1,11 @@
#include <sys/time.h>
+#include <filesystem>
#include "util.hh"
#include "types.hh"
+namespace fs = std::filesystem;
+
namespace nix {
void createSymlink(const Path & target, const Path & link,
@@ -42,8 +45,16 @@ void replaceSymlink(const Path & target, const Path & link,
void moveFile(const Path & oldName, const Path & newName)
{
- if (::rename(oldName.c_str(), newName.c_str()))
- throw SysError("renaming '%1%' to '%2%'", oldName, newName);
+ auto oldPath = fs::path(oldName);
+ auto newPath = fs::path(newName);
+ try {
+ fs::rename(oldPath, newPath);
+ } catch (fs::filesystem_error & e) {
+ if (e.code().value() == EXDEV) {
+ fs::copy(oldName, newName, fs::copy_options::copy_symlinks);
+ fs::remove_all(oldName);
+ }
+ }
}
}