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:
parent
09755e696a
commit
40b25153b8
3 changed files with 28 additions and 1 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue