1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-22 18:29:36 +01:00

libutil: Implement second overload of createDirectory for RestoreSink

Now the intermediate symlink following issue should be completely plugged.
This commit is contained in:
Sergei Zimmerman 2025-11-20 02:03:19 +03:00
parent 09755e696a
commit 40b25153b8
No known key found for this signature in database
3 changed files with 28 additions and 1 deletions

View file

@ -71,6 +71,29 @@ static std::filesystem::path append(const std::filesystem::path & src, const Can
return dst; return dst;
} }
#ifndef _WIN32
void RestoreSink::createDirectory(const CanonPath & path, DirectoryCreatedCallback callback)
{
if (path.isRoot()) {
createDirectory(path);
callback(*this, path);
return;
}
createDirectory(path);
assert(dirFd); // If that's not true the above call must have thrown an exception.
RestoreSink dirSink{startFsync};
dirSink.dstPath = append(dstPath, path);
dirSink.dirFd = ::openat(dirFd.get(), path.rel_c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
if (!dirSink.dirFd)
throw SysError("opening directory '%s'", dirSink.dstPath.string());
callback(dirSink, CanonPath::root);
}
#endif
void RestoreSink::createDirectory(const CanonPath & path) void RestoreSink::createDirectory(const CanonPath & path)
{ {
auto p = append(dstPath, path); auto p = append(dstPath, path);

View file

@ -120,6 +120,10 @@ struct RestoreSink : FileSystemObjectSink
void createDirectory(const CanonPath & path) override; void createDirectory(const CanonPath & path) override;
#ifndef _WIN32
void createDirectory(const CanonPath & path, DirectoryCreatedCallback callback) override;
#endif
void createRegularFile(const CanonPath & path, std::function<void(CreateRegularFileSink &)>) override; void createRegularFile(const CanonPath & path, std::function<void(CreateRegularFileSink &)>) override;
void createSymlink(const CanonPath & path, const std::string & target) override; void createSymlink(const CanonPath & path, const std::string & target) override;

View file

@ -114,7 +114,7 @@ if (( unicodeTestCode == 1 )); then
# If the command failed (MacOS or ZFS + normalization), checks that it failed # If the command failed (MacOS or ZFS + normalization), checks that it failed
# with the expected "already exists" error, and that this is the same # with the expected "already exists" error, and that this is the same
# behavior as `touch` # behavior as `touch`
echo "$unicodeTestOut" | grepQuiet "path '.*/out/â' already exists" echo "$unicodeTestOut" | grepQuiet "creating directory '.*/out/â': File exists"
(( touchFilesCount == 1 )) (( touchFilesCount == 1 ))
elif (( unicodeTestCode == 0 )); then elif (( unicodeTestCode == 0 )); then