diff options
author | Kenny Root <kroot@google.com> | 2013-02-21 16:24:41 -0800 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-02-21 16:24:41 -0800 |
commit | 893df066bbd156b05171e68204a407a212c507e9 (patch) | |
tree | cc5cd5b6bfce812e0003a477bf55ea150aa92d85 /libs | |
parent | 65b0052a7473b73a18aef73460c9ebec77a2c2a0 (diff) | |
parent | 8dda0956b6565a958989af44e885b94dc9bfc9bd (diff) | |
download | frameworks_base-893df066bbd156b05171e68204a407a212c507e9.zip frameworks_base-893df066bbd156b05171e68204a407a212c507e9.tar.gz frameworks_base-893df066bbd156b05171e68204a407a212c507e9.tar.bz2 |
am 8dda0956: am 49999acb: Merge "StreamingZipInflater: fix mmap\'d end of read"
* commit '8dda0956b6565a958989af44e885b94dc9bfc9bd':
StreamingZipInflater: fix mmap'd end of read
Diffstat (limited to 'libs')
-rw-r--r-- | libs/androidfw/StreamingZipInflater.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/libs/androidfw/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp index d3fb98d..1dfec23 100644 --- a/libs/androidfw/StreamingZipInflater.cpp +++ b/libs/androidfw/StreamingZipInflater.cpp @@ -23,6 +23,23 @@ #include <string.h> #include <stddef.h> #include <assert.h> +#include <unistd.h> +#include <errno.h> + +/* + * TEMP_FAILURE_RETRY is defined by some, but not all, versions of + * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's + * not already defined, then define it here. + */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + typeof (exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; } @@ -135,7 +152,7 @@ ssize_t StreamingZipInflater::read(void* outBuf, size_t count) { // if we don't have any data to decode, read some in. If we're working // from mmapped data this won't happen, because the clipping to total size // will prevent reading off the end of the mapped input chunk. - if (mInflateState.avail_in == 0) { + if ((mInflateState.avail_in == 0) && (mDataMap == NULL)) { int err = readNextChunk(); if (err < 0) { ALOGE("Unable to access asset data: %d", err); @@ -191,11 +208,10 @@ int StreamingZipInflater::readNextChunk() { if (mInNextChunkOffset < mInTotalSize) { size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset); if (toRead > 0) { - ssize_t didRead = ::read(mFd, mInBuf, toRead); + ssize_t didRead = TEMP_FAILURE_RETRY(::read(mFd, mInBuf, toRead)); //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead); if (didRead < 0) { - // TODO: error - ALOGE("Error reading asset data"); + ALOGE("Error reading asset data: %s", strerror(errno)); return didRead; } else { mInNextChunkOffset += didRead; |