Move zipos into runtime package

This way complex runtime features (e.g. ftrace, symbol tables) can
always yoink zipos support. This is important now that apelink.com
automates embedding symbol tables for multiple cpus.
This commit is contained in:
Justine Tunney 2023-08-11 23:14:02 -07:00
parent d53c335a45
commit e11fa30791
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
90 changed files with 133 additions and 289 deletions

0
libc/runtime/.cosmo Normal file
View file

View file

@ -21,6 +21,8 @@
#include "libc/str/str.h"
#include "libc/thread/tls.h"
__static_yoink("zipos");
/**
* Enables plaintext function tracing if `--ftrace` flag is passed.
*

View file

@ -29,7 +29,7 @@
#include "libc/thread/thread.h"
#include "libc/x/x.h"
#include "libc/zip.internal.h"
#include "libc/zipos/zipos.internal.h"
#include "libc/runtime/zipos.internal.h"
#include "third_party/puff/puff.h"
__static_yoink("__get_symbol");

View file

@ -43,6 +43,7 @@
#include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/stdckdint.h"
#include "libc/stdio/rand.h"
#include "libc/str/str.h"

View file

@ -26,7 +26,8 @@ LIBC_RUNTIME_A_SRCS = \
LIBC_RUNTIME_A_OBJS = \
$(LIBC_RUNTIME_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(LIBC_RUNTIME_A_SRCS_C:%.c=o/$(MODE)/%.o)
$(LIBC_RUNTIME_A_SRCS_C:%.c=o/$(MODE)/%.o) \
o/$(MODE)/libc/runtime/.cosmo.zip.o
LIBC_RUNTIME_A_CHECKS = \
$(LIBC_RUNTIME_A).pkg \
@ -138,6 +139,10 @@ o/$(MODE)/libc/runtime/clone.o: private \
-fno-sanitize=all \
-fpatchable-function-entry=0,0
o/$(MODE)/libc/runtime/.cosmo.zip.o: private \
ZIPOBJ_FLAGS += \
-B
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/runtime/init.o: libc/runtime/init.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
@ -151,6 +156,8 @@ o/$(MODE)/libc/runtime/ftrace-hook.o: libc/runtime/ftrace-hook.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/runtime/dsohandle.o: libc/runtime/dsohandle.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/runtime/zipos.o: libc/runtime/zipos.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_RUNTIME_LIBS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)))
LIBC_RUNTIME_SRCS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_SRCS))

View file

@ -0,0 +1,67 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/errfuns.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
// TODO: this should check parent directory components
/**
* Checks access metadata in αcτµαlly pδrταblε εxεcµταblε object store.
*
* @param uri is obtained via __zipos_parseuri()
* @asyncsignalsafe
*/
int __zipos_access(const struct ZiposUri *name, int amode) {
ssize_t cf;
int rc, mode;
struct Zipos *z;
if ((z = __zipos_get()) && (cf = __zipos_find(z, name)) != -1) {
mode = GetZipCfileMode(z->map + cf);
if (amode == F_OK) {
rc = 0;
} else if (amode == R_OK) {
if (mode & 0444) {
rc = 0;
} else {
rc = eacces();
}
} else if (amode == W_OK) {
if (mode & 0222) {
rc = 0;
} else {
rc = eacces();
}
} else if (amode == X_OK) {
if (mode & 0111) {
rc = 0;
} else {
rc = eacces();
}
} else {
rc = einval();
}
} else {
rc = enoent();
}
return rc;
}

View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/runtime/zipos.internal.h"
/**
* Closes compressed object.
*
* @param fd is vetted by close()
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int __zipos_close(int fd) {
int rc;
struct ZiposHandle *h;
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
if (!IsWindows()) {
rc = sys_close(fd);
} else {
rc = 0; /* no system file descriptor needed on nt */
}
if (!__vforked) {
__zipos_free(__zipos_get(), h);
}
return rc;
}

