Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08599621 authored by Kenny Root's avatar Kenny Root Committed by Android (Google) Code Review
Browse files

Merge "Use pread() in ZipFileRO for Linux" into gingerbread

parents 250b2c9c 61ef747e
Loading
Loading
Loading
Loading
+17 −7
Original line number Original line Diff line number Diff line
@@ -14,13 +14,19 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


//
/*
// Read-only access to Zip archives, with minimal heap allocation.
 * Read-only access to Zip archives, with minimal heap allocation.
//
 *
// This is similar to the more-complete ZipFile class, but no attempt
 * This is similar to the more-complete ZipFile class, but no attempt
// has been made to make them interchangeable.  This class operates under
 * has been made to make them interchangeable.  This class operates under
// a very different set of assumptions and constraints.
 * a very different set of assumptions and constraints.
//
 *
 * One such assumption is that if you're getting file descriptors for
 * use with this class as a child of a fork() operation, you must be on
 * a pread() to guarantee correct operation. This is because pread() can
 * atomically read at a file offset without worrying about a lock around an
 * lseek() + read() pair.
 */
#ifndef __LIBS_ZIPFILERO_H
#ifndef __LIBS_ZIPFILERO_H
#define __LIBS_ZIPFILERO_H
#define __LIBS_ZIPFILERO_H


@@ -55,6 +61,10 @@ typedef void* ZipEntryRO;
 * the record structure.  However, this requires a private mapping of
 * the record structure.  However, this requires a private mapping of
 * every page that the Central Directory touches.  Easier to tuck a copy
 * every page that the Central Directory touches.  Easier to tuck a copy
 * of the string length into the hash table entry.
 * of the string length into the hash table entry.
 *
 * NOTE: If this is used on file descriptors inherited from a fork() operation,
 * you must be on a platform that implements pread() to guarantee correctness
 * on the shared file descriptors.
 */
 */
class ZipFileRO {
class ZipFileRO {
public:
public:
+32 −1
Original line number Original line Diff line number Diff line
@@ -508,6 +508,36 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,


        unsigned char lfhBuf[kLFHLen];
        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);
            AutoMutex _l(mFdLock);


@@ -531,6 +561,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
                return false;
                return false;
            }
            }
        }
        }
#endif /* HAVE_PREAD */


        off_t dataOffset = localHdrOffset + kLFHLen
        off_t dataOffset = localHdrOffset + kLFHLen
            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);