summaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2011-10-13 05:06:45 +0000
committerCary Coutant <ccoutant@google.com>2011-10-13 05:06:45 +0000
commitdfb4547188c61f6686d459919e38e63c1f7ef999 (patch)
treee93ab1b19ddcecb2f782edcff107ed81d4ba0356 /gold/output.cc
parent0432176d1e4adbcf2ba67cb67e3ec73f0d60d9cd (diff)
* gold/output.cc (Output_file::open_base_file): Handle case where
::read returns less than requested size.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc32
1 files changed, 21 insertions, 11 deletions
diff --git a/gold/output.cc b/gold/output.cc
index d6bdabacbc..7b272e8547 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -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;
}