* gold/output.cc (Output_file::open_base_file): Handle case where
authorCary Coutant <ccoutant@google.com>
Thu, 13 Oct 2011 05:06:45 +0000 (05:06 +0000)
committerCary Coutant <ccoutant@google.com>
Thu, 13 Oct 2011 05:06:45 +0000 (05:06 +0000)
::read returns less than requested size.

gold/ChangeLog
gold/output.cc

index 1d128a6..e6e8a9b 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-12  Cary Coutant  <ccoutant@google.com>
+
+       * gold/output.cc (Output_file::open_base_file): Handle case where
+       ::read returns less than requested size.
+
 2011-10-10  Cary Coutant  <ccoutant@google.com>
 
        * gold/incremental.cc (Sized_relobj_incr::Sized_relobj_incr):
index d6bdaba..7b272e8 100644 (file)
@@ -4893,17 +4893,27 @@ Output_file::open_base_file(const char* base_name, bool writable)
   if (use_base_file)
     {
       this->open(s.st_size);
-      ssize_t len = ::read(o, this->base_, s.st_size);
-      if (len < 0)
-        {
-         gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
-         return false;
-        }
-      if (len < s.st_size)
-        {
-         gold_info(_("%s: file too short"), base_name);
-         return false;
-        }
+      ssize_t bytes_to_read = s.st_size;
+      unsigned char* p = this->base_;
+      while (bytes_to_read > 0)
+       {
+         ssize_t len = ::read(o, p, bytes_to_read);
+         if (len < 0)
+           {
+             gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
+             return false;
+           }
+         if (len == 0)
+           {
+             gold_info(_("%s: file too short: read only %lld of %lld bytes"),
+                       base_name,
+                       static_cast<long long>(s.st_size - bytes_to_read),
+                       static_cast<long long>(s.st_size));
+             return false;
+           }
+         p += len;
+         bytes_to_read -= len;
+       }
       ::close(o);
       return true;
     }