View file

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
#define ZIPOS __zipos_get()
#define HANDLE ((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle)
int __zipos_fcntl(int fd, int cmd, uintptr_t arg) {
int rc;
if (cmd == F_GETFD) {
if (g_fds.p[fd].flags & O_CLOEXEC) {
rc = FD_CLOEXEC;
} else {
rc = 0;
}
} else if (cmd == F_SETFD) {
if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC;
rc = FD_CLOEXEC;
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
rc = 0;
}
} else {
rc = einval();
}
return rc;
}

54
libc/runtime/zipos-find.c Normal file
View file

@ -0,0 +1,54 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "ape/relocations.h"
#include "libc/assert.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
// TODO(jart): improve time complexity here
ssize_t __zipos_find(struct Zipos *zipos, const struct ZiposUri *name) {
const char *zname;
size_t i, n, c, znamesize;
if (!name->len) {
return 0;
}
c = GetZipCdirOffset(zipos->cdir);
n = GetZipCdirRecords(zipos->cdir);
for (i = 0; i < n; ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) {
npassert(ZIP_CFILE_MAGIC(zipos->map + c) == kZipCfileHdrMagic);
zname = ZIP_CFILE_NAME(zipos->map + c);
znamesize = ZIP_CFILE_NAMESIZE(zipos->map + c);
if ((name->len == znamesize && !memcmp(name->path, zname, name->len)) ||
(name->len + 1 == znamesize && !memcmp(name->path, zname, name->len) &&
zname[name->len] == '/')) {
return c;
} else if ((name->len < znamesize &&
!memcmp(name->path, zname, name->len) &&
zname[name->len - 1] == '/') ||
(name->len + 1 < znamesize &&
!memcmp(name->path, zname, name->len) &&
zname[name->len] == '/')) {
return 0;
}
}
return -1;
}

37
libc/runtime/zipos-free.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
#include "libc/runtime/zipos.internal.h"
void __zipos_free(struct Zipos *z, struct ZiposHandle *h) {
if (IsAsan()) {
__asan_poison((char *)h + sizeof(struct ZiposHandle),
h->mapsize - sizeof(struct ZiposHandle), kAsanHeapFree);
}
pthread_mutex_destroy(&h->lock);
__zipos_lock();
do h->next = z->freelist;
while (!_cmpxchg(&z->freelist, h->next, h));
__zipos_unlock();
}

View file

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/sysv/errfuns.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
/**
* Reads file metadata from αcτµαlly pδrταblε εxεcµταblε object store.
*
* @param uri is obtained via __zipos_parseuri()
* @asyncsignalsafe
*/
int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) {
int rc;
if (st) {
rc = __zipos_stat_impl(__zipos_get(), h->cfile, st);
} else {
rc = efault();
}
return rc;
}

120
libc/runtime/zipos-get.c Normal file
View file

@ -0,0 +1,120 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/promises.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/thread/thread.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
#ifdef __x86_64__
__static_yoink(APE_COM_NAME);
#endif
static uint64_t __zipos_get_min_offset(const uint8_t *base,
const uint8_t *cdir) {
uint64_t i, n, c, r, o;
c = GetZipCdirOffset(cdir);
n = GetZipCdirRecords(cdir);
for (r = c, i = 0; i < n; ++i, c += ZIP_CFILE_HDRSIZE(base + c)) {
o = GetZipCfileOffset(base + c);
if (o < r) r = o;
}
return r;
}
static void __zipos_munmap_unneeded(const uint8_t *base, const uint8_t *cdir,
const uint8_t *map) {
uint64_t n;
n = __zipos_get_min_offset(base, cdir);
n += base - map;
n = ROUNDDOWN(n, FRAMESIZE);
if (n) munmap(map, n);
}
/**
* Returns pointer to zip central directory of current executable.
* @asyncsignalsafe
* @threadsafe
*/
struct Zipos *__zipos_get(void) {
char *endptr;
ssize_t size;
int fd, err, msg;
static bool once;
struct Zipos *res;
uint8_t *map, *cdir;
const char *progpath;
static struct Zipos zipos;
__zipos_lock();
if (!once) {
progpath = getenv("COSMOPOLITAN_INIT_ZIPOS");
if (progpath) {
fd = strtol(progpath, &endptr, 10);
if (*endptr) fd = -1;
} else {
fd = -1;
}
if (fd != -1 || PLEDGED(RPATH)) {
if (fd == -1) {
progpath = GetProgramExecutableName();
fd = open(progpath, O_RDONLY);
}
if (fd != -1) {
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
(map = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) !=
MAP_FAILED) {
if ((cdir = GetZipEocd(map, size, &err))) {
__zipos_munmap_unneeded(map, cdir, map);
zipos.map = map;
zipos.cdir = cdir;
msg = kZipOk;
} else {
munmap(map, size);
msg = !cdir ? err : kZipErrorRaceCondition;
}
} else {
msg = kZipErrorMapFailed;
}
close(fd);
} else {
msg = kZipErrorOpenFailed;
}
} else {
msg = -666;
}
STRACE("__zipos_get(%#s) → %d% m", progpath, msg);
once = true;
}
__zipos_unlock();
if (zipos.cdir) {
res = &zipos;
} else {
res = 0;
}
return res;
}

