io: use mmap to write archive entries to disk

avoids some copying and system calls.
cute-signatures
Timo Teras 2009-07-29 19:33:52 +03:00
parent 7b05eef61f
commit 2ff4059b9a
1 changed files with 28 additions and 11 deletions

View File

@ -114,15 +114,25 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
{ {
struct apk_istream *is = (struct apk_istream *) stream; struct apk_istream *is = (struct apk_istream *) stream;
unsigned char *buf; unsigned char *buf;
size_t bufsz, done = 0, r, togo; size_t bufsz, done = 0, r, togo, mmapped = 0;
bufsz = size; bufsz = size;
if (size > 256 * 1024) {
buf = mmap(NULL, size, PROT_WRITE, 0, fd, 0);
if (buf != NULL) {
mmapped = 1;
if (bufsz > 2*1024*1024)
bufsz = 2*1024*1024;
}
}
if (!mmapped) {
if (bufsz > 256*1024) if (bufsz > 256*1024)
bufsz = 256*1024; bufsz = 256*1024;
buf = malloc(bufsz); buf = malloc(bufsz);
if (buf == NULL) if (buf == NULL)
return -ENOMEM; return -ENOMEM;
}
while (done < size) { while (done < size) {
if (done != 0 && cb != NULL) if (done != 0 && cb != NULL)
@ -134,17 +144,24 @@ size_t apk_istream_splice(void *stream, int fd, size_t size,
r = is->read(is, buf, togo); r = is->read(is, buf, togo);
if (r < 0) if (r < 0)
goto err; goto err;
if (!mmapped) {
if (write(fd, buf, r) != r) { if (write(fd, buf, r) != r) {
if (r < 0) if (r < 0)
r = -errno; r = -errno;
goto err; goto err;
} }
}
done += r; done += r;
if (r != togo) if (r != togo)
break; break;
} }
r = done; r = done;
err: err:
if (mmapped)
munmap(buf, size);
else
free(buf); free(buf);
return r; return r;
} }