summaryrefslogtreecommitdiffstats
path: root/libziparchive
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2013-12-11 14:51:51 +0000
committerNarayan Kamath <narayan@google.com>2013-12-11 15:17:06 +0000
commiteaf988532b9e603b1599b7750bfa923fbb39d297 (patch)
treeb6043dc218a8e3f71bafd58da02361c5c2414038 /libziparchive
parenta183f45f7aaee721a9c1cde14cdd47e47a1592e4 (diff)
downloadsystem_core-eaf988532b9e603b1599b7750bfa923fbb39d297.zip
system_core-eaf988532b9e603b1599b7750bfa923fbb39d297.tar.gz
system_core-eaf988532b9e603b1599b7750bfa923fbb39d297.tar.bz2
Use FileMap from libcutil instead of rolling our own.
Adds windows support as a side effect. Change-Id: I912c1f980f284d01d4f3936291999646ddf6250a
Diffstat (limited to 'libziparchive')
-rw-r--r--libziparchive/Android.mk8
-rw-r--r--libziparchive/zip_archive.cc110
2 files changed, 43 insertions, 75 deletions
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index d783747..5d836a1 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -26,6 +26,7 @@ LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := ${source_files}
LOCAL_STATIC_LIBRARIES := libz
+LOCAL_SHARED_LIBRARIES := libutils
LOCAL_MODULE:= libziparchive
LOCAL_C_INCLUDES += ${includes}
@@ -37,7 +38,7 @@ LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := ${source_files}
LOCAL_C_INCLUDES += ${includes}
-LOCAL_STATIC_LIBRARIES := libz
+LOCAL_STATIC_LIBRARIES := libz libutils
LOCAL_MODULE:= libziparchive-host
include $(BUILD_HOST_STATIC_LIBRARY)
@@ -49,7 +50,7 @@ LOCAL_CFLAGS += \
-DGTEST_HAS_STD_STRING
LOCAL_SRC_FILES := zip_archive_test.cc
LOCAL_LDFLAGS := -llog
-LOCAL_STATIC_LIBRARIES := libziparchive libz libgtest libgtest_main
+LOCAL_STATIC_LIBRARIES := libziparchive libz libgtest libgtest_main libutils
include $(BUILD_NATIVE_TEST)
include $(CLEAR_VARS)
@@ -63,5 +64,6 @@ LOCAL_STATIC_LIBRARIES := libziparchive-host \
libz \
libgtest_host \
libgtest_main_host \
- liblog
+ liblog \
+ libutils
include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 43312b4..4143fac 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -28,8 +28,8 @@
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/mman.h>
#include <unistd.h>
+#include <utils/FileMap.h>
#include <JNIHelp.h> // TEMP_FAILURE_RETRY may or may not be in unistd
@@ -97,6 +97,7 @@ static const char* kErrorMessages[] = {
"Inconsistent information",
"Invalid entry name",
"I/O Error",
+ "File mapping failed"
};
static const int32_t kErrorMessageUpperBound = 0;
@@ -140,22 +141,12 @@ static const int32_t kInvalidEntryName = -10;
// An I/O related system call (read, lseek, ftruncate, map) failed.
static const int32_t kIoError = -11;
-static const int32_t kErrorMessageLowerBound = -12;
+// We were not able to mmap the central directory or entry contents.
+static const int32_t kMmapFailed = -12;
+static const int32_t kErrorMessageLowerBound = -13;
-#ifdef PAGE_SHIFT
-#define SYSTEM_PAGE_SIZE (1 << PAGE_SHIFT)
-#else
-#define SYSTEM_PAGE_SIZE 4096
-#endif
-
-struct MemMapping {
- uint8_t* addr; // Start of data
- size_t length; // Length of data
-
- uint8_t* base_address; // page-aligned base address
- size_t base_length; // length of mapping
-};
+static const char kTempMappingFileName[] = "zip: ExtractFileToFile";
/*
* A Read-only Zip archive.
@@ -182,7 +173,7 @@ struct ZipArchive {
/* mapped central directory area */
off64_t directory_offset;
- MemMapping directory_map;
+ android::FileMap* directory_map;
/* number of entries in the Zip archive */
uint16_t num_entries;
@@ -198,43 +189,17 @@ struct ZipArchive {
};
// Returns 0 on success and negative values on failure.
-static int32_t MapFileSegment(const int fd, const off64_t start, const size_t length,
- const int prot, const int flags, MemMapping *mapping) {
- /* adjust to be page-aligned */
- const int adjust = start % SYSTEM_PAGE_SIZE;
- const off64_t actual_start = start - adjust;
- const off64_t actual_length = length + adjust;
-
- void* map_addr = mmap(NULL, actual_length, prot, flags, fd, actual_start);
- if (map_addr == MAP_FAILED) {
- ALOGW("mmap(%llx, R, FILE|SHARED, %d, %llx) failed: %s",
- actual_length, fd, actual_start, strerror(errno));
- return kIoError;
+static android::FileMap* MapFileSegment(const int fd, const off64_t start,
+ const size_t length, const bool read_only,
+ const char* debug_file_name) {
+ android::FileMap* file_map = new android::FileMap;
+ const bool success = file_map->create(debug_file_name, fd, start, length, read_only);
+ if (!success) {
+ file_map->release();
+ return NULL;
}
- mapping->base_address = (uint8_t*) map_addr;
- mapping->base_length = actual_length;
- mapping->addr = (uint8_t*) map_addr + adjust;
- mapping->length = length;
-
- ALOGV("mmap seg (st=%d ln=%d): b=%p bl=%d ad=%p ln=%d",
- start, length, mapping->base_address, mapping->base_length,
- mapping->addr, mapping->length);
-
- return 0;
-}
-
-static void ReleaseMappedSegment(MemMapping* map) {
- if (map->base_address == 0 || map->base_length == 0) {
- return;
- }
-
- if (munmap(map->base_address, map->base_length) < 0) {
- ALOGW("munmap(%p, %d) failed: %s",
- map->base_address, map->base_length, strerror(errno));
- } else {
- ALOGV("munmap(%p, %d) succeeded", map->base_address, map->base_length);
- }
+ return file_map;
}
static int32_t CopyFileToFile(int fd, uint8_t* begin, const uint32_t length, uint64_t *crc_out) {
@@ -430,13 +395,14 @@ static int32_t MapCentralDirectory0(int fd, const char* debug_file_name,
* It all looks good. Create a mapping for the CD, and set the fields
* in archive.
*/
- const int32_t result = MapFileSegment(fd, dir_offset, dir_size,
- PROT_READ, MAP_FILE | MAP_SHARED,
- &(archive->directory_map));
- if (result) {
- return result;
+ android::FileMap* map = MapFileSegment(fd, dir_offset, dir_size,
+ true /* read only */, debug_file_name);
+ if (map == NULL) {
+ archive->directory_map = NULL;
+ return kMmapFailed;
}
+ archive->directory_map = map;
archive->num_entries = num_entries;
archive->directory_offset = dir_offset;
@@ -506,8 +472,8 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name,
*/
static int32_t ParseZipArchive(ZipArchive* archive) {
int32_t result = -1;
- const uint8_t* cd_ptr = (const uint8_t*) archive->directory_map.addr;
- size_t cd_length = archive->directory_map.length;
+ const uint8_t* cd_ptr = (const uint8_t*) archive->directory_map->getDataPtr();
+ size_t cd_length = archive->directory_map->getDataLength();
uint16_t num_entries = archive->num_entries;
/*
@@ -621,7 +587,9 @@ void CloseArchive(ZipArchiveHandle handle) {
close(archive->fd);
}
- ReleaseMappedSegment(&archive->directory_map);
+ if (archive->directory_map != NULL) {
+ archive->directory_map->release();
+ }
free(archive->hash_table);
/* ensure nobody tries to use the ZipArchive after it's closed */
@@ -668,7 +636,7 @@ static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len,
// is Windows. Only recent versions of windows support unix like forks,
// and even there the semantics are quite different.
if (lseek64(fd, off, SEEK_SET) != off) {
- ALOGW("Zip: failed seek to offset %lld", name_offset);
+ ALOGW("Zip: failed seek to offset %lld", off);
return kIoError;
}
@@ -691,8 +659,8 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent,
// the name that's in the hash table is a pointer to a location within
// this mapped region.
const unsigned char* base_ptr = (const unsigned char*)
- archive->directory_map.addr;
- if (ptr < base_ptr || ptr > base_ptr + archive->directory_map.length) {
+ archive->directory_map->getDataPtr();
+ if (ptr < base_ptr || ptr > base_ptr + archive->directory_map->getDataLength()) {
ALOGW("Zip: Invalid entry pointer");
return kInvalidOffset;
}
@@ -1045,18 +1013,16 @@ int32_t ExtractEntryToFile(ZipArchiveHandle handle,
return kIoError;
}
- MemMapping mapping;
- int32_t error = MapFileSegment(fd, 0, declared_length,
- PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_SHARED,
- &mapping);
- if (error) {
- return error;
+ android::FileMap* map = MapFileSegment(fd, 0, declared_length,
+ false, kTempMappingFileName);
+ if (map == NULL) {
+ return kMmapFailed;
}
- error = ExtractToMemory(handle, entry, mapping.addr,
- mapping.length);
- ReleaseMappedSegment(&mapping);
+ const int32_t error = ExtractToMemory(handle, entry,
+ reinterpret_cast<uint8_t*>(map->getDataPtr()),
+ map->getDataLength());
+ map->release();
return error;
}