diff options
Diffstat (limited to 'applypatch/applypatch.cpp')
-rw-r--r-- | applypatch/applypatch.cpp | 150 |
1 files changed, 46 insertions, 104 deletions
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp index b1aefa49b..bc8ea79a9 100644 --- a/applypatch/applypatch.cpp +++ b/applypatch/applypatch.cpp @@ -26,24 +26,25 @@ #include <sys/types.h> #include <unistd.h> +#include <algorithm> #include <functional> #include <memory> #include <string> #include <utility> #include <vector> +#include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> +#include <android-base/unique_fd.h> #include <openssl/sha.h> #include "edify/expr.h" -#include "otafault/ota_io.h" #include "otautil/paths.h" #include "otautil/print_sha1.h" static int LoadPartitionContents(const std::string& filename, FileContents* file); -static size_t FileSink(const unsigned char* data, size_t len, int fd); static int GenerateTarget(const FileContents& source_file, const std::unique_ptr<Value>& patch, const std::string& target_filename, const uint8_t target_sha1[SHA_DIGEST_LENGTH], const Value* bonus_data); @@ -54,26 +55,13 @@ int LoadFileContents(const std::string& filename, FileContents* file) { return LoadPartitionContents(filename, file); } - struct stat sb; - if (stat(filename.c_str(), &sb) == -1) { - PLOG(ERROR) << "Failed to stat \"" << filename << "\""; + std::string data; + if (!android::base::ReadFileToString(filename, &data)) { + PLOG(ERROR) << "Failed to read \"" << filename << "\""; return -1; } - std::vector<unsigned char> data(sb.st_size); - unique_file f(ota_fopen(filename.c_str(), "rb")); - if (!f) { - PLOG(ERROR) << "Failed to open \"" << filename << "\""; - return -1; - } - - size_t bytes_read = ota_fread(data.data(), 1, data.size(), f.get()); - if (bytes_read != data.size()) { - LOG(ERROR) << "Short read of \"" << filename << "\" (" << bytes_read << " bytes of " - << data.size() << ")"; - return -1; - } - file->data = std::move(data); + file->data = std::vector<unsigned char>(data.begin(), data.end()); SHA1(file->data.data(), file->data.size(), file->sha1); return 0; } @@ -110,8 +98,8 @@ static int LoadPartitionContents(const std::string& filename, FileContents* file std::sort(pairs.begin(), pairs.end()); const char* partition = pieces[1].c_str(); - unique_file dev(ota_fopen(partition, "rb")); - if (!dev) { + android::base::unique_fd dev(open(partition, O_RDONLY)); + if (dev == -1) { PLOG(ERROR) << "Failed to open eMMC partition \"" << partition << "\""; return -1; } @@ -121,8 +109,7 @@ static int LoadPartitionContents(const std::string& filename, FileContents* file // Allocate enough memory to hold the largest size. std::vector<unsigned char> buffer(pairs[pair_count - 1].first); - unsigned char* buffer_ptr = buffer.data(); - size_t buffer_size = 0; // # bytes read so far + size_t offset = 0; // # bytes read so far bool found = false; for (const auto& pair : pairs) { @@ -131,19 +118,16 @@ static int LoadPartitionContents(const std::string& filename, FileContents* file // Read enough additional bytes to get us up to the next size. (Again, // we're trying the possibilities in order of increasing size). - size_t next = current_size - buffer_size; - if (next > 0) { - size_t read = ota_fread(buffer_ptr, 1, next, dev.get()); - if (next != read) { - LOG(ERROR) << "Short read (" << read << " bytes of " << next << ") for partition \"" - << partition << "\""; + if (current_size - offset > 0) { + if (!android::base::ReadFully(dev, buffer.data() + offset, current_size - offset)) { + PLOG(ERROR) << "Failed to read " << current_size - offset << " bytes of data at offset " + << offset << " for partition " << partition; return -1; } - SHA1_Update(&sha_ctx, buffer_ptr, read); - buffer_size += read; - buffer_ptr += read; - } + SHA1_Update(&sha_ctx, buffer.data() + offset, current_size - offset); + offset = current_size; + } // Duplicate the SHA context and finalize the duplicate so we can // check it against this pair's expected hash. SHA_CTX temp_ctx; @@ -173,31 +157,31 @@ static int LoadPartitionContents(const std::string& filename, FileContents* file SHA1_Final(file->sha1, &sha_ctx); - buffer.resize(buffer_size); + buffer.resize(offset); file->data = std::move(buffer); return 0; } int SaveFileContents(const std::string& filename, const FileContents* file) { - unique_fd fd( - ota_open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR)); + android::base::unique_fd fd( + open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR)); if (fd == -1) { PLOG(ERROR) << "Failed to open \"" << filename << "\" for write"; return -1; } - size_t bytes_written = FileSink(file->data.data(), file->data.size(), fd); - if (bytes_written != file->data.size()) { - PLOG(ERROR) << "Short write of \"" << filename << "\" (" << bytes_written << " bytes of " - << file->data.size(); + if (!android::base::WriteFully(fd, file->data.data(), file->data.size())) { + PLOG(ERROR) << "Failed to write " << file->data.size() << " bytes of data to " << filename; return -1; } - if (ota_fsync(fd) != 0) { + + if (fsync(fd) != 0) { PLOG(ERROR) << "Failed to fsync \"" << filename << "\""; return -1; } - if (ota_close(fd) != 0) { + + if (close(fd.release()) != 0) { PLOG(ERROR) << "Failed to close \"" << filename << "\""; return -1; } @@ -215,42 +199,36 @@ static int WriteToPartition(const unsigned char* data, size_t len, const std::st return -1; } - const char* partition = pieces[1].c_str(); - unique_fd fd(ota_open(partition, O_RDWR)); - if (fd == -1) { - PLOG(ERROR) << "Failed to open \"" << partition << "\""; - return -1; - } - size_t start = 0; bool success = false; for (size_t attempt = 0; attempt < 2; ++attempt) { + std::string partition = pieces[1]; + android::base::unique_fd fd(open(partition.c_str(), O_RDWR)); + if (fd == -1) { + PLOG(ERROR) << "Failed to open \"" << partition << "\""; + return -1; + } + if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) { PLOG(ERROR) << "Failed to seek to " << start << " on \"" << partition << "\""; return -1; } - while (start < len) { - size_t to_write = len - start; - if (to_write > 1 << 20) to_write = 1 << 20; - ssize_t written = TEMP_FAILURE_RETRY(ota_write(fd, data + start, to_write)); - if (written == -1) { - PLOG(ERROR) << "Failed to write to \"" << partition << "\""; - return -1; - } - start += written; + if (!android::base::WriteFully(fd, data + start, len - start)) { + PLOG(ERROR) << "Failed to write " << len - start << " bytes to \"" << partition << "\""; + return -1; } - if (ota_fsync(fd) != 0) { + if (fsync(fd) != 0) { PLOG(ERROR) << "Failed to sync \"" << partition << "\""; return -1; } - if (ota_close(fd) != 0) { + if (close(fd.release()) != 0) { PLOG(ERROR) << "Failed to close \"" << partition << "\""; return -1; } - fd.reset(ota_open(partition, O_RDONLY)); + fd.reset(open(partition.c_str(), O_RDONLY)); if (fd == -1) { PLOG(ERROR) << "Failed to reopen \"" << partition << "\" for verification"; return -1; @@ -258,13 +236,12 @@ static int WriteToPartition(const unsigned char* data, size_t len, const std::st // Drop caches so our subsequent verification read won't just be reading the cache. sync(); - unique_fd dc(ota_open("/proc/sys/vm/drop_caches", O_WRONLY)); - if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) { - PLOG(ERROR) << "Failed to write to /proc/sys/vm/drop_caches"; + std::string drop_cache = "/proc/sys/vm/drop_caches"; + if (!android::base::WriteStringToFile("3\n", drop_cache)) { + PLOG(ERROR) << "Failed to write to " << drop_cache; } else { LOG(INFO) << " caches dropped"; } - ota_close(dc); sleep(1); // Verify. @@ -281,21 +258,9 @@ static int WriteToPartition(const unsigned char* data, size_t len, const std::st to_read = sizeof(buffer); } - size_t so_far = 0; - while (so_far < to_read) { - ssize_t read_count = TEMP_FAILURE_RETRY(ota_read(fd, buffer + so_far, to_read - so_far)); - if (read_count == -1) { - PLOG(ERROR) << "Failed to verify-read " << partition << " at " << p; - return -1; - } else if (read_count == 0) { - LOG(ERROR) << "Verify-reading " << partition << " reached unexpected EOF at " << p; - return -1; - } - if (static_cast<size_t>(read_count) < to_read) { - LOG(INFO) << "Short verify-read " << partition << " at " << p << ": expected " << to_read - << " actual " << read_count; - } - so_far += read_count; + if (!android::base::ReadFully(fd, buffer, to_read)) { + PLOG(ERROR) << "Failed to verify-read " << partition << " at " << p; + return -1; } if (memcmp(buffer, data + p, to_read) != 0) { @@ -311,16 +276,10 @@ static int WriteToPartition(const unsigned char* data, size_t len, const std::st break; } - if (ota_close(fd) != 0) { + if (close(fd.release()) != 0) { PLOG(ERROR) << "Failed to close " << partition; return -1; } - - fd.reset(ota_open(partition, O_RDWR)); - if (fd == -1) { - PLOG(ERROR) << "Failed to reopen " << partition << " for next attempt"; - return -1; - } } if (!success) { @@ -328,10 +287,6 @@ static int WriteToPartition(const unsigned char* data, size_t len, const std::st return -1; } - if (ota_close(fd) == -1) { - PLOG(ERROR) << "Failed to close " << partition; - return -1; - } sync(); return 0; @@ -407,19 +362,6 @@ int ShowLicenses() { return 0; } -static size_t FileSink(const unsigned char* data, size_t len, int fd) { - size_t done = 0; - while (done < len) { - ssize_t wrote = TEMP_FAILURE_RETRY(ota_write(fd, data + done, len - done)); - if (wrote == -1) { - PLOG(ERROR) << "Failed to write " << len - done << " bytes"; - return done; - } - done += wrote; - } - return done; -} - int applypatch(const char* source_filename, const char* target_filename, const char* target_sha1_str, size_t /* target_size */, const std::vector<std::string>& patch_sha1s, |