am 683c462
: align data passed to write() on 32k boundaries
Merge commit '683c4628039a8cb6dad1a086fae23a7d71438414' * commit '683c4628039a8cb6dad1a086fae23a7d71438414': align data passed to write() on 32k boundaries
This commit is contained in:
commit
1c10ff34b5
2 changed files with 55 additions and 17 deletions
62
minzip/Zip.c
62
minzip/Zip.c
|
@ -12,6 +12,7 @@
|
|||
#include <stdint.h> // for uintptr_t
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h> // for S_ISLNK()
|
||||
#include <sys/statfs.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define LOG_TAG "minzip"
|
||||
|
@ -84,6 +85,12 @@ enum {
|
|||
};
|
||||
|
||||
|
||||
/* The maximum zipped file write size we will align. */
|
||||
#define WRITE_SIZE 32768
|
||||
/* The boundary on which we will align it. */
|
||||
#define WRITE_ALIGNMENT 32768
|
||||
|
||||
|
||||
/*
|
||||
* For debugging, dump the contents of a ZipEntry.
|
||||
*/
|
||||
|
@ -770,17 +777,38 @@ bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
|
|||
}
|
||||
|
||||
static bool writeProcessFunction(const unsigned char *data, int dataLen,
|
||||
void *fd)
|
||||
void *cookie)
|
||||
{
|
||||
int zeroWrites = 0;
|
||||
WriteInfo *wi = (WriteInfo*)cookie;
|
||||
|
||||
if (dataLen <= WRITE_SIZE) {
|
||||
memcpy(wi->aligned_buffer, data, dataLen);
|
||||
data = wi->aligned_buffer;
|
||||
}
|
||||
|
||||
ssize_t soFar = 0;
|
||||
do {
|
||||
ssize_t n = write((int)fd, data+soFar, dataLen-soFar);
|
||||
if (n < 0) {
|
||||
LOGE("Error writing %ld bytes from zip file: %s\n",
|
||||
dataLen-soFar, strerror(errno));
|
||||
while (true) {
|
||||
ssize_t n = write(wi->fd, data+soFar, dataLen-soFar);
|
||||
if (n <= 0) {
|
||||
LOGE("Error writing %ld bytes from zip file from %p: %s\n",
|
||||
dataLen-soFar, data+soFar, strerror(errno));
|
||||
if (errno == ENOSPC) {
|
||||
struct statfs sf;
|
||||
if (statfs("/system", &sf) != 0) {
|
||||
LOGE("failed to statfs /system: %s\n", strerror(errno));
|
||||
} else {
|
||||
LOGE("statfs said: %ld * %ld = %ld\n",
|
||||
(long)sf.f_bsize, (long)sf.f_bfree,
|
||||
(long)sf.f_bsize * (long)sf.f_bfree);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (n > 0) {
|
||||
if (n < dataLen-soFar) {
|
||||
LOGE("short write: %d bytes of %d from %p\n",
|
||||
(int)n, (int)(dataLen-soFar),
|
||||
data+soFar);
|
||||
}
|
||||
soFar += n;
|
||||
if (soFar == dataLen) return true;
|
||||
if (soFar > dataLen) {
|
||||
|
@ -788,23 +816,18 @@ static bool writeProcessFunction(const unsigned char *data, int dataLen,
|
|||
soFar, dataLen);
|
||||
return false;
|
||||
}
|
||||
zeroWrites = 0;
|
||||
} else {
|
||||
++zeroWrites;
|
||||
}
|
||||
} while (zeroWrites < 5);
|
||||
LOGE("too many consecutive zero-length writes\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Uncompress "pEntry" in "pArchive" to "fd" at the current offset.
|
||||
*/
|
||||
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
|
||||
const ZipEntry *pEntry, int fd)
|
||||
const ZipEntry *pEntry, WriteInfo *wi)
|
||||
{
|
||||
bool ret = mzProcessZipEntryContents(pArchive, pEntry, writeProcessFunction,
|
||||
(void *)fd);
|
||||
wi);
|
||||
if (!ret) {
|
||||
LOGE("Can't extract entry to file.\n");
|
||||
return false;
|
||||
|
@ -906,6 +929,11 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
|
|||
return false;
|
||||
}
|
||||
|
||||
unsigned char* buffer = malloc(WRITE_SIZE+WRITE_ALIGNMENT);
|
||||
WriteInfo wi;
|
||||
wi.aligned_buffer = buffer + WRITE_ALIGNMENT -
|
||||
((long)buffer % WRITE_ALIGNMENT);
|
||||
|
||||
unsigned int zipDirLen;
|
||||
char *zpath;
|
||||
|
||||
|
@ -1086,7 +1114,8 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
|
|||
break;
|
||||
}
|
||||
|
||||
bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd);
|
||||
wi.fd = fd;
|
||||
bool ok = mzExtractZipEntryToFile(pArchive, pEntry, &wi);
|
||||
close(fd);
|
||||
if (!ok) {
|
||||
LOGE("Error extracting \"%s\"\n", targetFile);
|
||||
|
@ -1109,6 +1138,7 @@ bool mzExtractRecursive(const ZipArchive *pArchive,
|
|||
|
||||
free(helper.buf);
|
||||
free(zpath);
|
||||
free(buffer);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
10
minzip/Zip.h
10
minzip/Zip.h
|
@ -55,6 +55,14 @@ typedef struct {
|
|||
size_t len;
|
||||
} UnterminatedString;
|
||||
|
||||
/*
|
||||
* The information we pass down to writeProcessFunction.
|
||||
*/
|
||||
typedef struct {
|
||||
int fd;
|
||||
unsigned char* aligned_buffer;
|
||||
} WriteInfo;
|
||||
|
||||
/*
|
||||
* Open a Zip archive.
|
||||
*
|
||||
|
@ -166,7 +174,7 @@ bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
|
|||
* Inflate and write an entry to a file.
|
||||
*/
|
||||
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
|
||||
const ZipEntry *pEntry, int fd);
|
||||
const ZipEntry *pEntry, WriteInfo *wi);
|
||||
|
||||
/*
|
||||
* Inflate all entries under zipDir to the directory specified by
|
||||
|
|
Loading…
Reference in a new issue