Parse postinstall program progress updates.

In Android postinstall is expected to take a long time in common cases.
This patch allows the postinstall program to report back to the updater
a progress indication, which will then be forwarded to all the clients
listening. These progress updates are part of the FINALIZING status.

Bug: 27880754
TEST=Added unittests. Deployed an update to an edison-eng and post-install reported progress back with the postinstall_example.

Change-Id: I35f96b92f090219c54cca48d8ab07c54cf8b4ab1
diff --git a/common/subprocess.cc b/common/subprocess.cc
index 1bfb911..9738b1d 100644
--- a/common/subprocess.cc
+++ b/common/subprocess.cc
@@ -33,6 +33,8 @@
 #include <brillo/process.h>
 #include <brillo/secure_blob.h>
 
+#include "update_engine/common/utils.h"
+
 using brillo::MessageLoop;
 using std::string;
 using std::unique_ptr;
@@ -114,26 +116,21 @@
 
 void Subprocess::OnStdoutReady(SubprocessRecord* record) {
   char buf[1024];
-  ssize_t rc = 0;
+  size_t bytes_read;
   do {
-    rc = HANDLE_EINTR(read(record->stdout_fd, buf, arraysize(buf)));
-    if (rc < 0) {
-      // EAGAIN and EWOULDBLOCK are normal return values when there's no more
-      // input as we are in non-blocking mode.
-      if (errno != EWOULDBLOCK && errno != EAGAIN) {
-        PLOG(ERROR) << "Error reading fd " << record->stdout_fd;
-        MessageLoop::current()->CancelTask(record->stdout_task_id);
-        record->stdout_task_id = MessageLoop::kTaskIdNull;
-      }
-    } else if (rc == 0) {
-      // A value of 0 means that the child closed its end of the pipe and there
-      // is nothing else to read from stdout.
+    bytes_read = 0;
+    bool eof;
+    bool ok = utils::ReadAll(
+        record->stdout_fd, buf, arraysize(buf), &bytes_read, &eof);
+    record->stdout.append(buf, bytes_read);
+    if (!ok || eof) {
+      // There was either an error or an EOF condition, so we are done watching
+      // the file descriptor.
       MessageLoop::current()->CancelTask(record->stdout_task_id);
       record->stdout_task_id = MessageLoop::kTaskIdNull;
-    } else {
-      record->stdout.append(buf, rc);
+      return;
     }
-  } while (rc > 0);
+  } while (bytes_read);
 }
 
 void Subprocess::ChildExitedCallback(const siginfo_t& info) {
diff --git a/common/utils.cc b/common/utils.cc
index 2ac63b9..1b718a4 100644
--- a/common/utils.cc
+++ b/common/utils.cc
@@ -186,6 +186,35 @@
   return true;
 }
 
+bool ReadAll(
+    int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof) {
+  char* c_buf = static_cast<char*>(buf);
+  size_t bytes_read = 0;
+  *eof = false;
+  while (bytes_read < count) {
+    ssize_t rc = HANDLE_EINTR(read(fd, c_buf + bytes_read, count - bytes_read));
+    if (rc < 0) {
+      // EAGAIN and EWOULDBLOCK are normal return values when there's no more
+      // input and we are in non-blocking mode.
+      if (errno != EWOULDBLOCK && errno != EAGAIN) {
+        PLOG(ERROR) << "Error reading fd " << fd;
+        *out_bytes_read = bytes_read;
+        return false;
+      }
+      break;
+    } else if (rc == 0) {
+      // A value of 0 means that we reached EOF and there is nothing else to
+      // read from this fd.
+      *eof = true;
+      break;
+    } else {
+      bytes_read += rc;
+    }
+  }
+  *out_bytes_read = bytes_read;
+  return true;
+}
+
 bool WriteAll(int fd, const void* buf, size_t count) {
   const char* c_buf = static_cast<const char*>(buf);
   ssize_t bytes_written = 0;
diff --git a/common/utils.h b/common/utils.h
index 2402995..dbf92d2 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -75,6 +75,14 @@
                size_t count,
                off_t offset);
 
+// Calls read() repeatedly until |count| bytes are read or EOF or EWOULDBLOCK
+// is reached. Returns whether all read() calls succeeded (including EWOULDBLOCK
+// as a success case), sets |eof| to whether the eof was reached and sets
+// |out_bytes_read| to the actual number of bytes read regardless of the return
+// value.
+bool ReadAll(
+    int fd, void* buf, size_t count, size_t* out_bytes_read, bool* eof);
+
 // Calls pread() repeatedly until count bytes are read, or EOF is reached.
 // Returns number of bytes read in *bytes_read. Returns true on success.
 bool PReadAll(int fd, void* buf, size_t count, off_t offset,