summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-31 10:50:15 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-31 10:50:55 +0300
commit67108bf07a67811ea91fc965f3f1592a4a70044e (patch)
treef020cc21b7100152e7e10344d4df70d692ab83c4
parentfe43d8ab1d8aab0f0fba0a1ea6c0bf96c358478f (diff)
downloadapk-tools-67108bf07a67811ea91fc965f3f1592a4a70044e.tar.gz
apk-tools-67108bf07a67811ea91fc965f3f1592a4a70044e.tar.bz2
apk-tools-67108bf07a67811ea91fc965f3f1592a4a70044e.tar.xz
apk-tools-67108bf07a67811ea91fc965f3f1592a4a70044e.zip
io: fix corruption of big files on mmap write
remember to increment destination pointer; and munmap the proper base address.
-rw-r--r--src/io.c27
1 files changed, 13 insertions, 14 deletions
diff --git a/src/io.c b/src/io.c
index 18e89d3..3929ba1 100644
--- a/src/io.c
+++ b/src/io.c
@@ -114,21 +114,19 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
{
static void *splice_buffer = NULL;
struct apk_istream *is = (struct apk_istream *) stream;
- unsigned char *buf = MAP_FAILED;
- size_t bufsz, done = 0, r, togo, mmapped = 0;
+ unsigned char *buf, *mmapbase = MAP_FAILED;
+ size_t bufsz, done = 0, r, togo;
bufsz = size;
if (size > 128 * 1024) {
if (ftruncate(fd, size) == 0)
- buf = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0);
- if (buf != MAP_FAILED) {
- mmapped = 1;
- if (bufsz > 2*1024*1024)
- bufsz = 2*1024*1024;
- }
+ mmapbase = mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (bufsz > 2*1024*1024)
+ bufsz = 2*1024*1024;
+ buf = mmapbase;
}
- if (!mmapped) {
+ if (mmapbase == MAP_FAILED) {
if (splice_buffer == NULL)
splice_buffer = malloc(256*1024);
buf = splice_buffer;
@@ -149,13 +147,14 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
if (r < 0)
goto err;
- if (!mmapped) {
+ if (mmapbase == MAP_FAILED) {
if (write(fd, buf, r) != r) {
if (r < 0)
r = -errno;
goto err;
}
- }
+ } else
+ buf += r;
done += r;
if (r != togo)
@@ -163,8 +162,8 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
}
r = done;
err:
- if (mmapped)
- munmap(buf, size);
+ if (mmapbase != MAP_FAILED)
+ munmap(mmapbase, size);
return r;
}