39
libc/runtime/zipos-lock.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/thread/thread.h"
#include "libc/runtime/zipos.internal.h"
static pthread_mutex_t __zipos_lock_obj;
void(__zipos_lock)(void) {
pthread_mutex_lock(&__zipos_lock_obj);
}
void(__zipos_unlock)(void) {
pthread_mutex_unlock(&__zipos_lock_obj);
}
void __zipos_funlock(void) {
pthread_mutex_init(&__zipos_lock_obj, 0);
}
__attribute__((__constructor__)) static void __zipos_init(void) {
__zipos_funlock();
pthread_atfork(__zipos_lock, __zipos_unlock, __zipos_funlock);
}

View file

@ -0,0 +1,57 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
/**
* Changes current position of zip file handle.
*
* @param offset is the relative byte count
* @param whence can be SEEK_SET, SEEK_CUR, or SEEK_END
* @return new position relative to beginning, or -1 on error
* @asyncsignalsafe
*/
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
int64_t rc;
pthread_mutex_lock(&h->lock);
switch (whence) {
case SEEK_SET:
rc = offset;
break;
case SEEK_CUR:
rc = h->pos + offset;
break;
case SEEK_END:
rc = h->size - offset;
break;
default:
rc = -1;
break;
}
if (rc >= 0) {
h->pos = rc;
} else {
rc = einval();
}
pthread_mutex_unlock(&h->lock);
return rc;
}

90
libc/runtime/zipos-mmap.c Normal file
View file

@ -0,0 +1,90 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/zipos.internal.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.h"
#define IP(X) (intptr_t)(X)
#define VIP(X) (void *)IP(X)
/**
* Map zipos file into memory. See mmap.
*
* @param addr should be 0 or a compatible address
* @param size must be >0 and will be rounded up to FRAMESIZE
* automatically.
* @param prot can have PROT_READ/PROT_WRITE/PROT_EXEC/PROT_NONE/etc.
* @param flags cannot have `MAP_SHARED` or `MAP_ANONYMOUS`, there is
* no actual file backing for zipos files. `MAP_SHARED` could be
* simulated for non-writable mappings, but that would require
* tracking zipos mappings to prevent making it PROT_WRITE.
* @param h is a zip store object
* @param off specifies absolute byte index of h's file for mapping,
* it does not need to be 64kb aligned.
* @return virtual base address of new mapping, or MAP_FAILED w/ errno
*/
dontasan void *__zipos_Mmap(void *addr, size_t size, int prot, int flags,
struct ZiposHandle *h, int64_t off) {
if (!(flags & MAP_PRIVATE) ||
(flags & ~(MAP_PRIVATE | MAP_FILE | MAP_FIXED | MAP_FIXED_NOREPLACE)) ||
(!!(flags & MAP_FIXED) ^ !!(flags & MAP_FIXED_NOREPLACE))) {
STRACE(
"zipos mappings currently only support MAP_PRIVATE with select flags");
return VIP(einval());
}
if (VERY_UNLIKELY(off < 0)) {
STRACE("neg off");
return VIP(einval());
}
const int tempProt = !IsXnu() ? prot | PROT_WRITE : PROT_WRITE;
void *outAddr =
_Mmap(addr, size, tempProt, (flags & (~MAP_FILE)) | MAP_ANONYMOUS, -1, 0);
if (outAddr == MAP_FAILED) {
return MAP_FAILED;
}
do {
if (__zipos_read(h, &(struct iovec){outAddr, size}, 1, off) == -1) {
strace_enabled(-1);
break;
} else if (prot != tempProt) {
strace_enabled(-1);
if (mprotect(outAddr, size, prot) == -1) {
break;
}
strace_enabled(+1);
}
return outAddr;
} while (0);
const int e = errno;
_Munmap(outAddr, size);
errno = e;
strace_enabled(+1);
return MAP_FAILED;
}

