diff options
author | Colin Watson <cjwatson@ubuntu.com> | 2016-03-04 22:17:12 -0300 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2016-03-06 10:22:45 +0100 |
commit | 9a63c3f480bcbc3232067237671b854d43a97236 (patch) | |
tree | 56748b8fdf424d146e1e6512c0c8af154e403090 | |
parent | 031a3f254a2a73b2843ead28a2481b63ec1d7244 (diff) |
Fix lzma write support to handle "try again" case
The liblzma-based write code needs the same tweaks that the read code
already has to cope with the situation where lzma_code returns zero the
first time through because avail_out is zero, but will do more work if
called again.
This ports the read tweaks to the write code as closely as possible
(including matching comments etc.).
Closes: #751688
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index eae4d233e..b7c7b231d 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1816,6 +1816,7 @@ public: } virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override { + ssize_t Res; lzma->stream.next_in = (uint8_t *)From; lzma->stream.avail_in = Size; lzma->stream.next_out = lzma->buffer; @@ -1826,9 +1827,21 @@ public: size_t const n = sizeof(lzma->buffer)/sizeof(lzma->buffer[0]) - lzma->stream.avail_out; size_t const m = (n == 0) ? 0 : fwrite(lzma->buffer, 1, n, lzma->file); if (m != n) - return -1; + { + Res = -1; + errno = 0; + } else - return Size - lzma->stream.avail_in; + { + Res = Size - lzma->stream.avail_in; + if (Res == 0) + { + // lzma run was okay, but produced no output… + Res = -1; + errno = EINTR; + } + } + return Res; } virtual bool InternalWriteError() override { @@ -2425,10 +2438,18 @@ bool FileFd::Write(const void *From,unsigned long long Size) while (Res > 0 && Size > 0) { Res = d->InternalWrite(From, Size); - if (Res < 0 && errno == EINTR) - continue; + if (Res < 0) + { + if (errno == EINTR) + { + // trick the while-loop into running again + Res = 1; + errno = 0; + continue; + } return d->InternalWriteError(); + } From = (char const *)From + Res; Size -= Res; |