]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[1470] Correct bug concerning status return check
authorStephen Morris <stephen@isc.org>
Tue, 13 Dec 2011 16:57:48 +0000 (16:57 +0000)
committerStephen Morris <stephen@isc.org>
Tue, 13 Dec 2011 16:57:48 +0000 (16:57 +0000)
Original code checked the wrong variable when doing a status check
on read(2)/write(2).

src/lib/util/io/fd.cc

index 04e64dcd3930d1cbaaa7b6146ca7fe3d0c516f6f..f9b17a783c719ef2d906572b5df2fed73d3c23ba 100644 (file)
@@ -23,46 +23,63 @@ namespace io {
 
 bool
 write_data(const int fd, const void *buffer_v, const size_t length) {
-    const unsigned char *buffer(static_cast<const unsigned char *>(buffer_v));
-    size_t rest(length);
-    // Just keep writing until all is written
-    while (rest) {
-        ssize_t written(write(fd, buffer, rest));
-        if (rest == -1) {
-            if (errno == EINTR) { // Just keep going
-                continue;
-            } else {
+
+    const unsigned char* buffer(static_cast<const unsigned char*>(buffer_v));
+    size_t remaining = length;  // Amount remaining to be written
+
+    while (remaining > 0) {
+        ssize_t amount = write(fd, buffer, remaining);
+        if (amount == -1) {
+            // Some error.  Ignore interrupted system calls otherwise return
+            // an error indication.
+            if (errno != EINTR) {
                 return false;
             }
-        } else { // Wrote something
-            rest -= written;
-            buffer += written;
+
+        } else if (amount > 0) {
+            // Wrote "amount" bytes from the buffer
+            remaining -= amount;
+            buffer += amount;
+
+        } else {
+            // Wrote zero bytes from the buffer. We should not get here as any
+            // error that causes zero bytes to be written should have returned
+            // -1.  However, write(2) can return 0, and in this case we
+            // interpret it as an error.
+            return (false);
         }
     }
-    return true;
+    return (true);
 }
 
 ssize_t
 read_data(const int fd, void *buffer_v, const size_t length) {
-    unsigned char *buffer(static_cast<unsigned char *>(buffer_v));
-    size_t rest(length), already(0);
-    while (rest) { // Stil something to read
-        ssize_t amount(read(fd, buffer, rest));
-        if (rest == -1) {
-            if (errno == EINTR) { // Continue on interrupted call
-                continue;
-            } else {
+
+    unsigned char* buffer(static_cast<unsigned char*>(buffer_v));
+    size_t remaining = length;   // Amount remaining to be read
+
+    while (remaining > 0) {
+        ssize_t amount = read(fd, buffer, remaining);
+        if (amount == -1) {
+            // Some error.  Ignore interrupted system calls otherwise return
+            // an error indication.
+            if (errno != EINTR) {
                 return -1;
             }
-        } else if (amount) {
-            already += amount;
-            rest -= amount;
+
+        } else if (amount > 0) {
+            // Read "amount" bytes into the buffer
+            remaining -= amount;
             buffer += amount;
-        } else { // EOF
-            return already;
+
+        } else {
+            // EOF - end the read
+            break;
         }
     }
-    return already;
+
+    // Return total number of bytes read
+    return (static_cast<ssize_t>(length - remaining));
 }
 
 }