* testsuite/binary_unittest.cc (read_all): New function.
	(Sized_binary_test): Use it instead of ::read.
	* fileread.cc (do_read): Don't assume pread always reads the whole
	amount in a single call.
This commit is contained in:
Roland McGrath
2012-12-10 17:38:42 +00:00
parent 8b9737bf8c
commit 4c8a1de1fe
3 changed files with 63 additions and 22 deletions

View File

@ -1,3 +1,10 @@
2012-12-10 Roland McGrath <mcgrathr@google.com>
* testsuite/binary_unittest.cc (read_all): New function.
(Sized_binary_test): Use it instead of ::read.
* fileread.cc (do_read): Don't assume pread always reads the whole
amount in a single call.
2012-12-10 Alan Modra <amodra@gmail.com> 2012-12-10 Alan Modra <amodra@gmail.com>
* powerpc.cc (Target_selector_powerpc::Target_selector_powerpc): * powerpc.cc (Target_selector_powerpc::Target_selector_powerpc):

View File

@ -1,6 +1,7 @@
// fileread.cc -- read files for gold // fileread.cc -- read files for gold
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>. // Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold. // This file is part of gold.
@ -389,16 +390,26 @@ File_read::do_read(off_t start, section_size_type size, void* p)
else else
{ {
this->reopen_descriptor(); this->reopen_descriptor();
bytes = ::pread(this->descriptor_, p, size, start);
if (static_cast<section_size_type>(bytes) == size)
return;
if (bytes < 0) char *read_ptr = static_cast<char *>(p);
off_t read_pos = start;
size_t to_read = size;
do
{ {
bytes = ::pread(this->descriptor_, read_ptr, to_read, read_pos);
if (bytes < 0)
gold_fatal(_("%s: pread failed: %s"), gold_fatal(_("%s: pread failed: %s"),
this->filename().c_str(), strerror(errno)); this->filename().c_str(), strerror(errno));
read_pos += bytes;
read_ptr += bytes;
to_read -= bytes;
if (to_read == 0)
return; return;
} }
while (bytes > 0);
bytes = size - to_read;
} }
gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"), gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"),

View File

@ -38,6 +38,29 @@
#include "test.h" #include "test.h"
#include "testfile.h" #include "testfile.h"
namespace
{
ssize_t
read_all (int fd, unsigned char* buf, ssize_t size)
{
ssize_t total_read = 0;
while (size > 0)
{
ssize_t nread = ::read(fd, buf, size);
if (nread < 0)
return nread;
if (nread == 0)
break;
buf += nread;
size -= nread;
total_read += nread;
}
return total_read;
}
} // End anonymous namespace.
namespace gold_testsuite namespace gold_testsuite
{ {
@ -57,7 +80,7 @@ Sized_binary_test()
int o = open_descriptor(-1, gold::program_name, O_RDONLY); int o = open_descriptor(-1, gold::program_name, O_RDONLY);
CHECK(o >= 0); CHECK(o >= 0);
unsigned char* filedata = new unsigned char[st.st_size]; unsigned char* filedata = new unsigned char[st.st_size];
CHECK(::read(o, filedata, st.st_size) == st.st_size); CHECK(read_all(o, filedata, st.st_size) == static_cast<ssize_t>(st.st_size));
CHECK(::close(o) == 0); CHECK(::close(o) == 0);
Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian, Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian,