diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 8f100da4c..4899fbaa4 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -181,6 +181,8 @@ static void parseContents(ParseSink & sink, Source & source, const Path & path) left -= n; } + sink.finalizeContents(size); + readPadding(size, source); } @@ -310,6 +312,12 @@ struct RestoreSink : ParseSink writeFull(fd, data, len); } + void finalizeContents(unsigned long long size) + { + errno = ftruncate(fd, size); + if (errno) throw SysError(format("truncating file to its allocated length of %1% bytes") % size); + } + void createSymlink(const Path & path, const string & target) { Path p = dstPath + path; diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh index fff620313..f358a2a6b 100644 --- a/src/libutil/archive.hh +++ b/src/libutil/archive.hh @@ -64,6 +64,7 @@ struct ParseSink virtual void isExecutable() { }; virtual void preallocateContents(unsigned long long size) { }; virtual void receiveContents(unsigned char * data, unsigned int len) { }; + virtual void finalizeContents(unsigned long long size) { }; virtual void createSymlink(const Path & path, const string & target) { }; };