summaryrefslogtreecommitdiffstats
path: root/main/apk-tools/0001-io-fix-corruption-of-big-files-on-mmap-write.patch
blob: 4261ce521f0f8f156540433e1c41ef077fc98a11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
From 67108bf07a67811ea91fc965f3f1592a4a70044e Mon Sep 17 00:00:00 2001
From: Timo Teras <timo.teras@iki.fi>
Date: Fri, 31 Jul 2009 10:50:15 +0300
Subject: [PATCH] io: fix corruption of big files on mmap write

remember to increment destination pointer; and munmap the proper
base address.
---
 src/io.c |   27 +++++++++++++--------------
 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;
 }
 
-- 
1.6.3.3