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.
}
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();