Polish recent changes and make improvements

- Simulate SIGPIPE on Windows NT
- Fix commandv() regression on Windows NT
- Fix sigprocmask() strace bug on OpenBSD
- Add many more system calls to --strace logging
- Make errno state more pristine in redbean strace
This commit is contained in:
Justine Tunney 2022-03-19 03:37:00 -07:00
parent 10a766ebd0
commit 39688a73e4
69 changed files with 460 additions and 1976 deletions

View file

@ -29,19 +29,17 @@
* @param fd is vetted by close()
*/
int __zipos_close(int fd) {
int rc;
struct ZiposHandle *h;
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
ZTRACE("__zipos_close(%.*s)",
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile));
if (!IsWindows()) {
sys_close(fd);
rc = sys_close(fd);
} else {
CloseHandle(h->handle);
rc = 0; /* no system file descriptor needed on nt */
}
if (!__vforked) {
free(h->freeme);
free(h);
}
return 0;
return rc;
}

View file

@ -28,30 +28,23 @@
#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) {
ZTRACE("__zipos_fcntl(%.*s, %s)",
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_GETFD");
if (g_fds.p[fd].flags & O_CLOEXEC) {
return FD_CLOEXEC;
rc = FD_CLOEXEC;
} else {
return 0;
rc = 0;
}
} else if (cmd == F_SETFD) {
ZTRACE("__zipos_fcntl(%.*s, %s, 0x%x)",
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_SETFD", arg);
if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC;
return FD_CLOEXEC;
rc = FD_CLOEXEC;
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0;
rc = 0;
}
} else {
ZTRACE("__zipos_fcntl(%.*s, %d, 0x%x) → EINVAL",
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), cmd, arg);
return einval();
rc = einval();
}
return rc;
}

View file

@ -29,13 +29,10 @@
*/
int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) {
int rc;
if (!st) return efault();
if (!(rc = __zipos_stat_impl(__zipos_get(), h->cfile, st))) {
ZTRACE("__zipos_fstat(%.*s) → %d",
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), st->st_size);
return 0;
if (st) {
rc = __zipos_stat_impl(__zipos_get(), h->cfile, st);
} else {
return rc;
rc = efault();
}
return rc;
}

View file

@ -19,10 +19,11 @@
#include "libc/bits/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/sigbits.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/limits.h"
#include "libc/log/libfatal.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/alloca.h"
#include "libc/runtime/runtime.h"
@ -84,16 +85,10 @@ struct Zipos *__zipos_get(void) {
zipos.cdir = cdir;
} else {
munmap(map, size);
ZTRACE("__zipos_get(%s) → eocd not found", program_executable_name);
STRACE("__zipos_get(%#s) → eocd not found", program_executable_name);
}
} else {
ZTRACE("__zipos_get(%s) → stat/mmap %s", program_executable_name,
strerror(errno));
}
close(fd);
} else {
ZTRACE("__zipos_get(%s) → open %s", program_executable_name,
strerror(errno));
}
once = true;
sigprocmask(SIG_SETMASK, &old, 0);

View file

@ -30,26 +30,25 @@
* @asyncsignalsafe
*/
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
int64_t i;
int64_t rc;
switch (whence) {
case SEEK_SET:
i = offset;
rc = offset;
break;
case SEEK_CUR:
i = h->pos + offset;
rc = h->pos + offset;
break;
case SEEK_END:
i = h->size - offset;
rc = h->size - offset;
break;
default:
return einval();
rc = -1;
break;
}
if (i < 0) {
return einval();
if (rc >= 0) {
h->pos = rc;
} else {
rc = einval();
}
h->pos = i;
ZTRACE("__zipos_lseek(%.*s, %d)",
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), i);
return i;
return rc;
}

View file

@ -25,7 +25,6 @@ int __zipos_notat(int dirfd, const char *path) {
struct ZiposUri zipname;
if (!path) return efault();
if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) {
ZTRACE("__zipos_notat(%d, %s) → EINVAL", dirfd, path);
return einval();
}
return 0;

View file

@ -124,7 +124,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
h->mem = NULL;
}
if (h->mem) {
if ((fd = dup(2)) != -1) {
if ((fd = IsWindows() ? __reservefd() : dup(2)) != -1) {
if (__ensurefds(fd) != -1) {
h->handle = g_fds.p[fd].handle;
g_fds.p[fd].kind = kFdZip;
@ -147,22 +147,22 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
* @note don't call open() from signal handlers
*/
int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
int fd;
int rc;
ssize_t cf;
sigset_t oldmask;
struct Zipos *zipos;
if ((flags & O_ACCMODE) != O_RDONLY) return einval();
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
fd = __zipos_load(zipos, cf, flags, mode);
ZTRACE("__zipos_open(%.*s)", name->len, name->path);
if ((flags & O_ACCMODE) == O_RDONLY) {
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
rc = __zipos_load(zipos, cf, flags, mode);
} else {
rc = enoent();
}
} else {
ZTRACE("__zipos_open(%.*s) enoent", name->len, name->path);
fd = enoent();
rc = enoexec();
}
} else {
fd = enoexec();
ZTRACE("__zipos_open(%.*s) enoexec", name->len, name->path);
rc = einval();
}
return fd;
return rc;
}

View file

@ -46,9 +46,5 @@ ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov,
memcpy(iov[i].iov_base, h->mem + y, b);
}
if (opt_offset == -1) h->pos = y;
ZTRACE("__zipos_read(%.*s, cap=%d, off=%d) -> %d",
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), GetIovSize(iov, iovlen),
x, y - x);
return y - x;
}

View file

@ -28,18 +28,21 @@
* @asyncsignalsafe
*/
int __zipos_stat(const struct ZiposUri *name, struct stat *st) {
int rc;
ssize_t cf;
struct Zipos *zipos;
if (!st) return efault();
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
return __zipos_stat_impl(zipos, cf, st);
if (st) {
if ((zipos = __zipos_get())) {
if ((cf = __zipos_find(zipos, name)) != -1) {
rc = __zipos_stat_impl(zipos, cf, st);
} else {
rc = enoent();
}
} else {
ZTRACE("__zipos_stat(%.*s) -> enoent", name->len, name->path);
return enoent();
rc = enoexec();
}
} else {
ZTRACE("__zipos_stat(%.*s) → enoexec", name->len, name->path);
return enoexec();
rc = efault();
}
return rc;
}

View file

@ -1,16 +1,9 @@
#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
#include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#if DEBUGSYS
#define ZTRACE(FMT, ...) kprintf("ZIP: " FMT "\n", ##__VA_ARGS__)
#else
#define ZTRACE(FMT, ...) (void)0
#endif
struct stat;
struct iovec;