View file

@ -0,0 +1,30 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/sysv/errfuns.h"
#include "libc/runtime/zipos.internal.h"
int __zipos_notat(int dirfd, const char *path) {
struct ZiposUri zipname;
if (!path) return efault();
if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) {
return einval();
}
return 0;
}

222
libc/runtime/zipos-open.c Normal file
View file

@ -0,0 +1,222 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/directmap.internal.h"
#include "libc/intrin/extend.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
static char *mapend;
static size_t maptotal;
static void *__zipos_mmap_space(size_t mapsize) {
char *start;
size_t offset;
unassert(mapsize);
offset = maptotal;
maptotal += mapsize;
start = (char *)kMemtrackZiposStart;
if (!mapend) mapend = start;
mapend = _extend(start, maptotal, mapend, MAP_PRIVATE,
kMemtrackZiposStart + kMemtrackZiposSize);
return start + offset;
}
static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) {
size_t mapsize;
struct ZiposHandle *h, **ph;
__zipos_lock();
mapsize = sizeof(struct ZiposHandle) + size;
mapsize = ROUNDUP(mapsize, 4096);
StartOver:
ph = &zipos->freelist;
while ((h = *ph)) {
if (h->mapsize >= mapsize) {
if (!_cmpxchg(ph, h, h->next)) goto StartOver;
h->next = 0;
break;
}
ph = &h->next;
}
if (!h) {
h = __zipos_mmap_space(mapsize);
}
__zipos_unlock();
if (IsAsan()) {
__asan_unpoison((char *)h, sizeof(struct ZiposHandle) + size);
__asan_poison((char *)h + sizeof(struct ZiposHandle) + size,
mapsize - (sizeof(struct ZiposHandle) + size),
kAsanHeapOverrun);
}
if (h) {
h->size = size;
h->mapsize = mapsize;
pthread_mutex_init(&h->lock, 0);
}
return h;
}
static int __zipos_mkfd(int minfd) {
int e, fd;
static bool demodernize;
if (!demodernize) {
e = errno;
if ((fd = __sys_fcntl(2, F_DUPFD_CLOEXEC, minfd)) != -1) {
return fd;
} else if (errno == EINVAL) {
demodernize = true;
errno = e;
} else {
return fd;
}
}
if ((fd = __sys_fcntl(2, F_DUPFD, minfd)) != -1) {
__sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
}
return fd;
}
static int __zipos_setfd(int fd, struct ZiposHandle *h, unsigned flags,
int mode) {
int want = fd;
atomic_compare_exchange_strong_explicit(
&g_fds.f, &want, fd + 1, memory_order_release, memory_order_relaxed);
g_fds.p[fd].kind = kFdZip;
g_fds.p[fd].handle = (intptr_t)h;
g_fds.p[fd].flags = flags | O_CLOEXEC;
g_fds.p[fd].mode = mode;
g_fds.p[fd].extra = 0;
__fds_unlock();
return fd;
}
static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
int mode) {
size_t lf;
size_t size;
int rc, fd, minfd;
struct ZiposHandle *h;
lf = GetZipCfileOffset(zipos->map + cf);
npassert((ZIP_LFILE_MAGIC(zipos->map + lf) == kZipLfileHdrMagic));
size = GetZipLfileUncompressedSize(zipos->map + lf);
switch (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) {
case kZipCompressionNone:
if (!(h = __zipos_alloc(zipos, 0))) return -1;
h->mem = ZIP_LFILE_CONTENT(zipos->map + lf);
break;
case kZipCompressionDeflate:
if (!(h = __zipos_alloc(zipos, size))) return -1;
if (!__inflate(h->data, size, ZIP_LFILE_CONTENT(zipos->map + lf),
GetZipLfileCompressedSize(zipos->map + lf))) {
h->mem = h->data;
} else {
h->mem = 0;
eio();
}
break;
default:
return eio();
}
h->pos = 0;
h->cfile = cf;
h->size = size;
if (h->mem) {
minfd = 3;
__fds_lock();
TryAgain:
if (IsWindows() || IsMetal()) {
if ((fd = __reservefd_unlocked(-1)) != -1) {
return __zipos_setfd(fd, h, flags, mode);
}
} else if ((fd = __zipos_mkfd(minfd)) != -1) {
if (__ensurefds_unlocked(fd) != -1) {
if (g_fds.p[fd].kind) {
sys_close(fd);
minfd = fd + 1;
goto TryAgain;
}
return __zipos_setfd(fd, h, flags, mode);
}
sys_close(fd);
}
__fds_unlock();
}
__zipos_free(zipos, h);
return -1;
}
/**
* Loads compressed file from αcτµαlly pδrταblε εxεcµταblε object store.
*
* @param uri is obtained via __zipos_parseuri()
* @asyncsignalsafe
* @threadsafe
*/
int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
int rc;
ssize_t cf;
struct Zipos *zipos;
if (_weaken(pthread_testcancel_np) &&
(rc = _weaken(pthread_testcancel_np)())) {
errno = rc;
return -1;
}
BLOCK_SIGNALS;
if ((flags & O_ACCMODE) == O_RDONLY) {
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
rc = __zipos_load(zipos, cf, flags, mode);
assert(rc != 0);
} else {
rc = enoent();
assert(rc != 0);
}
} else {
rc = enoexec();
assert(rc != 0);
}
} else {
rc = einval();
assert(rc != 0);
}
ALLOW_SIGNALS;
return rc;
}

