summaryrefslogtreecommitdiffstats
path: root/src/io.c
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-07-30 09:07:35 +0300
committerTimo Teras <timo.teras@iki.fi>2009-07-30 09:07:35 +0300
commit8e4075e6b1911679ae3da837b5f13fb85c8f01f5 (patch)
treeacf7959f6c590f7bb7dcbd6c49981690f08d397a /src/io.c
parent49420239c2269971dd09e60b2ded496136a775e7 (diff)
downloadapk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.tar.bz2
apk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.tar.xz
io: fix mmap writing to actually work
apparently it needs to have both PROT_READ and PROT_WRITE. and it needs to be MAP_SHARED for the writing to be effective. oh, and the data needs to be preallocated with ftruncate; otherwise, one gets SIGBUS.
Diffstat (limited to 'src/io.c')
-rw-r--r--src/io.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/io.c b/src/io.c
index c78cda8..0fa1f88 100644
--- a/src/io.c
+++ b/src/io.c
@@ -113,13 +113,15 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
apk_progress_cb cb, void *cb_ctx)
{
struct apk_istream *is = (struct apk_istream *) stream;
- unsigned char *buf;
+ unsigned char *buf = MAP_FAILED;
size_t bufsz, done = 0, r, togo, mmapped = 0;
bufsz = size;
- if (size > 256 * 1024) {
- buf = mmap(NULL, size, PROT_WRITE, 0, fd, 0);
- if (buf != NULL) {
+ 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;