diff options
author | Michael Raskin <7c6f434c@mail.ru> | 2009-05-04T08·10+0000 |
---|---|---|
committer | Michael Raskin <7c6f434c@mail.ru> | 2009-05-04T08·10+0000 |
commit | 098cb9d233ff7e1568b55e88dacf52e1dc8eebab (patch) | |
tree | eb700b94450c279a81689c004721ac6c579e969d /src/libutil | |
parent | c710fe540e3763d821eab74621b43d9422cb7e92 (diff) |
Add an ftruncate call paired with fallocate to play safe with some FSes (namely, BtrFS fallocate sets file size to allocated size, i.e. multiple of block size)
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/archive.cc | 8 | ||||
-rw-r--r-- | src/libutil/archive.hh | 1 |
2 files changed, 9 insertions, 0 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 8f100da4c3ed..4899fbaa4580 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 fff62031397c..f358a2a6be17 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) { }; }; |