aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libutil/archive.cc8
-rw-r--r--src/libutil/archive.hh1
2 files changed, 9 insertions, 0 deletions
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) { };
};