summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2015-12-28 22:30:44 +0100
committerJulian Andres Klode <jak@debian.org>2015-12-28 22:30:44 +0100
commit1f5062f656b4919ff1d3126c413c40e53fdd1ab2 (patch)
treed735762c50362885f47b8982207780c825580883
parent1a3296c0bd67c46c6ff791345b6101edcb97e778 (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.
-rw-r--r--apt-pkg/contrib/fileutl.cc16
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();