mirror of
https://github.com/NixOS/nix
synced 2025-06-27 21:01:16 +02:00
Improve the FileSystemObjectSink
interface
More invariants are enforced in the type, and less state needs to be stored in the main sink itself. The method here is roughly that known as "session types". Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
parent
966d6fcd01
commit
6365bbfa81
9 changed files with 357 additions and 219 deletions
|
@ -19,16 +19,12 @@ void copyRecursive(
|
|||
|
||||
case SourceAccessor::tRegular:
|
||||
{
|
||||
sink.createRegularFile(to);
|
||||
if (stat.isExecutable)
|
||||
sink.isExecutable();
|
||||
LambdaSink sink2 {
|
||||
[&](auto d) {
|
||||
sink.receiveContents(d);
|
||||
}
|
||||
};
|
||||
accessor.readFile(from, sink2, [&](uint64_t size) {
|
||||
sink.preallocateContents(size);
|
||||
sink.createRegularFile(to, [&](CreateRegularFileSink & crf) {
|
||||
if (stat.isExecutable)
|
||||
crf.isExecutable();
|
||||
accessor.readFile(from, crf, [&](uint64_t size) {
|
||||
crf.preallocateContents(size);
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
@ -71,20 +67,24 @@ void RestoreSink::createDirectory(const Path & path)
|
|||
throw SysError("creating directory '%1%'", p);
|
||||
};
|
||||
|
||||
void RestoreSink::createRegularFile(const Path & path)
|
||||
struct RestoreRegularFile : CreateRegularFileSink {
|
||||
AutoCloseFD fd;
|
||||
|
||||
void operator () (std::string_view data) override;
|
||||
void isExecutable() override;
|
||||
void preallocateContents(uint64_t size) override;
|
||||
};
|
||||
|
||||
void RestoreSink::createRegularFile(const Path & path, std::function<void(CreateRegularFileSink &)> func)
|
||||
{
|
||||
Path p = dstPath + path;
|
||||
fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
||||
if (!fd) throw SysError("creating file '%1%'", p);
|
||||
RestoreRegularFile crf;
|
||||
crf.fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666);
|
||||
if (!crf.fd) throw SysError("creating file '%1%'", p);
|
||||
func(crf);
|
||||
}
|
||||
|
||||
void RestoreSink::closeRegularFile()
|
||||
{
|
||||
/* Call close explicitly to make sure the error is checked */
|
||||
fd.close();
|
||||
}
|
||||
|
||||
void RestoreSink::isExecutable()
|
||||
void RestoreRegularFile::isExecutable()
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat(fd.get(), &st) == -1)
|
||||
|
@ -93,7 +93,7 @@ void RestoreSink::isExecutable()
|
|||
throw SysError("fchmod");
|
||||
}
|
||||
|
||||
void RestoreSink::preallocateContents(uint64_t len)
|
||||
void RestoreRegularFile::preallocateContents(uint64_t len)
|
||||
{
|
||||
if (!restoreSinkSettings.preallocateContents)
|
||||
return;
|
||||
|
@ -111,7 +111,7 @@ void RestoreSink::preallocateContents(uint64_t len)
|
|||
#endif
|
||||
}
|
||||
|
||||
void RestoreSink::receiveContents(std::string_view data)
|
||||
void RestoreRegularFile::operator () (std::string_view data)
|
||||
{
|
||||
writeFull(fd.get(), data);
|
||||
}
|
||||
|
@ -122,4 +122,32 @@ void RestoreSink::createSymlink(const Path & path, const std::string & target)
|
|||
nix::createSymlink(target, p);
|
||||
}
|
||||
|
||||
|
||||
void RegularFileSink::createRegularFile(const Path & path, std::function<void(CreateRegularFileSink &)> func)
|
||||
{
|
||||
struct CRF : CreateRegularFileSink {
|
||||
RegularFileSink & back;
|
||||
CRF(RegularFileSink & back) : back(back) {}
|
||||
void operator () (std::string_view data) override
|
||||
{
|
||||
back.sink(data);
|
||||
}
|
||||
void isExecutable() override {}
|
||||
} crf { *this };
|
||||
func(crf);
|
||||
}
|
||||
|
||||
|
||||
void NullFileSystemObjectSink::createRegularFile(const Path & path, std::function<void(CreateRegularFileSink &)> func)
|
||||
{
|
||||
struct : CreateRegularFileSink {
|
||||
void operator () (std::string_view data) override {}
|
||||
void isExecutable() override {}
|
||||
} crf;
|
||||
// Even though `NullFileSystemObjectSink` doesn't do anything, it's important
|
||||
// that we call the function, to e.g. advance the parser using this
|
||||
// sink.
|
||||
func(crf);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue