diff options
author | Cary Coutant <ccoutant@google.com> | 2011-10-13 05:06:45 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2011-10-13 05:06:45 +0000 |
commit | dfb4547188c61f6686d459919e38e63c1f7ef999 (patch) | |
tree | e93ab1b19ddcecb2f782edcff107ed81d4ba0356 /gold | |
parent | 0432176d1e4adbcf2ba67cb67e3ec73f0d60d9cd (diff) | |
download | binutils-dfb4547188c61f6686d459919e38e63c1f7ef999.zip binutils-dfb4547188c61f6686d459919e38e63c1f7ef999.tar.gz binutils-dfb4547188c61f6686d459919e38e63c1f7ef999.tar.bz2 |
* gold/output.cc (Output_file::open_base_file): Handle case where
::read returns less than requested size.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 5 | ||||
-rw-r--r-- | gold/output.cc | 32 |
2 files changed, 26 insertions, 11 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 1d128a6..e6e8a9b 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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): diff --git a/gold/output.cc b/gold/output.cc index d6bdaba..7b272e8 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; } |