diff options
author | Julian Andres Klode <jak@debian.org> | 2015-12-28 22:30:44 +0100 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2015-12-28 22:30:44 +0100 |
commit | 1f5062f656b4919ff1d3126c413c40e53fdd1ab2 (patch) | |
tree | d735762c50362885f47b8982207780c825580883 /apt-pkg/contrib | |
parent | 1a3296c0bd67c46c6ff791345b6101edcb97e778 (diff) |
BufferedFileFdPrivate: Make InternalFlush() save against errors
Previously, if flush errored inside the loop, data could have
already been written to the wrapped descriptor without having
been removed from the buffer.
Also try to work around EINTR here. A better solution might be
to have the individual privates detect an interrupt and return
0 in such a case, instead of relying on errno being untouched
in between the syscall and the return from InternalWrite.
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0c5d76290..7f3ed673a 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1218,16 +1218,16 @@ public: } virtual bool InternalFlush() override { - size_t written = 0; - char *data = writebuffer.get(); - auto size = writebuffer.size(); - - while (written < size) { - auto written_this_time = wrapped->InternalWrite(data + written, size - written); - if (written_this_time < 0) + while (writebuffer.empty() == false) { + auto written = wrapped->InternalWrite(writebuffer.get(), + writebuffer.size()); + // Ignore interrupted syscalls + if (written < 0 && errno == EINTR) + continue; + if (written < 0) return false; - written += written_this_time; + writebuffer.bufferstart += written; } writebuffer.reset(); |