Use FdFile::Copy() in dex2oat for better error checking.
Previously, read errors would have been silently ignored
and write errors would ungracefully crash.
Also improves performance on Linux, including Android,
by using sendfile(). (We still keep Mac builds around.)
Test: m test-art-host
Change-Id: I689e8b9fee4595c42b353bd10042b60a7d6c1bc7
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index e26fa7f..57d4386 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1920,15 +1920,14 @@
TimingLogger::ScopedTiming t("dex2oat OatFile copy", timings_);
std::unique_ptr<File> in(OS::OpenFileForReading(oat_filenames_[i]));
std::unique_ptr<File> out(OS::CreateEmptyFile(oat_unstripped_[i]));
- size_t buffer_size = 8192;
- std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]);
- while (true) {
- int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size));
- if (bytes_read <= 0) {
- break;
- }
- bool write_ok = out->WriteFully(buffer.get(), bytes_read);
- CHECK(write_ok);
+ int64_t in_length = in->GetLength();
+ if (in_length < 0) {
+ PLOG(ERROR) << "Failed to get the length of oat file: " << in->GetPath();
+ return false;
+ }
+ if (!out->Copy(in.get(), 0, in_length)) {
+ PLOG(ERROR) << "Failed to copy oat file to file: " << out->GetPath();
+ return false;
}
if (out->FlushCloseOrErase() != 0) {
PLOG(ERROR) << "Failed to flush and close copied oat file: " << oat_unstripped_[i];