]> git.saurik.com Git - apt.git/commitdiff
BufferedFileFdPrivate: Make InternalFlush() save against errors
authorJulian Andres Klode <jak@debian.org>
Mon, 28 Dec 2015 21:30:44 +0000 (22:30 +0100)
committerJulian Andres Klode <jak@debian.org>
Mon, 28 Dec 2015 21:30:44 +0000 (22:30 +0100)
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.

apt-pkg/contrib/fileutl.cc

index 0c5d76290ed5d9c26803cb3d7f9b0a5889f61ddd..7f3ed673a13144e7563a7c8e136d57371c98415a 100644 (file)
@@ -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();