/* * Copy the given number of bytes from one fd to another, first * seeking the source fd to the start of the file. */ static int copyFileToFile(int destFd, int srcFd, size_t size) { if (lseek(srcFd, 0, SEEK_SET) != 0) { ALOGE("lseek failure: %s", strerror(errno)); return -1; } return sysCopyFileToFile(destFd, srcFd, size); }
/* * Uncompress an entry, in its entirety, to an open file descriptor. * * TODO: this doesn't verify the data's CRC, but probably should (especially * for uncompressed data). */ int dexZipExtractEntryToFile(const ZipArchive* pArchive, const ZipEntry entry, int fd) { int result = -1; int ent = entryToIndex(pArchive, entry); if (ent < 0) { LOGW("Zip: extract can't find entry %p", entry); goto bail; } int method; size_t uncompLen, compLen; off_t dataOffset; if (dexZipGetEntryInfo(pArchive, entry, &method, &uncompLen, &compLen, &dataOffset, NULL, NULL) != 0) { goto bail; } if (lseek(pArchive->mFd, dataOffset, SEEK_SET) != dataOffset) { LOGW("Zip: lseek to data at %ld failed", (long) dataOffset); goto bail; } if (method == kCompressStored) { if (sysCopyFileToFile(fd, pArchive->mFd, uncompLen) != 0) goto bail; } else { if (inflateToFile(fd, pArchive->mFd, uncompLen, compLen) != 0) goto bail; } result = 0; bail: return result; }