From dfb4547188c61f6686d459919e38e63c1f7ef999 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Thu, 13 Oct 2011 05:06:45 +0000 Subject: [PATCH] * gold/output.cc (Output_file::open_base_file): Handle case where ::read returns less than requested size. --- gold/ChangeLog | 5 +++++ gold/output.cc | 32 +++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 1d128a6e53..e6e8a9b6ce 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,8 @@ +2011-10-12 Cary Coutant + + * gold/output.cc (Output_file::open_base_file): Handle case where + ::read returns less than requested size. + 2011-10-10 Cary Coutant * gold/incremental.cc (Sized_relobj_incr::Sized_relobj_incr): 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(s.st_size - bytes_to_read), + static_cast(s.st_size)); + return false; + } + p += len; + bytes_to_read -= len; + } ::close(o); return true; } -- 2.34.1