Make ZipOS and Qemu work better

This change improves the dirstream library in a lot of respects,
especially for /zip/... files. Also turn off MAP_STACK on Aarch64
because Qemu seems to implement it differently than Linux and it's
probably responsible for a lot of mysterious crashes.
This commit is contained in:
Justine Tunney 2023-08-15 18:24:53 -07:00
parent 4658ae539f
commit 110559ce6a
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
48 changed files with 748 additions and 500 deletions

View file

@ -18,11 +18,10 @@
*/
#include "libc/assert.h"
#include "libc/calls/struct/iovec.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
#include "libc/zip.internal.h"
static size_t GetIovSize(const struct iovec *iov, size_t iovlen) {
size_t i, r;
@ -30,6 +29,29 @@ static size_t GetIovSize(const struct iovec *iov, size_t iovlen) {
return r;
}
static ssize_t __zipos_read_impl(struct ZiposHandle *h, const struct iovec *iov,
size_t iovlen, ssize_t opt_offset) {
int i;
int64_t b, x, y;
if (h->cfile == ZIPOS_SYNTHETIC_DIRECTORY ||
S_ISDIR(GetZipCfileMode(h->zipos->map + h->cfile))) {
return eisdir();
}
if (opt_offset == -1) {
x = y = h->pos;
} else {
x = y = opt_offset;
}
for (i = 0; i < iovlen && y < h->size; ++i, y += b) {
b = MIN(iov[i].iov_len, h->size - y);
if (b) memcpy(iov[i].iov_base, h->mem + y, b);
}
if (opt_offset == -1) {
h->pos = y;
}
return y - x;
}
/**
* Reads data from zip store object.
*
@ -39,14 +61,10 @@ static size_t GetIovSize(const struct iovec *iov, size_t iovlen) {
*/
ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov,
size_t iovlen, ssize_t opt_offset) {
size_t i, b, x, y;
ssize_t rc;
unassert(opt_offset >= 0 || opt_offset == -1);
pthread_mutex_lock(&h->lock);
x = y = opt_offset != -1 ? opt_offset : h->pos;
for (i = 0; i < iovlen && y < h->size; ++i, y += b) {
b = min(iov[i].iov_len, h->size - y);
if (b) memcpy(iov[i].iov_base, h->mem + y, b);
}
if (opt_offset == -1) h->pos = y;
rc = __zipos_read_impl(h, iov, iovlen, opt_offset);
pthread_mutex_unlock(&h->lock);
return y - x;
return rc;
}