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
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
index cef7db4..a18294b 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/utils/Asset.cpp
@@ -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 @@
         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 @@
 {
     _FileAsset* pAsset;
     status_t result;
-    off_t length;
+    off64_t length;
     int fd;
 
     fd = open(fileName, O_RDONLY | O_BINARY);
@@ -132,12 +135,26 @@
      * 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 @@
 {
     _CompressedAsset* pAsset;
     status_t result;
-    off_t fileLen;
+    off64_t fileLen;
     bool scanResult;
     long offset;
     int method;
@@ -215,7 +232,7 @@
 /*
  * 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 @@
 /*
  * 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 @@
  *
  * 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 @@
         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 @@
  *
  * 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 @@
     /*
      * 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 @@
 /*
  * 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 @@
     }
 }
 
-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 @@
  * 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 @@
  * 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) {