diff options
Diffstat (limited to 'src/libutil/archive.cc')
-rw-r--r-- | src/libutil/archive.cc | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index ce7cf9754..ed0eb2fb5 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -27,11 +27,13 @@ struct ArchiveSettings : Config #endif "use-case-hack", "Whether to enable a Darwin-specific hack for dealing with file name collisions."}; + Setting<bool> preallocateContents{this, false, "preallocate-contents", + "Whether to preallocate files when writing objects with known size."}; }; static ArchiveSettings archiveSettings; -static GlobalConfig::Register r1(&archiveSettings); +static GlobalConfig::Register rArchiveSettings(&archiveSettings); const std::string narVersionMagic1 = "nix-archive-1"; @@ -48,14 +50,14 @@ static void dumpContents(const Path & path, size_t size, AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); if (!fd) throw SysError("opening file '%1%'", path); - std::vector<unsigned char> buf(65536); + std::vector<char> buf(65536); size_t left = size; while (left > 0) { auto n = std::min(left, buf.size()); readFull(fd.get(), buf.data(), n); left -= n; - sink(buf.data(), n); + sink({buf.data(), n}); } writePadding(size, sink); @@ -66,9 +68,7 @@ static void dump(const Path & path, Sink & sink, PathFilter & filter) { checkInterrupt(); - struct stat st; - if (lstat(path.c_str(), &st)) - throw SysError("getting attributes of path '%1%'", path); + auto st = lstat(path); sink << "("; @@ -155,14 +155,14 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path) sink.preallocateContents(size); uint64_t left = size; - std::vector<unsigned char> buf(65536); + std::vector<char> buf(65536); while (left) { checkInterrupt(); auto n = buf.size(); if ((uint64_t)n > left) n = left; source(buf.data(), n); - sink.receiveContents(buf.data(), n); + sink.receiveContents({buf.data(), n}); left -= n; } @@ -300,21 +300,21 @@ struct RestoreSink : ParseSink Path dstPath; AutoCloseFD fd; - void createDirectory(const Path & path) + void createDirectory(const Path & path) override { Path p = dstPath + path; if (mkdir(p.c_str(), 0777) == -1) throw SysError("creating directory '%1%'", p); }; - void createRegularFile(const Path & path) + void createRegularFile(const Path & path) override { 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); } - void isExecutable() + void isExecutable() override { struct stat st; if (fstat(fd.get(), &st) == -1) @@ -323,8 +323,11 @@ struct RestoreSink : ParseSink throw SysError("fchmod"); } - void preallocateContents(uint64_t len) + void preallocateContents(uint64_t len) override { + if (!archiveSettings.preallocateContents) + return; + #if HAVE_POSIX_FALLOCATE if (len) { errno = posix_fallocate(fd.get(), 0, len); @@ -338,12 +341,12 @@ struct RestoreSink : ParseSink #endif } - void receiveContents(unsigned char * data, size_t len) + void receiveContents(std::string_view data) override { - writeFull(fd.get(), data, len); + writeFull(fd.get(), data); } - void createSymlink(const Path & path, const string & target) + void createSymlink(const Path & path, const string & target) override { Path p = dstPath + path; nix::createSymlink(target, p); @@ -366,11 +369,7 @@ void copyNAR(Source & source, Sink & sink) ParseSink parseSink; /* null sink; just parse the NAR */ - LambdaSource wrapper([&](unsigned char * data, size_t len) { - auto n = source.read(data, len); - sink(data, n); - return n; - }); + TeeSource wrapper { source, sink }; parseDump(parseSink, wrapper); } |