diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-07-30 09:07:35 +0300 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-07-30 09:07:35 +0300 |
commit | 8e4075e6b1911679ae3da837b5f13fb85c8f01f5 (patch) | |
tree | acf7959f6c590f7bb7dcbd6c49981690f08d397a /src | |
parent | 49420239c2269971dd09e60b2ded496136a775e7 (diff) | |
download | apk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.tar.gz apk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.tar.bz2 apk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.tar.xz apk-tools-8e4075e6b1911679ae3da837b5f13fb85c8f01f5.zip |
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')
-rw-r--r-- | src/archive.c | 2 | ||||
-rw-r--r-- | src/io.c | 10 |
2 files changed, 7 insertions, 5 deletions
diff --git a/src/archive.c b/src/archive.c index dca99fd..31c0909 100644 --- a/src/archive.c +++ b/src/archive.c @@ -331,7 +331,7 @@ int apk_archive_entry_extract(const struct apk_file_info *ae, break; case S_IFREG: if (ae->link_target == NULL) { - fd = open(fn, O_WRONLY | O_CREAT, ae->mode & 07777); + fd = open(fn, O_RDWR | O_CREAT, ae->mode & 07777); if (fd < 0) { r = -1; break; @@ -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; |