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:
parent
1d618d63c1
commit
e2fa7dc58e
13 changed files with 172 additions and 117 deletions
|
@ -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
42
include/utils/Compat.h
Normal 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 */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue