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
}
virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override
{
}
virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override
{
lzma->stream.next_in = (uint8_t *)From;
lzma->stream.avail_in = Size;
lzma->stream.next_out = lzma->buffer;
lzma->stream.next_in = (uint8_t *)From;
lzma->stream.avail_in = Size;
lzma->stream.next_out = lzma->buffer;
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)
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)
+ {
+ Res = -1;
+ errno = 0;
+ }
- 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
{
}
virtual bool InternalWriteError() override
{
while (Res > 0 && Size > 0)
{
Res = d->InternalWrite(From, Size);
while (Res > 0 && Size > 0)
{
Res = d->InternalWrite(From, Size);
- if (Res < 0 && errno == EINTR)
- continue;
+ {
+ if (errno == EINTR)
+ {
+ // trick the while-loop into running again
+ Res = 1;
+ errno = 0;
+ continue;
+ }
return d->InternalWriteError();
return d->InternalWriteError();
From = (char const *)From + Res;
Size -= Res;
From = (char const *)From + Res;
Size -= Res;