summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorColin Watson <cjwatson@ubuntu.com>2016-03-04 22:17:12 -0300
committerDavid Kalnischkies <david@kalnischkies.de>2016-03-06 10:22:45 +0100
commit9a63c3f480bcbc3232067237671b854d43a97236 (patch)
tree56748b8fdf424d146e1e6512c0c8af154e403090 /apt-pkg
parent031a3f254a2a73b2843ead28a2481b63ec1d7244 (diff)
downloadapt-9a63c3f480bcbc3232067237671b854d43a97236.tar.gz
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
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/contrib/fileutl.cc29
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;