summaryrefslogtreecommitdiffstats
path: root/libs/utils
diff options
context:
space:
mode:
authorKenny Root <kroot@google.com>2010-10-05 17:02:42 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2010-10-05 17:02:42 -0700
commit4f65ea60555ef01e6ca0cd64acc0ef698640c853 (patch)
treeb3078773f7d362251cab92b32ac8c12f25adb690 /libs/utils
parent0f935ebfffee769c3c707813bf9db7d50996d785 (diff)
parentbfa33b9484e2c0a019ab81f30261b9696df23a9b (diff)
downloadframeworks_base-4f65ea60555ef01e6ca0cd64acc0ef698640c853.zip
frameworks_base-4f65ea60555ef01e6ca0cd64acc0ef698640c853.tar.gz
frameworks_base-4f65ea60555ef01e6ca0cd64acc0ef698640c853.tar.bz2
am bfa33b94: am f84a5918: Merge "Use pread() in ZipFileRO for Linux" into gingerbread
Merge commit 'bfa33b9484e2c0a019ab81f30261b9696df23a9b' * commit 'bfa33b9484e2c0a019ab81f30261b9696df23a9b': Use pread() in ZipFileRO for Linux
Diffstat (limited to 'libs/utils')
-rw-r--r--libs/utils/ZipFileRO.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index bee86b2..9b1f82f 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -508,6 +508,36 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
unsigned char lfhBuf[kLFHLen];
+#ifdef HAVE_PREAD
+ /*
+ * This file descriptor might be from zygote's preloaded assets,
+ * so we need to do an pread() instead of a lseek() + read() to
+ * guarantee atomicity across the processes with the shared file
+ * descriptors.
+ */
+ ssize_t actual =
+ TEMP_FAILURE_RETRY(pread(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
+
+ if (actual != sizeof(lfhBuf)) {
+ LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+ return false;
+ }
+
+ if (get4LE(lfhBuf) != kLFHSignature) {
+ LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+ "got: data=0x%08lx\n",
+ localHdrOffset, kLFHSignature, get4LE(lfhBuf));
+ return false;
+ }
+#else /* HAVE_PREAD */
+ /*
+ * For hosts don't have pread() we cannot guarantee atomic reads from
+ * an offset in a file. Android should never run on those platforms.
+ * File descriptors inherited from a fork() share file offsets and
+ * there would be nothing to protect from two different processes
+ * calling lseek() concurrently.
+ */
+
{
AutoMutex _l(mFdLock);
@@ -517,7 +547,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
ssize_t actual =
- TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+ TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
if (actual != sizeof(lfhBuf)) {
LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
return false;
@@ -531,6 +561,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
return false;
}
}
+#endif /* HAVE_PREAD */
off_t dataOffset = localHdrOffset + kLFHLen
+ get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);