Change assets to use 64-bit API

The asset system and supporting libraries were using off_t instead of
off64_t to access files larger than 2GB (32-bit signed). This change
replaces all off_t with off64_t and lseek64.

There is a new utils/Compat.h added for Mac OS compatibility.

Also fixed some size-related compiler warnings.

Bug: 3205336
Change-Id: I9097b3cb7a602e811fe52f245939d8975da55e9e
This commit is contained in:
Kenny Root 2010-11-24 12:56:06 -08:00 committed by Alex Ray
parent 1d618d63c1
commit e2fa7dc58e
13 changed files with 172 additions and 117 deletions

View file

@ -23,9 +23,11 @@
#include <stdio.h>
#include <sys/types.h>
#include "FileMap.h"
#include "String8.h"
#include "Errors.h"
#include <utils/Compat.h>
#include <utils/Errors.h>
#include <utils/FileMap.h>
#include <utils/String8.h>
namespace android {
@ -69,10 +71,10 @@ public:
/*
* Seek to the specified offset. "whence" uses the same values as
* lseek/fseek. Returns the new position on success, or (off_t) -1
* lseek/fseek. Returns the new position on success, or (off64_t) -1
* on failure.
*/
virtual off_t seek(off_t offset, int whence) = 0;
virtual off64_t seek(off64_t offset, int whence) = 0;
/*
* Close the asset, freeing all associated resources.
@ -87,26 +89,26 @@ public:
/*
* Get the total amount of data that can be read.
*/
virtual off_t getLength(void) const = 0;
virtual off64_t getLength(void) const = 0;
/*
* Get the total amount of data that can be read from the current position.
*/
virtual off_t getRemainingLength(void) const = 0;
virtual off64_t getRemainingLength(void) const = 0;
/*
* Open a new file descriptor that can be used to read this asset.
* Returns -1 if you can not use the file descriptor (for example if the
* asset is compressed).
*/
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const = 0;
/*
* Return whether this asset's buffer is allocated in RAM (not mmapped).
* Note: not virtual so it is safe to call even when being destroyed.
*/
virtual bool isAllocated(void) const { return false; }
/*
* Get a string identifying the asset's source. This might be a full
* path, it might be a colon-separated list of identifiers.
@ -120,7 +122,7 @@ protected:
Asset(void); // constructor; only invoked indirectly
/* handle common seek() housekeeping */
off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn);
off64_t handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn);
/* set the asset source string */
void setAssetSource(const String8& path) { mAssetSource = path; }
@ -153,7 +155,7 @@ private:
*
* The asset takes ownership of the file descriptor.
*/
static Asset* createFromFileSegment(int fd, off_t offset, size_t length,
static Asset* createFromFileSegment(int fd, off64_t offset, size_t length,
AccessMode mode);
/*
@ -166,7 +168,7 @@ private:
* This may not verify the validity of the compressed data until first
* use.
*/
static Asset* createFromCompressedData(int fd, off_t offset,
static Asset* createFromCompressedData(int fd, off64_t offset,
int compressionMethod, size_t compressedLength,
size_t uncompressedLength, AccessMode mode);
#endif
@ -221,7 +223,7 @@ public:
*
* On success, the object takes ownership of "fd".
*/
status_t openChunk(const char* fileName, int fd, off_t offset, size_t length);
status_t openChunk(const char* fileName, int fd, off64_t offset, size_t length);
/*
* Use a memory-mapped region.
@ -234,18 +236,18 @@ public:
* Standard Asset interfaces.
*/
virtual ssize_t read(void* buf, size_t count);
virtual off_t seek(off_t offset, int whence);
virtual off64_t seek(off64_t offset, int whence);
virtual void close(void);
virtual const void* getBuffer(bool wordAligned);
virtual off_t getLength(void) const { return mLength; }
virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
virtual off64_t getLength(void) const { return mLength; }
virtual off64_t getRemainingLength(void) const { return mLength-mOffset; }
virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const;
virtual bool isAllocated(void) const { return mBuf != NULL; }
private:
off_t mStart; // absolute file offset of start of chunk
off_t mLength; // length of the chunk
off_t mOffset; // current local offset, 0 == mStart
off64_t mStart; // absolute file offset of start of chunk
off64_t mLength; // length of the chunk
off64_t mOffset; // current local offset, 0 == mStart
FILE* mFp; // for read/seek
char* mFileName; // for opening
@ -276,7 +278,7 @@ public:
*
* On success, the object takes ownership of "fd".
*/
status_t openChunk(int fd, off_t offset, int compressionMethod,
status_t openChunk(int fd, off64_t offset, int compressionMethod,
size_t uncompressedLen, size_t compressedLen);
/*
@ -291,19 +293,19 @@ public:
* Standard Asset interfaces.
*/
virtual ssize_t read(void* buf, size_t count);
virtual off_t seek(off_t offset, int whence);
virtual off64_t seek(off64_t offset, int whence);
virtual void close(void);
virtual const void* getBuffer(bool wordAligned);
virtual off_t getLength(void) const { return mUncompressedLen; }
virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
virtual off64_t getLength(void) const { return mUncompressedLen; }
virtual off64_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
virtual int openFileDescriptor(off64_t* outStart, off64_t* outLength) const { return -1; }
virtual bool isAllocated(void) const { return mBuf != NULL; }
private:
off_t mStart; // offset to start of compressed data
off_t mCompressedLen; // length of the compressed data
off_t mUncompressedLen; // length of the uncompressed data
off_t mOffset; // current offset, 0 == start of uncomp data
off64_t mStart; // offset to start of compressed data
off64_t mCompressedLen; // length of the compressed data
off64_t mUncompressedLen; // length of the uncompressed data
off64_t mOffset; // current offset, 0 == start of uncomp data
FileMap* mMap; // for memory-mapped input
int mFd; // for file input

42
include/utils/Compat.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __LIB_UTILS_COMPAT_H
#define __LIB_UTILS_COMPAT_H
#include <unistd.h>
/* Compatibility definitions for non-Linux (i.e., BSD-based) hosts. */
#ifndef HAVE_OFF64_T
#if _FILE_OFFSET_BITS < 64
#error "_FILE_OFFSET_BITS < 64; large files are not supported on this platform"
#endif /* _FILE_OFFSET_BITS < 64 */
typedef off_t off64_t;
static inline off64_t lseek64(int fd, off64_t offset, int whence) {
return lseek(fd, offset, whence);
}
#ifdef HAVE_PREAD
static inline ssize_t pread64(int fd, void* buf, size_t nbytes, off64_t offset) {
return pread(fd, buf, nbytes, offset);
}
#endif
#endif /* !HAVE_OFF64_T */
#endif /* __LIB_UTILS_COMPAT_H */

View file

@ -22,6 +22,8 @@
#include <sys/types.h>
#include <utils/Compat.h>
#ifdef HAVE_WIN32_FILEMAP
#include <windows.h>
#endif
@ -55,7 +57,7 @@ public:
* Returns "false" on failure.
*/
bool create(const char* origFileName, int fd,
off_t offset, size_t length, bool readOnly);
off64_t offset, size_t length, bool readOnly);
/*
* Return the name of the file this map came from, if known.
@ -75,7 +77,7 @@ public:
/*
* Get the data offset used to create this map.
*/
off_t getDataOffset(void) const { return mDataOffset; }
off64_t getDataOffset(void) const { return mDataOffset; }
/*
* Get a "copy" of the object.
@ -118,7 +120,7 @@ private:
char* mFileName; // original file name, if known
void* mBasePtr; // base of mmap area; page aligned
size_t mBaseLength; // length, measured from "mBasePtr"
off_t mDataOffset; // offset used when map was created
off64_t mDataOffset; // offset used when map was created
void* mDataPtr; // start of requested data, offset from base
size_t mDataLength; // length, measured from "mDataPtr"
#ifdef HAVE_WIN32_FILEMAP

View file

@ -21,6 +21,8 @@
#include <inttypes.h>
#include <zlib.h>
#include <utils/Compat.h>
namespace android {
class StreamingZipInflater {
@ -29,7 +31,7 @@ public:
static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
// Flavor that pages in the compressed data from a fd
StreamingZipInflater(int fd, off_t compDataStart, size_t uncompSize, size_t compSize);
StreamingZipInflater(int fd, off64_t compDataStart, size_t uncompSize, size_t compSize);
// Flavor that gets the compressed data from an in-memory buffer
StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
@ -43,7 +45,7 @@ public:
// seeking backwards requires uncompressing fom the beginning, so is very
// expensive. seeking forwards only requires uncompressing from the current
// position to the destination.
off_t seekAbsolute(off_t absoluteInputPosition);
off64_t seekAbsolute(off64_t absoluteInputPosition);
private:
void initInflateState();
@ -51,7 +53,7 @@ private:
// where to find the uncompressed data
int mFd;
off_t mInFileStart; // where the compressed data lives in the file
off64_t mInFileStart; // where the compressed data lives in the file
class FileMap* mDataMap;
z_stream mInflateState;
@ -63,7 +65,7 @@ private:
size_t mOutTotalSize; // total uncompressed size of the blob
// current output state bookkeeping
off_t mOutCurPosition; // current position in total offset
off64_t mOutCurPosition; // current position in total offset
size_t mOutLastDecoded; // last decoded byte + 1 in mOutbuf
size_t mOutDeliverable; // next undelivered byte of decoded output in mOutBuf

View file

@ -24,6 +24,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <utils/Compat.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -48,7 +50,7 @@ extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
int* pMethod, size_t* pUncompLen,
size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32);
extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);

View file

@ -30,6 +30,7 @@
#ifndef __LIBS_ZIPFILERO_H
#define __LIBS_ZIPFILERO_H
#include <utils/Compat.h>
#include <utils/Errors.h>
#include <utils/FileMap.h>
#include <utils/threads.h>
@ -128,7 +129,7 @@ public:
* appears to be bad.
*/
bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const;
/*
* Create a new FileMap object that maps a subset of the archive. For
@ -231,7 +232,7 @@ private:
int mNumEntries;
/* CD directory offset in the Zip archive */
off_t mDirectoryOffset;
off64_t mDirectoryOffset;
/*
* We know how many entries are in the Zip archive, so we have a

View file

@ -70,11 +70,6 @@ LOCAL_CFLAGS += -DMB_CUR_MAX=1
endif
endif
ifeq ($(HOST_OS),darwin)
# MacOS doesn't have lseek64. However, off_t is 64-bit anyway.
LOCAL_CFLAGS += -DOFF_T_IS_64_BIT
endif
include $(BUILD_HOST_STATIC_LIBRARY)

View file

@ -35,6 +35,9 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
using namespace android;
@ -62,7 +65,7 @@ String8 Asset::getAssetAllocations()
if (cur->isAllocated()) {
res.append(" ");
res.append(cur->getAssetSource());
off_t size = (cur->getLength()+512)/1024;
off64_t size = (cur->getLength()+512)/1024;
char buf[64];
sprintf(buf, ": %dK\n", (int)size);
res.append(buf);
@ -119,7 +122,7 @@ Asset::~Asset(void)
{
_FileAsset* pAsset;
status_t result;
off_t length;
off64_t length;
int fd;
fd = open(fileName, O_RDONLY | O_BINARY);
@ -132,12 +135,26 @@ Asset::~Asset(void)
* always open things read-only it doesn't really matter, so there's
* no value in incurring the extra overhead of an fstat() call.
*/
length = lseek(fd, 0, SEEK_END);
// TODO(kroot): replace this with fstat despite the plea above.
#if 1
length = lseek64(fd, 0, SEEK_END);
if (length < 0) {
::close(fd);
return NULL;
}
(void) lseek(fd, 0, SEEK_SET);
(void) lseek64(fd, 0, SEEK_SET);
#else
struct stat st;
if (fstat(fd, &st) < 0) {
::close(fd);
return NULL;
}
if (!S_ISREG(st.st_mode)) {
::close(fd);
return NULL;
}
#endif
pAsset = new _FileAsset;
result = pAsset->openChunk(fileName, fd, 0, length);
@ -162,7 +179,7 @@ Asset::~Asset(void)
{
_CompressedAsset* pAsset;
status_t result;
off_t fileLen;
off64_t fileLen;
bool scanResult;
long offset;
int method;
@ -215,7 +232,7 @@ Asset::~Asset(void)
/*
* Create a new Asset from part of an open file.
*/
/*static*/ Asset* Asset::createFromFileSegment(int fd, off_t offset,
/*static*/ Asset* Asset::createFromFileSegment(int fd, off64_t offset,
size_t length, AccessMode mode)
{
_FileAsset* pAsset;
@ -233,7 +250,7 @@ Asset::~Asset(void)
/*
* Create a new Asset from compressed data in an open file.
*/
/*static*/ Asset* Asset::createFromCompressedData(int fd, off_t offset,
/*static*/ Asset* Asset::createFromCompressedData(int fd, off64_t offset,
int compressionMethod, size_t uncompressedLen, size_t compressedLen,
AccessMode mode)
{
@ -295,9 +312,9 @@ Asset::~Asset(void)
*
* Returns the new chunk offset, or -1 if the seek is illegal.
*/
off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
off64_t Asset::handleSeek(off64_t offset, int whence, off64_t curPosn, off64_t maxPosn)
{
off_t newOffset;
off64_t newOffset;
switch (whence) {
case SEEK_SET:
@ -311,15 +328,15 @@ off_t Asset::handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn)
break;
default:
LOGW("unexpected whence %d\n", whence);
// this was happening due to an off_t size mismatch
// this was happening due to an off64_t size mismatch
assert(false);
return (off_t) -1;
return (off64_t) -1;
}
if (newOffset < 0 || newOffset > maxPosn) {
LOGW("seek out of range: want %ld, end=%ld\n",
(long) newOffset, (long) maxPosn);
return (off_t) -1;
return (off64_t) -1;
}
return newOffset;
@ -353,7 +370,7 @@ _FileAsset::~_FileAsset(void)
*
* Zero-length chunks are allowed.
*/
status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_t length)
status_t _FileAsset::openChunk(const char* fileName, int fd, off64_t offset, size_t length)
{
assert(mFp == NULL); // no reopen
assert(mMap == NULL);
@ -363,15 +380,15 @@ status_t _FileAsset::openChunk(const char* fileName, int fd, off_t offset, size_
/*
* Seek to end to get file length.
*/
off_t fileLength;
fileLength = lseek(fd, 0, SEEK_END);
if (fileLength == (off_t) -1) {
off64_t fileLength;
fileLength = lseek64(fd, 0, SEEK_END);
if (fileLength == (off64_t) -1) {
// probably a bad file descriptor
LOGD("failed lseek (errno=%d)\n", errno);
return UNKNOWN_ERROR;
}
if ((off_t) (offset + length) > fileLength) {
if ((off64_t) (offset + length) > fileLength) {
LOGD("start (%ld) + len (%ld) > end (%ld)\n",
(long) offset, (long) length, (long) fileLength);
return BAD_INDEX;
@ -482,21 +499,21 @@ ssize_t _FileAsset::read(void* buf, size_t count)
/*
* Seek to a new position.
*/
off_t _FileAsset::seek(off_t offset, int whence)
off64_t _FileAsset::seek(off64_t offset, int whence)
{
off_t newPosn;
long actualOffset;
off64_t newPosn;
off64_t actualOffset;
// compute new position within chunk
newPosn = handleSeek(offset, whence, mOffset, mLength);
if (newPosn == (off_t) -1)
if (newPosn == (off64_t) -1)
return newPosn;
actualOffset = (long) (mStart + newPosn);
actualOffset = mStart + newPosn;
if (mFp != NULL) {
if (fseek(mFp, (long) actualOffset, SEEK_SET) != 0)
return (off_t) -1;
return (off64_t) -1;
}
mOffset = actualOffset - mStart;
@ -603,7 +620,7 @@ const void* _FileAsset::getBuffer(bool wordAligned)
}
}
int _FileAsset::openFileDescriptor(off_t* outStart, off_t* outLength) const
int _FileAsset::openFileDescriptor(off64_t* outStart, off64_t* outLength) const
{
if (mMap != NULL) {
const char* fname = mMap->getFileName();
@ -678,7 +695,7 @@ _CompressedAsset::~_CompressedAsset(void)
* This currently just sets up some values and returns. On the first
* read, we expand the entire file into a buffer and return data from it.
*/
status_t _CompressedAsset::openChunk(int fd, off_t offset,
status_t _CompressedAsset::openChunk(int fd, off64_t offset,
int compressionMethod, size_t uncompressedLen, size_t compressedLen)
{
assert(mFd < 0); // no re-open
@ -782,13 +799,13 @@ ssize_t _CompressedAsset::read(void* buf, size_t count)
* expensive, because it requires plowing through a bunch of compressed
* data.
*/
off_t _CompressedAsset::seek(off_t offset, int whence)
off64_t _CompressedAsset::seek(off64_t offset, int whence)
{
off_t newPosn;
off64_t newPosn;
// compute new position within chunk
newPosn = handleSeek(offset, whence, mOffset, mUncompressedLen);
if (newPosn == (off_t) -1)
if (newPosn == (off64_t) -1)
return newPosn;
if (mZipInflater) {

View file

@ -88,11 +88,12 @@ FileMap::~FileMap(void)
*
* Returns "false" on failure.
*/
bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t length, bool readOnly)
bool FileMap::create(const char* origFileName, int fd, off64_t offset, size_t length,
bool readOnly)
{
#ifdef HAVE_WIN32_FILEMAP
int adjust;
off_t adjOffset;
off64_t adjOffset;
size_t adjLength;
if (mPageSize == -1) {
@ -131,7 +132,7 @@ bool FileMap::create(const char* origFileName, int fd, off_t offset, size_t leng
#endif
#ifdef HAVE_POSIX_FILEMAP
int prot, flags, adjust;
off_t adjOffset;
off64_t adjOffset;
size_t adjLength;
void* ptr;

View file

@ -22,6 +22,8 @@
#include <unistd.h>
#define LOG_TAG "ObbFile"
#include <utils/Compat.h>
#include <utils/Log.h>
#include <utils/ObbFile.h>
@ -67,17 +69,6 @@
_rc; })
#endif
/*
* Work around situations where off_t is 64-bit and use off64_t in
* situations where it's 32-bit.
*/
#ifdef OFF_T_IS_64_BIT
#define my_lseek64 lseek
typedef off_t my_off64_t;
#else
#define my_lseek64 lseek64
typedef off64_t my_off64_t;
#endif
namespace android {
@ -125,7 +116,7 @@ bool ObbFile::readFrom(int fd)
bool ObbFile::parseObbFile(int fd)
{
my_off64_t fileLength = my_lseek64(fd, 0, SEEK_END);
off64_t fileLength = lseek64(fd, 0, SEEK_END);
if (fileLength < kFooterMinSize) {
if (fileLength < 0) {
@ -140,7 +131,7 @@ bool ObbFile::parseObbFile(int fd)
size_t footerSize;
{
my_lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
char *footer = new char[kFooterTagSize];
actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
@ -171,8 +162,8 @@ bool ObbFile::parseObbFile(int fd)
}
}
my_off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
if (my_lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
LOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
return false;
}
@ -211,10 +202,10 @@ bool ObbFile::parseObbFile(int fd)
memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
if (packageNameLen <= 0
size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
if (packageNameLen == 0
|| packageNameLen > (footerSize - kPackageNameOffset)) {
LOGW("bad ObbFile package name length (0x%04x; 0x%04x possible)\n",
LOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
packageNameLen, footerSize - kPackageNameOffset);
free(scanBuf);
return false;
@ -257,7 +248,7 @@ bool ObbFile::writeTo(int fd)
return false;
}
my_lseek64(fd, 0, SEEK_END);
lseek64(fd, 0, SEEK_END);
if (mPackageName.size() == 0 || mVersion == -1) {
LOGW("tried to write uninitialized ObbFile data\n");

View file

@ -31,7 +31,7 @@ using namespace android;
/*
* Streaming access to compressed asset data in an open fd
*/
StreamingZipInflater::StreamingZipInflater(int fd, off_t compDataStart,
StreamingZipInflater::StreamingZipInflater(int fd, off64_t compDataStart,
size_t uncompSize, size_t compSize) {
mFd = fd;
mDataMap = NULL;
@ -210,7 +210,7 @@ int StreamingZipInflater::readNextChunk() {
// seeking backwards requires uncompressing fom the beginning, so is very
// expensive. seeking forwards only requires uncompressing from the current
// position to the destination.
off_t StreamingZipInflater::seekAbsolute(off_t absoluteInputPosition) {
off64_t StreamingZipInflater::seekAbsolute(off64_t absoluteInputPosition) {
if (absoluteInputPosition < mOutCurPosition) {
// rewind and reprocess the data from the beginning
if (!mStreamNeedsInit) {

View file

@ -40,7 +40,7 @@ ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zipToken,
bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
int* pMethod, size_t* pUncompLen,
size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) {
ZipFileRO* zip = (ZipFileRO*)zipToken;
ZipEntryRO entry = (ZipEntryRO)entryToken;
return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,

View file

@ -146,7 +146,7 @@ status_t ZipFileRO::open(const char* zipFileName)
return NAME_NOT_FOUND;
}
mFileLength = lseek(fd, 0, SEEK_END);
mFileLength = lseek64(fd, 0, SEEK_END);
if (mFileLength < kEOCDLen) {
TEMP_FAILURE_RETRY(close(fd));
return UNKNOWN_ERROR;
@ -202,7 +202,7 @@ bool ZipFileRO::mapCentralDirectory(void)
/*
* Make sure this is a Zip archive.
*/
if (lseek(mFd, 0, SEEK_SET) != 0) {
if (lseek64(mFd, 0, SEEK_SET) != 0) {
LOGW("seek to start failed: %s", strerror(errno));
free(scanBuf);
return false;
@ -240,9 +240,9 @@ bool ZipFileRO::mapCentralDirectory(void)
*
* We start by pulling in the last part of the file.
*/
off_t searchStart = mFileLength - readAmount;
off64_t searchStart = mFileLength - readAmount;
if (lseek(mFd, searchStart, SEEK_SET) != searchStart) {
if (lseek64(mFd, searchStart, SEEK_SET) != searchStart) {
LOGW("seek %ld failed: %s\n", (long) searchStart, strerror(errno));
free(scanBuf);
return false;
@ -274,7 +274,7 @@ bool ZipFileRO::mapCentralDirectory(void)
return false;
}
off_t eocdOffset = searchStart + i;
off64_t eocdOffset = searchStart + i;
const unsigned char* eocdPtr = scanBuf + i;
assert(eocdOffset < mFileLength);
@ -473,7 +473,7 @@ ZipEntryRO ZipFileRO::findEntryByIndex(int idx) const
* appear to be bogus.
*/
bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
size_t* pCompLen, off64_t* pOffset, long* pModWhen, long* pCrc32) const
{
bool ret = false;
@ -489,7 +489,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
* so we can just subtract back from that.
*/
const unsigned char* ptr = (const unsigned char*) hashEntry.name;
off_t cdOffset = mDirectoryOffset;
off64_t cdOffset = mDirectoryOffset;
ptr -= kCDELen;
@ -536,12 +536,12 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
#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
* so we need to do an pread64() instead of a lseek64() + read() to
* guarantee atomicity across the processes with the shared file
* descriptors.
*/
ssize_t actual =
TEMP_FAILURE_RETRY(pread(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
TEMP_FAILURE_RETRY(pread64(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
if (actual != sizeof(lfhBuf)) {
LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
@ -556,17 +556,17 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
#else /* HAVE_PREAD */
/*
* For hosts don't have pread() we cannot guarantee atomic reads from
* For hosts don't have pread64() 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.
* calling lseek64() concurrently.
*/
{
AutoMutex _l(mFdLock);
if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
if (lseek64(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
return false;
}
@ -579,7 +579,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
if (get4LE(lfhBuf) != kLFHSignature) {
off_t actualOffset = lseek(mFd, 0, SEEK_CUR);
off64_t actualOffset = lseek64(mFd, 0, SEEK_CUR);
LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
"got: offset=" ZD " data=0x%08lx\n",
localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
@ -588,7 +588,7 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
#endif /* HAVE_PREAD */
off_t dataOffset = localHdrOffset + kLFHLen
off64_t dataOffset = localHdrOffset + kLFHLen
+ get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
if (dataOffset >= cdOffset) {
LOGW("bad data offset %ld in zip\n", (long) dataOffset);
@ -596,14 +596,14 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
}
/* check lengths */
if ((off_t)(dataOffset + compLen) > cdOffset) {
if ((off64_t)(dataOffset + compLen) > cdOffset) {
LOGW("bad compressed length in zip (%ld + " ZD " > %ld)\n",
(long) dataOffset, (ZD_TYPE) compLen, (long) cdOffset);
return false;
}
if (method == kCompressStored &&
(off_t)(dataOffset + uncompLen) > cdOffset)
(off64_t)(dataOffset + uncompLen) > cdOffset)
{
LOGE("ERROR: bad uncompressed length in zip (%ld + " ZD " > %ld)\n",
(long) dataOffset, (ZD_TYPE) uncompLen, (long) cdOffset);
@ -649,7 +649,7 @@ FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const
FileMap* newMap;
size_t compLen;
off_t offset;
off64_t offset;
if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
return NULL;
@ -679,7 +679,7 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
int method;
size_t uncompLen, compLen;
off_t offset;
off64_t offset;
const unsigned char* ptr;
getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
@ -739,7 +739,7 @@ bool ZipFileRO::uncompressEntry(ZipEntryRO entry, int fd) const
int method;
size_t uncompLen, compLen;
off_t offset;
off64_t offset;
const unsigned char* ptr;
getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);