summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2013-02-21 16:24:41 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2013-02-21 16:24:41 -0800
commit893df066bbd156b05171e68204a407a212c507e9 (patch)
treecc5cd5b6bfce812e0003a477bf55ea150aa92d85 /libs
parent65b0052a7473b73a18aef73460c9ebec77a2c2a0 (diff)
parent8dda0956b6565a958989af44e885b94dc9bfc9bd (diff)
downloadframeworks_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.cpp24
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;