diff options
author | Kenny Root <kroot@google.com> | 2010-10-05 17:02:42 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-10-05 17:02:42 -0700 |
commit | 4f65ea60555ef01e6ca0cd64acc0ef698640c853 (patch) | |
tree | b3078773f7d362251cab92b32ac8c12f25adb690 /libs/utils | |
parent | 0f935ebfffee769c3c707813bf9db7d50996d785 (diff) | |
parent | bfa33b9484e2c0a019ab81f30261b9696df23a9b (diff) | |
download | frameworks_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.cpp | 33 |
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); |