View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/str/str.h"
#include "libc/runtime/zipos.internal.h"
/**
* Extracts information about ZIP URI if it is one.
*/
ssize_t __zipos_parseuri(const char *uri, struct ZiposUri *out) {
size_t len;
if ((uri[0] == '/' && uri[1] == 'z' && uri[2] == 'i' && uri[3] == 'p' &&
(!uri[4] || uri[4] == '/')) &&
(len = strlen(uri)) < PATH_MAX) {
out->path = uri + 4 + !!uri[4];
return (out->len = len - 4 - !!uri[4]);
} else {
return -1;
}
}

52
libc/runtime/zipos-read.c Normal file
View file

@ -0,0 +1,52 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#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"
static size_t GetIovSize(const struct iovec *iov, size_t iovlen) {
size_t i, r;
for (r = i = 0; i < iovlen; ++i) r += iov[i].iov_len;
return r;
}
/**
* Reads data from zip store object.
*
* @return [1..size] bytes on success, 0 on EOF, or -1 w/ errno; with
* exception of size==0, in which case return zero means no error
* @asyncsignalsafe
*/
ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov,
size_t iovlen, ssize_t opt_offset) {
size_t i, b, x, y;
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;
pthread_mutex_unlock(&h->lock);
return y - x;
}

View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/stat.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
#include "libc/zip.internal.h"
#include "libc/runtime/zipos.internal.h"
int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) {
size_t lf;
if (zipos && st) {
bzero(st, sizeof(*st));
if (cf) {
lf = GetZipCfileOffset(zipos->map + cf);
st->st_mode = GetZipCfileMode(zipos->map + cf);
st->st_size = GetZipLfileUncompressedSize(zipos->map + lf);
st->st_blocks =
roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512;
GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim,
&st->st_ctim, 0);
st->st_birthtim = st->st_ctim;
} else {
st->st_mode = 0444 | S_IFDIR | 0111;
}
return 0;
} else {
return einval();
}
}

47
libc/runtime/zipos-stat.c Normal file
View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/stdio/stdio.h"
#include "libc/sysv/errfuns.h"
#include "libc/runtime/zipos.internal.h"
/**
* Reads file metadata from αcτµαlly pδrταblε εxεcµταblε object store.
*
* @param uri is obtained via __zipos_parseuri()
* @asyncsignalsafe
*/
int __zipos_stat(const struct ZiposUri *name, struct stat *st) {
int rc;
ssize_t cf;
struct Zipos *zipos;
if (st) {
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
rc = __zipos_stat_impl(zipos, cf, st);
} else {
rc = enoent();
}
} else {
rc = enoexec();
}
} else {
rc = efault();
}
return rc;
}

42
libc/runtime/zipos.S Normal file
View file

@ -0,0 +1,42 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
// static_yoink this symbol for open(/zip/...) support.
zipos = 0
.globl zipos
.yoink __zipos_close
.yoink __zipos_fcntl
.yoink __zipos_fstat
.yoink __zipos_access
.yoink __zipos_lseek
.yoink __zipos_open
.yoink __zipos_parseuri
.yoink __zipos_read
.yoink __zipos_stat
.yoink __zipos_notat
.yoink __zipos_Mmap
// TODO(jart): why does corruption happen when zip has no assets?
.yoink .cosmo
// deprecated: use __static_yoink("zipos")
zip_uri_support = 0
.globl zip_uri_support

View file

@ -0,0 +1,66 @@
#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
#include "libc/intrin/nopl.internal.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct stat;
struct iovec;
struct ZiposUri {
const char *path;
size_t len;
};
struct ZiposHandle {
struct ZiposHandle *next;
pthread_mutex_t lock;
size_t size; /* byte length of `mem` */
size_t mapsize; /* total size of this struct */
size_t pos; /* read/write byte offset state */
uint32_t cfile; /* central directory entry rva */
uint8_t *mem; /* points to inflated data or uncompressed image */
uint8_t data[]; /* uncompressed file memory */
};
struct Zipos {
uint8_t *map;
uint8_t *cdir;
struct ZiposHandle *freelist;
};
void __zipos_lock(void);
void __zipos_unlock(void);
int __zipos_close(int);
struct Zipos *__zipos_get(void) pureconst;
void __zipos_free(struct Zipos *, struct ZiposHandle *);
ssize_t __zipos_parseuri(const char *, struct ZiposUri *);
ssize_t __zipos_find(struct Zipos *, const struct ZiposUri *);
int __zipos_open(const struct ZiposUri *, unsigned, int);
int __zipos_access(const struct ZiposUri *, int);
int __zipos_stat(const struct ZiposUri *, struct stat *);
int __zipos_fstat(const struct ZiposHandle *, struct stat *);
int __zipos_stat_impl(struct Zipos *, size_t, struct stat *);
ssize_t __zipos_read(struct ZiposHandle *, const struct iovec *, size_t,
ssize_t);
ssize_t __zipos_write(struct ZiposHandle *, const struct iovec *, size_t,
ssize_t);
int64_t __zipos_lseek(struct ZiposHandle *, int64_t, unsigned);
int __zipos_fcntl(int, int, uintptr_t);
int __zipos_notat(int, const char *);
void *__zipos_Mmap(void *, uint64_t, int32_t, int32_t, struct ZiposHandle *,
int64_t) dontasan;
#ifdef _NOPL0
#define __zipos_lock() _NOPL0("__threadcalls", __zipos_lock)
#define __zipos_unlock() _NOPL0("__threadcalls", __zipos_unlock)
#else
#define __zipos_lock() (__threaded ? __zipos_lock() : 0)
#define __zipos_unlock() (__threaded ? __zipos_unlock() : 0)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_ */