mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 15:03:34 +00:00
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:
parent
10a766ebd0
commit
39688a73e4
69 changed files with 460 additions and 1976 deletions
|
@ -39,6 +39,6 @@ int chdir(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
rc = sys_chdir_nt(path);
|
rc = sys_chdir_nt(path);
|
||||||
}
|
}
|
||||||
STRACE("chdir(%#s) → %d% m", path, rc);
|
STRACE("%s(%#s) → %d% m", "chdir", path, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,16 @@
|
||||||
* This function may be used for file descriptors returned by socket,
|
* This function may be used for file descriptors returned by socket,
|
||||||
* accept, epoll_create, and zipos file descriptors too.
|
* accept, epoll_create, and zipos file descriptors too.
|
||||||
*
|
*
|
||||||
|
* This function should never be called twice for the same file
|
||||||
|
* descriptor, regardless of whether or not an error happened. However
|
||||||
|
* that doesn't mean the error should be ignored.
|
||||||
|
*
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
|
* @error EINTR means a signal was received while closing (possibly
|
||||||
|
* because linger is enabled) in which case close() does not need to
|
||||||
|
* be called again, since the fd will close in the background, and
|
||||||
|
* chances are that on linux, the fd is already closed, even if the
|
||||||
|
* underlying resource isn't closed yet
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
|
@ -56,6 +65,7 @@ int close(int fd) {
|
||||||
g_fds.p[fd].kind == kFdProcess)) {
|
g_fds.p[fd].kind == kFdProcess)) {
|
||||||
rc = sys_close_nt(g_fds.p + fd);
|
rc = sys_close_nt(g_fds.p + fd);
|
||||||
} else {
|
} else {
|
||||||
|
STRACE("close(%d) unknown kind: %d", fd, g_fds.p[fd].kind);
|
||||||
rc = ebadf();
|
rc = ebadf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,8 @@ noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||||
e = errno;
|
e = errno;
|
||||||
f = ENOENT;
|
f = ENOENT;
|
||||||
if ((IsWindows() && (FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
if ((IsWindows() && (FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
||||||
FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
FindVerbatim(name, pathbuf, namelen, true, &f) ||
|
||||||
FindVerbatim(name, pathbuf, namelen, false, &f) ||
|
FindSuffixed(name, pathbuf, namelen, false, &f) ||
|
||||||
FindVerbatim(name, pathbuf, namelen, false, &f))) ||
|
FindVerbatim(name, pathbuf, namelen, false, &f))) ||
|
||||||
(!IsWindows() && (FindVerbatim(name, pathbuf, namelen, true, &f) ||
|
(!IsWindows() && (FindVerbatim(name, pathbuf, namelen, true, &f) ||
|
||||||
FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
||||||
|
|
|
@ -33,11 +33,17 @@ static noasan char DescribeMapType(int flags) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
noasan char *DescribeProt(int prot, char p[hasatleast 4]) {
|
||||||
/* asan runtime depends on this function */
|
|
||||||
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
||||||
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
||||||
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
||||||
|
p[3] = 0;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
||||||
|
/* asan runtime depends on this function */
|
||||||
|
DescribeProt(prot, p);
|
||||||
p[3] = DescribeMapType(flags);
|
p[3] = DescribeMapType(flags);
|
||||||
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
|
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
|
||||||
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';
|
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';
|
||||||
|
|
|
@ -33,6 +33,7 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
int prot, int flags,
|
int prot, int flags,
|
||||||
int64_t handle, int64_t off) {
|
int64_t handle, int64_t off) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
|
bool32 rc;
|
||||||
uint32_t got;
|
uint32_t got;
|
||||||
size_t i, upsize;
|
size_t i, upsize;
|
||||||
struct DirectMap dm;
|
struct DirectMap dm;
|
||||||
|
@ -68,9 +69,11 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
if (i == size) {
|
if (i == size) {
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
UnmapViewOfFile(dm.addr);
|
rc = UnmapViewOfFile(dm.addr);
|
||||||
|
STRACE("%s(addr:%p) → %hhhd% m", "UnmapViewOfFile", dm.maphandle, rc);
|
||||||
}
|
}
|
||||||
CloseHandle(dm.maphandle);
|
rc = CloseHandle(dm.maphandle);
|
||||||
|
STRACE("%s(%p) → %hhhd% m", "CloseHandle", dm.maphandle, rc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dm.maphandle = CreateFileMappingNuma(
|
dm.maphandle = CreateFileMappingNuma(
|
||||||
|
@ -91,7 +94,8 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
if (dm.addr) {
|
if (dm.addr) {
|
||||||
return dm;
|
return dm;
|
||||||
} else {
|
} else {
|
||||||
CloseHandle(dm.maphandle);
|
rc = CloseHandle(dm.maphandle);
|
||||||
|
STRACE("%s(%p) → %d% m", "CloseHandle", dm.maphandle, rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
@ -37,13 +38,17 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
|
int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
int rc;
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return -1; /* TODO(jart): implement me */
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) &&
|
||||||
if (!IsWindows()) {
|
weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||||
return sys_faccessat(dirfd, path, mode, flags);
|
rc = -1; /* TODO(jart): implement me */
|
||||||
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_faccessat(dirfd, path, mode, flags);
|
||||||
} else {
|
} else {
|
||||||
return sys_faccessat_nt(dirfd, path, mode, flags);
|
rc = sys_faccessat_nt(dirfd, path, mode, flags);
|
||||||
}
|
}
|
||||||
|
STRACE("faccessat(%d, %#s, %#o, %#x) → %d% m", dirfd, path, mode, flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metastat.internal.h"
|
#include "libc/calls/struct/metastat.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -49,8 +50,11 @@ bool fileexists(const char *path) {
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
uint16_t path16[PATH_MAX];
|
uint16_t path16[PATH_MAX];
|
||||||
e = errno;
|
e = errno;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
efault();
|
||||||
|
res = false;
|
||||||
|
} else if (weaken(__zipos_open) &&
|
||||||
|
weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||||
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
||||||
res = true;
|
res = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -69,7 +73,7 @@ bool fileexists(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
STRACE("fileexists(%#s) → %hhhd% m", path, res);
|
STRACE("%s(%#s) → %hhhd% m", "fileexists", path, res);
|
||||||
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
errno = e;
|
errno = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/pushpop.h"
|
#include "libc/bits/pushpop.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/sysv/consts/fileno.h"
|
#include "libc/sysv/consts/fileno.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,13 @@ STATIC_YOINK("_init_g_fds");
|
||||||
|
|
||||||
hidden struct Fds g_fds;
|
hidden struct Fds g_fds;
|
||||||
|
|
||||||
|
static textwindows int64_t GetHandleNt(long a) {
|
||||||
|
int64_t b;
|
||||||
|
b = GetStdHandle(a);
|
||||||
|
STRACE("GetStdHandle(%ld) → %p% m", a, b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
hidden textstartup void InitializeFileDescriptors(void) {
|
hidden textstartup void InitializeFileDescriptors(void) {
|
||||||
struct Fds *fds;
|
struct Fds *fds;
|
||||||
fds = VEIL("r", &g_fds);
|
fds = VEIL("r", &g_fds);
|
||||||
|
@ -44,10 +52,10 @@ hidden textstartup void InitializeFileDescriptors(void) {
|
||||||
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile);
|
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile);
|
||||||
fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile);
|
fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile);
|
||||||
fds->__init_p[STDIN_FILENO].handle =
|
fds->__init_p[STDIN_FILENO].handle =
|
||||||
GetStdHandle(pushpop(kNtStdInputHandle));
|
GetHandleNt(pushpop(kNtStdInputHandle));
|
||||||
fds->__init_p[STDOUT_FILENO].handle =
|
fds->__init_p[STDOUT_FILENO].handle =
|
||||||
GetStdHandle(pushpop(kNtStdOutputHandle));
|
GetHandleNt(pushpop(kNtStdOutputHandle));
|
||||||
fds->__init_p[STDERR_FILENO].handle =
|
fds->__init_p[STDERR_FILENO].handle =
|
||||||
GetStdHandle(pushpop(kNtStdErrorHandle));
|
GetHandleNt(pushpop(kNtStdErrorHandle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,7 +299,7 @@ int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
|
||||||
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
|
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
|
||||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||||
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
|
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
|
||||||
ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden;
|
||||||
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
||||||
|
|
||||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||||
|
@ -320,7 +320,7 @@ int sys_getsetpriority_nt(int, int, int, int (*)(int));
|
||||||
int64_t __winerr(void) nocallback privileged;
|
int64_t __winerr(void) nocallback privileged;
|
||||||
int64_t ntreturn(uint32_t);
|
int64_t ntreturn(uint32_t);
|
||||||
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden;
|
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden;
|
||||||
ssize_t sys_writev_nt(struct Fd *, const struct iovec *, int) hidden;
|
ssize_t sys_writev_nt(int, const struct iovec *, int) hidden;
|
||||||
struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden;
|
struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden;
|
||||||
unsigned __wincrash_nt(struct NtExceptionPointers *);
|
unsigned __wincrash_nt(struct NtExceptionPointers *);
|
||||||
void *GetProcAddressModule(const char *, const char *) hidden;
|
void *GetProcAddressModule(const char *, const char *) hidden;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
||||||
*/
|
*/
|
||||||
int ioctl_fioclex(int fd, int req) {
|
int ioctl_fioclex(int fd, int req) {
|
||||||
|
int rc;
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
|
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
|
||||||
if (__isfdopen(fd)) {
|
if (__isfdopen(fd)) {
|
||||||
|
@ -36,14 +38,16 @@ int ioctl_fioclex(int fd, int req) {
|
||||||
} else {
|
} else {
|
||||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||||
}
|
}
|
||||||
return 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
rc = ebadf();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return sys_ioctl(fd, req);
|
rc = sys_ioctl(fd, req);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return einval();
|
rc = einval();
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d, %d) → %d% m", "ioctl_fioclex", fd, req, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -105,16 +106,19 @@ static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
|
||||||
* @see ioctl(fd, SIOCGIFCONF, tio) dispatches here
|
* @see ioctl(fd, SIOCGIFCONF, tio) dispatches here
|
||||||
*/
|
*/
|
||||||
int ioctl_siocgifconf(int fd, ...) {
|
int ioctl_siocgifconf(int fd, ...) {
|
||||||
|
int rc;
|
||||||
va_list va;
|
va_list va;
|
||||||
struct ifconf *ifc;
|
struct ifconf *ifc;
|
||||||
va_start(va, fd);
|
va_start(va, fd);
|
||||||
ifc = va_arg(va, struct ifconf *);
|
ifc = va_arg(va, struct ifconf *);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return ioctl_siocgifconf_sysv(fd, ifc);
|
rc = ioctl_siocgifconf_sysv(fd, ifc);
|
||||||
} else {
|
} else {
|
||||||
return ioctl_siocgifconf_nt(fd, ifc);
|
rc = ioctl_siocgifconf_nt(fd, ifc);
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d) → %d% m", "ioctl_siocgifconf", fd, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ioctl_siocgifaddr(int fd, ...) {
|
int ioctl_siocgifaddr(int fd, ...) {
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/termios.h"
|
#include "libc/calls/struct/termios.h"
|
||||||
#include "libc/calls/struct/winsize.h"
|
#include "libc/calls/struct/winsize.h"
|
||||||
|
#include "libc/log/log.h"
|
||||||
#include "libc/nt/console.h"
|
#include "libc/nt/console.h"
|
||||||
#include "libc/nt/enum/startf.h"
|
#include "libc/nt/enum/startf.h"
|
||||||
#include "libc/nt/startupinfo.h"
|
#include "libc/nt/startupinfo.h"
|
||||||
|
@ -57,6 +60,7 @@ textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) {
|
||||||
__winerr();
|
__winerr();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
STRACE("%s() failed %m", "GetConsoleMode");
|
||||||
enotty();
|
enotty();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/winsize.h"
|
#include "libc/calls/struct/winsize.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -30,21 +31,25 @@
|
||||||
* @see ioctl(fd, TIOCGWINSZ, ws) dispatches here
|
* @see ioctl(fd, TIOCGWINSZ, ws) dispatches here
|
||||||
*/
|
*/
|
||||||
int ioctl_tiocgwinsz(int fd, ...) {
|
int ioctl_tiocgwinsz(int fd, ...) {
|
||||||
|
int rc;
|
||||||
va_list va;
|
va_list va;
|
||||||
struct winsize *ws;
|
struct winsize *ws;
|
||||||
va_start(va, fd);
|
va_start(va, fd);
|
||||||
ws = va_arg(va, struct winsize *);
|
ws = va_arg(va, struct winsize *);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) return efault();
|
if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) {
|
||||||
if (fd >= 0) {
|
rc = efault();
|
||||||
|
} else if (fd >= 0) {
|
||||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||||
return enotty();
|
rc = enotty();
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
return sys_ioctl(fd, TIOCGWINSZ, ws);
|
rc = sys_ioctl(fd, TIOCGWINSZ, ws);
|
||||||
} else {
|
} else {
|
||||||
return ioctl_tiocgwinsz_nt(g_fds.p + fd, ws);
|
rc = ioctl_tiocgwinsz_nt(g_fds.p + fd, ws);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return einval();
|
rc = einval();
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d) → %d% m", "ioctl_tiocgwinsz", fd, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
|
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
|
||||||
* S_ISDIR(st.st_mode);
|
* S_ISDIR(st.st_mode);
|
||||||
*
|
*
|
||||||
* Except faster and with fewer dependencies.
|
* Except faster, with fewer dependencies, and less errno clobbering.
|
||||||
*
|
*
|
||||||
* @see isregularfile(), issymlink(), ischardev()
|
* @see isregularfile(), issymlink(), ischardev()
|
||||||
*/
|
*/
|
||||||
|
@ -49,8 +49,11 @@ bool isdirectory(const char *path) {
|
||||||
union metastat st;
|
union metastat st;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
e = errno;
|
e = errno;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
efault();
|
||||||
|
res = false;
|
||||||
|
} else if (weaken(__zipos_open) &&
|
||||||
|
weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||||
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
||||||
res = S_ISDIR(st.cosmo.st_mode);
|
res = S_ISDIR(st.cosmo.st_mode);
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,7 +62,6 @@ bool isdirectory(const char *path) {
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
res = false;
|
res = false;
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
e = errno;
|
|
||||||
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
||||||
res = S_ISDIR(METASTAT(st, st_mode));
|
res = S_ISDIR(METASTAT(st, st_mode));
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,7 +70,7 @@ bool isdirectory(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
res = isdirectory_nt(path);
|
res = isdirectory_nt(path);
|
||||||
}
|
}
|
||||||
STRACE("isdirectory(%#s) → %hhhd% m", path, res);
|
STRACE("%s(%#s) → %hhhd% m", "isdirectory", path, res);
|
||||||
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
errno = e;
|
errno = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metastat.internal.h"
|
#include "libc/calls/struct/metastat.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -35,34 +36,40 @@
|
||||||
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
|
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
|
||||||
* S_ISREG(st.st_mode);
|
* S_ISREG(st.st_mode);
|
||||||
*
|
*
|
||||||
* Except faster and with fewer dependencies.
|
* Except faster, with fewer dependencies, and less errno clobbering.
|
||||||
*
|
*
|
||||||
* @see isdirectory(), ischardev(), issymlink()
|
* @see isdirectory(), ischardev(), issymlink()
|
||||||
*/
|
*/
|
||||||
bool isregularfile(const char *path) {
|
bool isregularfile(const char *path) {
|
||||||
int e;
|
int e;
|
||||||
|
bool res;
|
||||||
union metastat st;
|
union metastat st;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
e = errno;
|
||||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
e = errno;
|
efault();
|
||||||
|
res = false;
|
||||||
|
} else if (weaken(__zipos_open) &&
|
||||||
|
weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||||
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
|
||||||
return S_ISREG(st.cosmo.st_mode);
|
res = !!S_ISREG(st.cosmo.st_mode);
|
||||||
} else {
|
} else {
|
||||||
errno = e;
|
res = false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return false;
|
res = false;
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
e = errno;
|
|
||||||
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
||||||
return S_ISREG(METASTAT(st, st_mode));
|
res = S_ISREG(METASTAT(st, st_mode));
|
||||||
} else {
|
} else {
|
||||||
errno = e;
|
res = false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return isregularfile_nt(path);
|
res = isregularfile_nt(path);
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%#s) → %hhhd% m", "isregularfile", path, res);
|
||||||
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
|
errno = e;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metastat.internal.h"
|
#include "libc/calls/struct/metastat.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -44,22 +45,30 @@
|
||||||
*/
|
*/
|
||||||
bool issymlink(const char *path) {
|
bool issymlink(const char *path) {
|
||||||
int e;
|
int e;
|
||||||
|
bool res;
|
||||||
union metastat st;
|
union metastat st;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
e = errno;
|
||||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return false;
|
efault();
|
||||||
|
res = false;
|
||||||
|
} else if (weaken(__zipos_open) &&
|
||||||
|
weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||||
|
res = false;
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return false;
|
res = false;
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
e = errno;
|
|
||||||
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
|
||||||
return S_ISLNK(METASTAT(st, st_mode));
|
res = S_ISLNK(METASTAT(st, st_mode));
|
||||||
} else {
|
} else {
|
||||||
errno = e;
|
res = false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return issymlink_nt(path);
|
res = issymlink_nt(path);
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%#s) → %hhhd% m", "issymlink", path, res);
|
||||||
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
|
errno = e;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
#define ShouldUseMsabiAttribute() 1
|
#define ShouldUseMsabiAttribute() 1
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/thunk/msabi.h"
|
#include "libc/nt/thunk/msabi.h"
|
||||||
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/sysv/consts/nr.h"
|
#include "libc/sysv/consts/nr.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,10 +34,11 @@
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
* @see mmap()
|
* @see mmap()
|
||||||
*/
|
*/
|
||||||
noasan noubsan privileged int mprotect(void *addr, uint64_t len, int prot) {
|
noasan noubsan privileged int mprotect(void *addr, size_t len, int prot) {
|
||||||
bool cf;
|
bool cf;
|
||||||
int64_t rc;
|
int64_t rc;
|
||||||
uint32_t oldprot;
|
uint32_t oldprot;
|
||||||
|
char protbuf[4];
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
asm volatile(CFLAG_ASM("clc\n\tsyscall")
|
asm volatile(CFLAG_ASM("clc\n\tsyscall")
|
||||||
: CFLAG_CONSTRAINT(cf), "=a"(rc)
|
: CFLAG_CONSTRAINT(cf), "=a"(rc)
|
||||||
|
@ -48,12 +51,14 @@ noasan noubsan privileged int mprotect(void *addr, uint64_t len, int prot) {
|
||||||
errno = -rc;
|
errno = -rc;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
} else {
|
} else {
|
||||||
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
|
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
|
||||||
return 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
return __winerr();
|
rc = __winerr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
STRACE("mprotect(%p, %'zu, %s[%#x]) → %d% m", addr, len,
|
||||||
|
DescribeProt(prot, protbuf), prot, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nt/enum/accessmask.h"
|
#include "libc/nt/enum/accessmask.h"
|
||||||
#include "libc/nt/enum/securityimpersonationlevel.h"
|
#include "libc/nt/enum/securityimpersonationlevel.h"
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include "libc/nt/struct/privilegeset.h"
|
#include "libc/nt/struct/privilegeset.h"
|
||||||
#include "libc/nt/struct/securitydescriptor.h"
|
#include "libc/nt/struct/securitydescriptor.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/ok.h"
|
#include "libc/sysv/consts/ok.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -104,7 +106,6 @@ TryAgain:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e = GetLastError();
|
e = GetLastError();
|
||||||
STRACE("GetFileSecurity failed: %d %u", e, secsize);
|
|
||||||
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
|
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
|
||||||
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
|
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
|
||||||
s = freeme;
|
s = freeme;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntmagicpaths.internal.h"
|
#include "libc/calls/ntmagicpaths.internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/nt/createfile.h"
|
#include "libc/nt/createfile.h"
|
||||||
#include "libc/nt/enum/accessmask.h"
|
#include "libc/nt/enum/accessmask.h"
|
||||||
#include "libc/nt/enum/creationdisposition.h"
|
#include "libc/nt/enum/creationdisposition.h"
|
||||||
|
@ -63,14 +64,15 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
||||||
kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics |
|
kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics |
|
||||||
kNtFileAttributeTemporary)))),
|
kNtFileAttributeTemporary)))),
|
||||||
0)) != -1) {
|
0)) != -1) {
|
||||||
return handle;
|
|
||||||
} else if (GetLastError() == kNtErrorFileExists &&
|
} else if (GetLastError() == kNtErrorFileExists &&
|
||||||
((flags & O_CREAT) &&
|
((flags & O_CREAT) &&
|
||||||
(flags & O_TRUNC))) { /* TODO(jart): What was this? */
|
(flags & O_TRUNC))) { /* TODO(jart): What was this? */
|
||||||
return eisdir();
|
handle = eisdir();
|
||||||
} else {
|
} else {
|
||||||
return __winerr();
|
handle = __winerr();
|
||||||
}
|
}
|
||||||
|
STRACE("CreateFile() → %ld% m", handle);
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static textwindows ssize_t sys_open_nt_console(int dirfd,
|
static textwindows ssize_t sys_open_nt_console(int dirfd,
|
||||||
|
|
|
@ -61,11 +61,15 @@
|
||||||
char program_executable_name[SIZE];
|
char program_executable_name[SIZE];
|
||||||
|
|
||||||
static textwindows bool GetNtExePath(char executable[SIZE]) {
|
static textwindows bool GetNtExePath(char executable[SIZE]) {
|
||||||
|
bool32 rc;
|
||||||
uint64_t w;
|
uint64_t w;
|
||||||
wint_t x, y;
|
wint_t x, y;
|
||||||
uint32_t i, j;
|
uint32_t i, j;
|
||||||
char16_t path16[PATH_MAX + 1];
|
char16_t path16[PATH_MAX + 1];
|
||||||
if (!GetModuleFileName(0, path16, ARRAYLEN(path16))) return 0;
|
path16[0] = 0;
|
||||||
|
rc = GetModuleFileName(0, path16, ARRAYLEN(path16));
|
||||||
|
STRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||||
|
if (!rc) return false;
|
||||||
for (i = j = 0; (x = path16[i++] & 0xffff);) {
|
for (i = j = 0; (x = path16[i++] & 0xffff);) {
|
||||||
if (!IsUcs2(x)) {
|
if (!IsUcs2(x)) {
|
||||||
y = path16[i++] & 0xffff;
|
y = path16[i++] & 0xffff;
|
||||||
|
|
|
@ -45,7 +45,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
rc = sys_pwrite(fd, buf, size, offset, offset);
|
rc = sys_pwrite(fd, buf, size, offset, offset);
|
||||||
} else if (__isfdkind(fd, kFdFile)) {
|
} else if (__isfdkind(fd, kFdFile)) {
|
||||||
rc = sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset);
|
rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, offset);
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
return ebadf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
||||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);
|
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);
|
||||||
} else if (IsWindows()) {
|
} else if (IsWindows()) {
|
||||||
if (fd < g_fds.n) {
|
if (fd < g_fds.n) {
|
||||||
return sys_write_nt(g_fds.p + fd, iov, iovlen, off);
|
return sys_write_nt(fd, iov, iovlen, off);
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
return ebadf();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
|
@ -23,6 +24,8 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/log/log.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -55,6 +58,7 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
||||||
char howbuf[12];
|
char howbuf[12];
|
||||||
char buf[2][41];
|
char buf[2][41];
|
||||||
sigset_t old, *oldp;
|
sigset_t old, *oldp;
|
||||||
|
const sigset_t *arg;
|
||||||
if (!(IsAsan() &&
|
if (!(IsAsan() &&
|
||||||
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
|
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
|
||||||
(opt_out_oldset &&
|
(opt_out_oldset &&
|
||||||
|
@ -75,9 +79,14 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
}
|
}
|
||||||
} else if (IsOpenbsd()) {
|
} else if (IsOpenbsd()) {
|
||||||
if (!opt_set) how = 1;
|
if (opt_set) {
|
||||||
if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
/* openbsd only supports 32 signals so it passses them in a reg */
|
||||||
if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) {
|
arg = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||||
|
} else {
|
||||||
|
how = 1; /* SIG_BLOCK */
|
||||||
|
arg = 0; /* changes nothing */
|
||||||
|
}
|
||||||
|
if ((x = sys_sigprocmask(how, arg, 0, 0)) != -1) {
|
||||||
if (opt_out_oldset) {
|
if (opt_out_oldset) {
|
||||||
bzero(opt_out_oldset, sizeof(*opt_out_oldset));
|
bzero(opt_out_oldset, sizeof(*opt_out_oldset));
|
||||||
memcpy(opt_out_oldset, &x, sizeof(x));
|
memcpy(opt_out_oldset, &x, sizeof(x));
|
||||||
|
|
|
@ -16,12 +16,16 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
#include "libc/nt/console.h"
|
#include "libc/nt/console.h"
|
||||||
#include "libc/nt/enum/consolemodeflags.h"
|
#include "libc/nt/enum/consolemodeflags.h"
|
||||||
|
@ -75,17 +79,20 @@ static int ttyname_linux(int fd, char *buf, size_t size) {
|
||||||
* Returns name of terminal, reentrantly.
|
* Returns name of terminal, reentrantly.
|
||||||
*/
|
*/
|
||||||
int ttyname_r(int fd, char *buf, size_t size) {
|
int ttyname_r(int fd, char *buf, size_t size) {
|
||||||
|
int rc;
|
||||||
if (IsLinux()) {
|
if (IsLinux()) {
|
||||||
return ttyname_linux(fd, buf, size);
|
rc = ttyname_linux(fd, buf, size);
|
||||||
} else if (IsFreebsd()) {
|
} else if (IsFreebsd()) {
|
||||||
return ttyname_freebsd(fd, buf, size);
|
rc = ttyname_freebsd(fd, buf, size);
|
||||||
} else if (IsWindows()) {
|
} else if (IsWindows()) {
|
||||||
if (__isfdkind(fd, kFdFile)) {
|
if (__isfdkind(fd, kFdFile)) {
|
||||||
return sys_ttyname_nt(fd, buf, size);
|
rc = sys_ttyname_nt(fd, buf, size);
|
||||||
} else {
|
} else {
|
||||||
return ebadf();
|
rc = ebadf();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
rc = enosys();
|
||||||
}
|
}
|
||||||
|
STRACE("ttyname_r(%d, %s) → %d% m", fd, buf, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
@ -35,13 +36,16 @@
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
int unlinkat(int dirfd, const char *path, int flags) {
|
int unlinkat(int dirfd, const char *path, int flags) {
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
int rc;
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return -1; /* TODO(jart): implement me */
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
|
||||||
if (!IsWindows()) {
|
STRACE("zipos unlinkat not supported yet");
|
||||||
return sys_unlinkat(dirfd, path, flags);
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_unlinkat(dirfd, path, flags);
|
||||||
} else {
|
} else {
|
||||||
return sys_unlinkat_nt(dirfd, path, flags);
|
rc = sys_unlinkat_nt(dirfd, path, flags);
|
||||||
}
|
}
|
||||||
|
STRACE("unlinkat(%d, %#s, %#b) → %d% m", dirfd, path, flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -34,16 +35,23 @@
|
||||||
*/
|
*/
|
||||||
int utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
int utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
||||||
int flags) {
|
int flags) {
|
||||||
|
int rc;
|
||||||
if (IsAsan() && (!__asan_is_valid(path, 1) ||
|
if (IsAsan() && (!__asan_is_valid(path, 1) ||
|
||||||
(ts && !__asan_is_valid(ts, sizeof(struct timespec) * 2)))) {
|
(ts && !__asan_is_valid(ts, sizeof(struct timespec) * 2)))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
STRACE("zipos mkdirat not supported yet");
|
||||||
return -1; /* TODO(jart): implement me */
|
} else if (!IsWindows()) {
|
||||||
}
|
rc = sys_utimensat(dirfd, path, ts, flags);
|
||||||
if (!IsWindows()) {
|
|
||||||
return sys_utimensat(dirfd, path, ts, flags);
|
|
||||||
} else {
|
} else {
|
||||||
return sys_utimensat_nt(dirfd, path, ts, flags);
|
rc = sys_utimensat_nt(dirfd, path, ts, flags);
|
||||||
}
|
}
|
||||||
|
if (ts) {
|
||||||
|
STRACE("utimensat(%d, %#s, {{%,ld, %,ld}, {%,ld, %,ld}}, %#b) → %d% m",
|
||||||
|
dirfd, path, ts[0].tv_sec, ts[0].tv_nsec, ts[1].tv_sec,
|
||||||
|
ts[1].tv_nsec, flags, rc);
|
||||||
|
} else {
|
||||||
|
STRACE("utimensat(%d, %#s, 0, %#b) → %d% m", dirfd, path, flags, rc);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#define ShouldUseMsabiAttribute() 1
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
@ -30,16 +31,16 @@
|
||||||
* @return -1 w/ few exceptions
|
* @return -1 w/ few exceptions
|
||||||
* @note this is a code-size saving device
|
* @note this is a code-size saving device
|
||||||
*/
|
*/
|
||||||
privileged noasan int64_t __winerr(void) {
|
privileged int64_t __winerr(void) {
|
||||||
errno_t e;
|
errno_t e;
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
e = GetLastError();
|
e = __imp_GetLastError();
|
||||||
if (weaken(__dos2errno)) {
|
if (weaken(__dos2errno)) {
|
||||||
e = weaken(__dos2errno)(e);
|
e = weaken(__dos2errno)(e);
|
||||||
}
|
}
|
||||||
errno = e;
|
|
||||||
return -1;
|
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
e = ENOSYS;
|
||||||
}
|
}
|
||||||
|
errno = e;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,28 +18,47 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
|
#include "libc/calls/struct/siginfo.h"
|
||||||
|
#include "libc/calls/typedef/sigaction_f.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
|
#include "libc/nt/errors.h"
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/struct/overlapped.h"
|
#include "libc/nt/struct/overlapped.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
static textwindows ssize_t sys_write_nt_impl(struct Fd *fd, void *data,
|
static textwindows ssize_t sys_write_nt_epipe(int fd) {
|
||||||
size_t size, ssize_t offset) {
|
siginfo_t info;
|
||||||
|
STRACE("WriteFile(%d:%p) → %m", fd, g_fds.p[fd].handle);
|
||||||
|
if (!__sighandrvas[SIGPIPE]) {
|
||||||
|
_Exit(128 + SIGPIPE);
|
||||||
|
} else if (__sighandrvas[SIGPIPE] >= kSigactionMinRva) {
|
||||||
|
bzero(&info, sizeof(info));
|
||||||
|
((sigaction_f)(_base + __sighandrvas[SIGPIPE]))(SIGPIPE, &info, 0);
|
||||||
|
}
|
||||||
|
return epipe();
|
||||||
|
}
|
||||||
|
|
||||||
|
static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
|
||||||
|
ssize_t offset) {
|
||||||
uint32_t sent;
|
uint32_t sent;
|
||||||
struct NtOverlapped overlap;
|
struct NtOverlapped overlap;
|
||||||
if (WriteFile(fd->handle, data, clampio(size), &sent,
|
if (WriteFile(g_fds.p[fd].handle, data, clampio(size), &sent,
|
||||||
offset2overlap(offset, &overlap))) {
|
offset2overlap(offset, &overlap))) {
|
||||||
/* TODO(jart): Trigger SIGPIPE on kNtErrorBrokenPipe */
|
|
||||||
return sent;
|
return sent;
|
||||||
|
} else if (GetLastError() == kNtErrorBrokenPipe) {
|
||||||
|
return sys_write_nt_epipe(fd);
|
||||||
} else {
|
} else {
|
||||||
return __winerr();
|
return __winerr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows ssize_t sys_write_nt(struct Fd *fd, const struct iovec *iov,
|
textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen,
|
||||||
size_t iovlen, ssize_t opt_offset) {
|
ssize_t opt_offset) {
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
size_t i, total;
|
size_t i, total;
|
||||||
uint32_t size, wrote;
|
uint32_t size, wrote;
|
||||||
|
|
|
@ -50,7 +50,7 @@ ssize_t write(int fd, const void *buf, size_t size) {
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
||||||
} else {
|
} else {
|
||||||
return sys_writev_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
|
return sys_writev_nt(fd, &(struct iovec){buf, size}, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return einval();
|
return einval();
|
||||||
|
|
|
@ -21,9 +21,8 @@
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
textwindows ssize_t sys_writev_nt(struct Fd *fd, const struct iovec *iov,
|
textwindows ssize_t sys_writev_nt(int fd, const struct iovec *iov, int iovlen) {
|
||||||
int iovlen) {
|
switch (g_fds.p[fd].kind) {
|
||||||
switch (fd->kind) {
|
|
||||||
case kFdFile:
|
case kFdFile:
|
||||||
case kFdConsole:
|
case kFdConsole:
|
||||||
return sys_write_nt(fd, iov, iovlen, -1);
|
return sys_write_nt(fd, iov, iovlen, -1);
|
||||||
|
|
|
@ -47,7 +47,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
|
||||||
} else {
|
} else {
|
||||||
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
|
return sys_writev_nt(fd, iov, iovlen);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return einval();
|
return einval();
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/bsr.h"
|
#include "libc/nexgen32e/bsr.h"
|
||||||
|
|
|
@ -29,12 +29,21 @@ extern const struct Dos2Errno kDos2Errno[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates Windows error using superset of consts.sh.
|
* Translates Windows error using superset of consts.sh.
|
||||||
|
*
|
||||||
|
* This function is called by __winerr(). It can only be used on
|
||||||
|
* Windows, because it returns an errno. Normally, errnos will be
|
||||||
|
* programmed to be the same as DOS errnos, per consts.sh. But since
|
||||||
|
* there's so many more errors in DOS, this function provides an added
|
||||||
|
* optional benefit mapping additional constants onto the errnos in
|
||||||
|
* consts.sh.
|
||||||
*/
|
*/
|
||||||
privileged errno_t __dos2errno(uint32_t error) {
|
privileged errno_t __dos2errno(uint32_t error) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; kDos2Errno[i].doscode; ++i) {
|
if (error) {
|
||||||
if (error == kDos2Errno[i].doscode) {
|
for (i = 0; kDos2Errno[i].doscode; ++i) {
|
||||||
return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv);
|
if (error == kDos2Errno[i].doscode) {
|
||||||
|
return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
|
@ -16,8 +16,11 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
forceinline int Identity(int c) {
|
forceinline int Identity(int c) {
|
||||||
|
|
|
@ -18,20 +18,6 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
|
|
||||||
static const char *__addr2line;
|
|
||||||
|
|
||||||
static textstartup void __addr2line_init() {
|
|
||||||
static bool once;
|
|
||||||
if (!once) {
|
|
||||||
__addr2line = commandvenv("ADDR2LINE", "addr2line");
|
|
||||||
once = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *GetAddr2linePath(void) {
|
const char *GetAddr2linePath(void) {
|
||||||
return __addr2line;
|
return commandvenv("ADDR2LINE", "addr2line");
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *const __addr2line_ctor[] initarray = {
|
|
||||||
__addr2line_init,
|
|
||||||
};
|
|
||||||
|
|
|
@ -76,13 +76,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DWARF is a weak standard. If we build on Linux then only the
|
* DWARF is a weak standard. Platforms that use LLVM or old GNU
|
||||||
* precice same version of the same tools on Linux can be counted upon
|
* usually can't be counted upon to print backtraces correctly.
|
||||||
* to work reliably. So if it's not Linux, we fall back to our builtin
|
|
||||||
* tooling which can be counted upon.
|
|
||||||
*/
|
*/
|
||||||
if (!IsLinux()) {
|
if (!IsLinux() /* && !IsWindows() */) {
|
||||||
ShowHint("won't print addr2line backtrace on non-linux");
|
ShowHint("won't print addr2line backtrace because probably llvm");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,6 +242,20 @@ forceinline char *__strstr(const char *haystack, const char *needle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline char16_t *__strstr16(const char16_t *haystack,
|
||||||
|
const char16_t *needle) {
|
||||||
|
size_t i;
|
||||||
|
for (;;) {
|
||||||
|
for (i = 0;; ++i) {
|
||||||
|
if (!needle[i]) return (/*unconst*/ char16_t *)haystack;
|
||||||
|
if (!haystack[i]) break;
|
||||||
|
if (needle[i] != haystack[i]) break;
|
||||||
|
}
|
||||||
|
if (!*haystack++) break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
forceinline char *__getenv(char **p, const char *s) {
|
forceinline char *__getenv(char **p, const char *s) {
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
if (p) {
|
if (p) {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nexgen32e/kcpuids.h"
|
#include "libc/nexgen32e/kcpuids.h"
|
||||||
|
@ -67,18 +68,21 @@ ssize_t getrandom(void *p, size_t n, unsigned f) {
|
||||||
char cf;
|
char cf;
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
size_t i, j, m;
|
|
||||||
int fd, cmd[2];
|
int fd, cmd[2];
|
||||||
|
size_t i, j, m;
|
||||||
|
const char *via;
|
||||||
sigset_t neu, old;
|
sigset_t neu, old;
|
||||||
if (n > 256) n = 256;
|
if (n > 256) n = 256;
|
||||||
if ((f & ~(GRND_RANDOM | GRND_NONBLOCK))) return einval();
|
if ((f & ~(GRND_RANDOM | GRND_NONBLOCK))) return einval();
|
||||||
if (IsWindows()) {
|
if (IsWindows()) {
|
||||||
|
via = "RtlGenRandom";
|
||||||
if (RtlGenRandom(p, n)) {
|
if (RtlGenRandom(p, n)) {
|
||||||
rc = n;
|
rc = n;
|
||||||
} else {
|
} else {
|
||||||
return __winerr();
|
rc = __winerr();
|
||||||
}
|
}
|
||||||
} else if (IsFreebsd() || IsNetbsd()) {
|
} else if (IsFreebsd() || IsNetbsd()) {
|
||||||
|
via = "KERN_ARND";
|
||||||
if (IsFreebsd()) {
|
if (IsFreebsd()) {
|
||||||
cmd[0] = 1; /* CTL_KERN */
|
cmd[0] = 1; /* CTL_KERN */
|
||||||
cmd[1] = 37; /* KERN_ARND */
|
cmd[1] = 37; /* KERN_ARND */
|
||||||
|
@ -91,27 +95,34 @@ ssize_t getrandom(void *p, size_t n, unsigned f) {
|
||||||
rc = m;
|
rc = m;
|
||||||
}
|
}
|
||||||
} else if (have_getrandom) {
|
} else if (have_getrandom) {
|
||||||
|
via = "getrandom";
|
||||||
if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) {
|
if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) {
|
||||||
if (!rc && (IsXnu() || IsOpenbsd())) {
|
if (!rc && (IsXnu() || IsOpenbsd())) {
|
||||||
rc = n;
|
rc = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((fd = __sys_openat(
|
} else if ((fd = __sys_openat(
|
||||||
AT_FDCWD, (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom",
|
AT_FDCWD,
|
||||||
|
(via = (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom"),
|
||||||
O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) !=
|
O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) !=
|
||||||
-1) {
|
-1) {
|
||||||
rc = sys_read(fd, p, n);
|
rc = sys_read(fd, p, n);
|
||||||
sys_close(fd);
|
sys_close(fd);
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
rc = enosys();
|
||||||
}
|
}
|
||||||
|
STRACE("getrandom(%p, %'zu, %#x) via %s → %'ld% m", p, n, f, via, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static textstartup void getrandom_init(void) {
|
static textstartup void getrandom_init(void) {
|
||||||
if (sys_getrandom(0, 0, 0) == 0) {
|
int e, rc;
|
||||||
|
e = errno;
|
||||||
|
if (!(rc = sys_getrandom(0, 0, 0))) {
|
||||||
have_getrandom = true;
|
have_getrandom = true;
|
||||||
}
|
}
|
||||||
|
STRACE("sys_getrandom(0,0,0) → %d% m");
|
||||||
|
errno = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *const g_getrandom_init[] initarray = {getrandom_init};
|
const void *const g_getrandom_init[] initarray = {getrandom_init};
|
||||||
|
|
|
@ -46,6 +46,7 @@ extern hidden struct MemoryIntervals _mmi;
|
||||||
|
|
||||||
const char *DescribeFrame(int);
|
const char *DescribeFrame(int);
|
||||||
void PrintSystemMappings(int) hidden;
|
void PrintSystemMappings(int) hidden;
|
||||||
|
char *DescribeProt(int, char[hasatleast 4]);
|
||||||
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
||||||
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
||||||
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
||||||
|
|
|
@ -109,7 +109,7 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
||||||
dm = sys_mmap(addr, size, prot, f, fd, off);
|
dm = sys_mmap(addr, size, prot, f, fd, off);
|
||||||
if (UNLIKELY(dm.addr == MAP_FAILED)) {
|
if (UNLIKELY(dm.addr == MAP_FAILED)) {
|
||||||
if (IsWindows() && (flags & MAP_FIXED)) {
|
if (IsWindows() && (flags & MAP_FIXED)) {
|
||||||
STRACE("mmap(%.12p, %'ld) → %s (%s)", addr, size, strerror(errno),
|
STRACE("mmap(%.12p, %'ld) → %m (%s)", addr, size,
|
||||||
"can't recover from MAP_FIXED errors on Windows");
|
"can't recover from MAP_FIXED errors on Windows");
|
||||||
assert(!"MapMemory() failed");
|
assert(!"MapMemory() failed");
|
||||||
Die();
|
Die();
|
||||||
|
@ -123,14 +123,14 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
||||||
}
|
}
|
||||||
if (!IsWindows() && (flags & MAP_FIXED)) {
|
if (!IsWindows() && (flags & MAP_FIXED)) {
|
||||||
if (UntrackMemoryIntervals(addr, size)) {
|
if (UntrackMemoryIntervals(addr, size)) {
|
||||||
STRACE("FIXED UNTRACK FAILED %s", strerror(errno));
|
STRACE("FIXED UNTRACK FAILED %m");
|
||||||
assert(!"MapMemory() failed");
|
assert(!"MapMemory() failed");
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) {
|
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) {
|
||||||
if (sys_munmap(addr, n) == -1) {
|
if (sys_munmap(addr, n) == -1) {
|
||||||
STRACE("TRACK MUNMAP FAILED %s", strerror(errno));
|
STRACE("TRACK MUNMAP FAILED %m");
|
||||||
assert(!"MapMemory() failed");
|
assert(!"MapMemory() failed");
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ RaiseEnobufs:
|
||||||
RaiseEnoexec:
|
RaiseEnoexec:
|
||||||
errno = ENOEXEC;
|
errno = ENOEXEC;
|
||||||
SystemError:
|
SystemError:
|
||||||
STRACE("OpenSymbolTable() %m");
|
STRACE("OpenSymbolTable()% m");
|
||||||
if (map != MAP_FAILED) {
|
if (map != MAP_FAILED) {
|
||||||
munmap(map, st.st_size);
|
munmap(map, st.st_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
|
@ -100,7 +101,9 @@ forceinline void MakeLongDoubleLongAgain(void) {
|
||||||
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
|
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
|
||||||
}
|
}
|
||||||
|
|
||||||
static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
static noasan textwindows wontreturn noinstrument void WinMainNew(
|
||||||
|
const char16_t *cmdline) {
|
||||||
|
bool32 rc;
|
||||||
int64_t h;
|
int64_t h;
|
||||||
int version;
|
int version;
|
||||||
int i, count;
|
int i, count;
|
||||||
|
@ -112,13 +115,17 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
||||||
version = NtGetPeb()->OSMajorVersion;
|
version = NtGetPeb()->OSMajorVersion;
|
||||||
__oldstack = (intptr_t)__builtin_frame_address(0);
|
__oldstack = (intptr_t)__builtin_frame_address(0);
|
||||||
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
||||||
SetConsoleCP(kNtCpUtf8);
|
rc = SetConsoleCP(kNtCpUtf8);
|
||||||
SetConsoleOutputCP(kNtCpUtf8);
|
STRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
||||||
|
rc = SetConsoleOutputCP(kNtCpUtf8);
|
||||||
|
STRACE("SetConsoleOutputCP(kNtCpUtf8) → %hhhd", rc);
|
||||||
SetEnvironmentVariable(u"TERM", u"xterm-truecolor");
|
SetEnvironmentVariable(u"TERM", u"xterm-truecolor");
|
||||||
for (i = 0; i < 2; ++i) {
|
for (i = 0; i < 2; ++i) {
|
||||||
hand = GetStdHandle(kConsoleHandles[i]);
|
hand = GetStdHandle(kConsoleHandles[i]);
|
||||||
GetConsoleMode(hand, __ntconsolemode + i);
|
rc = GetConsoleMode(hand, __ntconsolemode + i);
|
||||||
SetConsoleMode(hand, kConsoleModes[i]);
|
STRACE("GetConsoleMode(%p, [%#x]) → %hhhd", hand, __ntconsolemode[i], rc);
|
||||||
|
rc = SetConsoleMode(hand, kConsoleModes[i]);
|
||||||
|
STRACE("SetConsoleMode(%p, %#x) → %hhhd", hand, kConsoleModes[i], rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_mmi.p = _mmi.s;
|
_mmi.p = _mmi.s;
|
||||||
|
@ -128,7 +135,8 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
||||||
stacksize = GetStackSize();
|
stacksize = GetStackSize();
|
||||||
allocsize = argsize + stacksize;
|
allocsize = argsize + stacksize;
|
||||||
allocaddr = stackaddr - argsize;
|
allocaddr = stackaddr - argsize;
|
||||||
STRACE("WinMainNew() mapping arg block / stack");
|
STRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize,
|
||||||
|
allocaddr);
|
||||||
MapViewOfFileExNuma(
|
MapViewOfFileExNuma(
|
||||||
(_mmi.p[0].h = CreateFileMappingNuma(
|
(_mmi.p[0].h = CreateFileMappingNuma(
|
||||||
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, allocsize >> 32,
|
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, allocsize >> 32,
|
||||||
|
@ -142,8 +150,8 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
||||||
_mmi.i = 1;
|
_mmi.i = 1;
|
||||||
wa = (struct WinArgs *)allocaddr;
|
wa = (struct WinArgs *)allocaddr;
|
||||||
STRACE("WinMainNew() loading arg block");
|
STRACE("WinMainNew() loading arg block");
|
||||||
count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock),
|
count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv,
|
||||||
wa->argv, ARRAYLEN(wa->argv));
|
ARRAYLEN(wa->argv));
|
||||||
for (i = 0; wa->argv[0][i]; ++i) {
|
for (i = 0; wa->argv[0][i]; ++i) {
|
||||||
if (wa->argv[0][i] == '\\') {
|
if (wa->argv[0][i] == '\\') {
|
||||||
wa->argv[0][i] = '/';
|
wa->argv[0][i] = '/';
|
||||||
|
@ -197,15 +205,21 @@ noasan textwindows noinstrument int64_t WinMain(int64_t hInstance,
|
||||||
int64_t hPrevInstance,
|
int64_t hPrevInstance,
|
||||||
const char *lpCmdLine,
|
const char *lpCmdLine,
|
||||||
int nCmdShow) {
|
int nCmdShow) {
|
||||||
|
const char16_t *cmdline;
|
||||||
extern char os asm("__hostos");
|
extern char os asm("__hostos");
|
||||||
extern uint64_t ts asm("kStartTsc");
|
extern uint64_t ts asm("kStartTsc");
|
||||||
os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */
|
os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */
|
||||||
ts = rdtsc();
|
ts = rdtsc();
|
||||||
__nomultics = true;
|
__nomultics = true;
|
||||||
__pid = GetCurrentProcessId();
|
__pid = GetCurrentProcessId();
|
||||||
|
cmdline = GetCommandLine();
|
||||||
|
#ifdef SYSDEBUG
|
||||||
|
/* sloppy flag-only check for early initialization */
|
||||||
|
if (__strstr16(cmdline, u"--strace")) ++__strace;
|
||||||
|
#endif
|
||||||
STRACE("WinMain()");
|
STRACE("WinMain()");
|
||||||
MakeLongDoubleLongAgain();
|
MakeLongDoubleLongAgain();
|
||||||
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
||||||
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
||||||
WinMainNew();
|
WinMainNew(cmdline);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,8 @@ int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden;
|
||||||
|
|
||||||
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
||||||
size_t) hidden;
|
size_t) hidden;
|
||||||
ssize_t sys_sendto_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
|
||||||
void *, uint32_t) hidden;
|
uint32_t) hidden;
|
||||||
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
||||||
void *, uint32_t *) hidden;
|
void *, uint32_t *) hidden;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/winsock.h"
|
#include "libc/nt/winsock.h"
|
||||||
|
@ -40,6 +41,7 @@ static textwindows void WinSockCleanup(void) {
|
||||||
textwindows noasan void WinSockInit(void) {
|
textwindows noasan void WinSockInit(void) {
|
||||||
int rc;
|
int rc;
|
||||||
atexit(WinSockCleanup);
|
atexit(WinSockCleanup);
|
||||||
|
STRACE("WSAStartup()");
|
||||||
if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 ||
|
if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 ||
|
||||||
kNtWsaData.wVersion != VERSION) {
|
kNtWsaData.wVersion != VERSION) {
|
||||||
ExitProcess(123);
|
ExitProcess(123);
|
||||||
|
|
|
@ -58,10 +58,10 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
||||||
if (__isfdopen(fd)) {
|
if (__isfdopen(fd)) {
|
||||||
if (msg->msg_control) return einval(); /* control msg not supported */
|
if (msg->msg_control) return einval(); /* control msg not supported */
|
||||||
if (__isfdkind(fd, kFdSocket)) {
|
if (__isfdkind(fd, kFdSocket)) {
|
||||||
return sys_sendto_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, flags,
|
return sys_sendto_nt(fd, msg->msg_iov, msg->msg_iovlen, flags,
|
||||||
msg->msg_name, msg->msg_namelen);
|
msg->msg_name, msg->msg_namelen);
|
||||||
} else if (__isfdkind(fd, kFdFile)) {
|
} else if (__isfdkind(fd, kFdFile)) {
|
||||||
return sys_write_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, -1);
|
return sys_write_nt(fd, msg->msg_iov, msg->msg_iovlen, -1);
|
||||||
} else {
|
} else {
|
||||||
return enotsock();
|
return enotsock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,13 +30,13 @@
|
||||||
* @param fd must be a socket
|
* @param fd must be a socket
|
||||||
* @return number of bytes handed off, or -1 w/ errno
|
* @return number of bytes handed off, or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
textwindows ssize_t sys_sendto_nt(struct Fd *fd, const struct iovec *iov,
|
textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
||||||
size_t iovlen, uint32_t flags,
|
size_t iovlen, uint32_t flags,
|
||||||
void *opt_in_addr, uint32_t in_addrsize) {
|
void *opt_in_addr, uint32_t in_addrsize) {
|
||||||
uint32_t sent;
|
uint32_t sent;
|
||||||
struct NtIovec iovnt[16];
|
struct NtIovec iovnt[16];
|
||||||
if (WSASendTo(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &sent, flags,
|
if (WSASendTo(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen),
|
||||||
opt_in_addr, in_addrsize, NULL, NULL) != -1) {
|
&sent, flags, opt_in_addr, in_addrsize, NULL, NULL) != -1) {
|
||||||
return sent;
|
return sent;
|
||||||
} else {
|
} else {
|
||||||
return __winsockerr();
|
return __winsockerr();
|
||||||
|
|
|
@ -67,12 +67,12 @@ ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags,
|
||||||
} else {
|
} else {
|
||||||
if (__isfdopen(fd)) {
|
if (__isfdopen(fd)) {
|
||||||
if (__isfdkind(fd, kFdSocket)) {
|
if (__isfdkind(fd, kFdSocket)) {
|
||||||
return sys_sendto_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1,
|
return sys_sendto_nt(fd, (struct iovec[]){{buf, size}}, 1, flags,
|
||||||
flags, opt_addr, addrsize);
|
opt_addr, addrsize);
|
||||||
} else if (__isfdkind(fd, kFdFile)) { /* e.g. socketpair() */
|
} else if (__isfdkind(fd, kFdFile)) { /* e.g. socketpair() */
|
||||||
if (flags) return einval();
|
if (flags) return einval();
|
||||||
if (opt_addr) return eisconn();
|
if (opt_addr) return eisconn();
|
||||||
return sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1);
|
return sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1);
|
||||||
} else {
|
} else {
|
||||||
return enotsock();
|
return enotsock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/dirent.h"
|
#include "libc/calls/struct/dirent.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
@ -234,7 +235,6 @@ DIR *opendir(const char *name) {
|
||||||
struct Zipos *zip;
|
struct Zipos *zip;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (weaken(__zipos_get) && weaken(__zipos_parseuri)(name, &zipname) != -1) {
|
if (weaken(__zipos_get) && weaken(__zipos_parseuri)(name, &zipname) != -1) {
|
||||||
ZTRACE("__zipos_opendir(%`'s)", name);
|
|
||||||
if (weaken(__zipos_stat)(&zipname, &st) != -1) {
|
if (weaken(__zipos_stat)(&zipname, &st) != -1) {
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
zip = weaken(__zipos_get)();
|
zip = weaken(__zipos_get)();
|
||||||
|
@ -250,25 +250,25 @@ DIR *opendir(const char *name) {
|
||||||
}
|
}
|
||||||
res->zip.prefix[zipname.len] = '\0';
|
res->zip.prefix[zipname.len] = '\0';
|
||||||
res->zip.prefixlen = zipname.len;
|
res->zip.prefixlen = zipname.len;
|
||||||
return res;
|
|
||||||
} else {
|
} else {
|
||||||
errno = ENOTDIR;
|
errno = ENOTDIR;
|
||||||
return 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
res = 0;
|
||||||
}
|
}
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
res = NULL;
|
res = 0;
|
||||||
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) {
|
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) {
|
||||||
if (!(res = fdopendir(fd))) {
|
if (!(res = fdopendir(fd))) {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
} else {
|
} else {
|
||||||
return opendir_nt(name);
|
res = opendir_nt(name);
|
||||||
}
|
}
|
||||||
|
STRACE("opendir(%#s) → %p% m", name, res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -284,10 +284,11 @@ DIR *fdopendir(int fd) {
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
if (!(dir = calloc(1, sizeof(*dir)))) return NULL;
|
if (!(dir = calloc(1, sizeof(*dir)))) return NULL;
|
||||||
dir->fd = fd;
|
dir->fd = fd;
|
||||||
return dir;
|
|
||||||
} else {
|
} else {
|
||||||
return fdopendir_nt(fd);
|
dir = fdopendir_nt(fd);
|
||||||
}
|
}
|
||||||
|
STRACE("fdopendir(%d) → %p% m", fd, dir);
|
||||||
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -403,6 +404,7 @@ int closedir(DIR *dir) {
|
||||||
} else {
|
} else {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
STRACE("closedir(%p) → %d% m", dir, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +412,7 @@ int closedir(DIR *dir) {
|
||||||
* Returns offset into directory data.
|
* Returns offset into directory data.
|
||||||
*/
|
*/
|
||||||
long telldir(DIR *dir) {
|
long telldir(DIR *dir) {
|
||||||
|
STRACE("telldir(%p) → %d", dir, dir->tell);
|
||||||
return dir->tell;
|
return dir->tell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,9 +420,16 @@ long telldir(DIR *dir) {
|
||||||
* Returns file descriptor associated with DIR object.
|
* Returns file descriptor associated with DIR object.
|
||||||
*/
|
*/
|
||||||
int dirfd(DIR *dir) {
|
int dirfd(DIR *dir) {
|
||||||
if (dir->iszip) return eopnotsupp();
|
int rc;
|
||||||
if (IsWindows()) return eopnotsupp();
|
if (dir->iszip) {
|
||||||
return dir->fd;
|
rc = eopnotsupp();
|
||||||
|
} else if (IsWindows()) {
|
||||||
|
rc = eopnotsupp();
|
||||||
|
} else {
|
||||||
|
rc = dir->fd;
|
||||||
|
}
|
||||||
|
STRACE("dirfd(%p) → %d% m", dir, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -443,4 +453,5 @@ void rewinddir(DIR *dir) {
|
||||||
dir->isdone = true;
|
dir->isdone = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
STRACE("rewinddir(%p)", dir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,9 +56,9 @@ textstartup int __fflush_register(FILE *f) {
|
||||||
struct StdioFlush *sf;
|
struct StdioFlush *sf;
|
||||||
sf = &__fflush;
|
sf = &__fflush;
|
||||||
if (!sf->handles.p) {
|
if (!sf->handles.p) {
|
||||||
sf->handles.p = &sf->handles_initmem[0];
|
sf->handles.p = sf->handles_initmem;
|
||||||
pushmov(&sf->handles.n, ARRAYLEN(sf->handles_initmem));
|
pushmov(&sf->handles.n, ARRAYLEN(sf->handles_initmem));
|
||||||
__cxa_atexit(fflush, NULL, NULL);
|
__cxa_atexit(fflush, 0, 0);
|
||||||
}
|
}
|
||||||
for (i = sf->handles.i; i; --i) {
|
for (i = sf->handles.i; i; --i) {
|
||||||
if (!sf->handles.p[i - 1]) {
|
if (!sf->handles.p[i - 1]) {
|
||||||
|
@ -76,7 +76,7 @@ void __fflush_unregister(FILE *f) {
|
||||||
sf = pushpop(sf);
|
sf = pushpop(sf);
|
||||||
for (i = sf->handles.i; i; --i) {
|
for (i = sf->handles.i; i; --i) {
|
||||||
if (sf->handles.p[i - 1] == f) {
|
if (sf->handles.p[i - 1] == f) {
|
||||||
pushmov(&sf->handles.p[i - 1], NULL);
|
pushmov(&sf->handles.p[i - 1], 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ FILE *popen(const char *cmdline, const char *mode) {
|
||||||
if (pipe(pipefds) == -1) return NULL;
|
if (pipe(pipefds) == -1) return NULL;
|
||||||
fcntl(pipefds[dir], F_SETFD, FD_CLOEXEC);
|
fcntl(pipefds[dir], F_SETFD, FD_CLOEXEC);
|
||||||
if ((f = fdopen(pipefds[dir], mode))) {
|
if ((f = fdopen(pipefds[dir], mode))) {
|
||||||
switch ((pid = vfork())) {
|
switch ((pid = fork())) {
|
||||||
case 0:
|
case 0:
|
||||||
dup2(pipefds[!dir], !dir);
|
dup2(pipefds[!dir], !dir);
|
||||||
systemexec(cmdline);
|
systemexec(cmdline);
|
||||||
|
|
|
@ -45,7 +45,7 @@ int posix_spawn(int *pid, const char *path,
|
||||||
if (!(*pid = vfork())) {
|
if (!(*pid = vfork())) {
|
||||||
if (attrp) {
|
if (attrp) {
|
||||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) {
|
if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) {
|
||||||
if (setpgid(0, attrp->posix_attr_pgroup)) _exit(127);
|
if (setpgid(0, attrp->posix_attr_pgroup)) _Exit(127);
|
||||||
}
|
}
|
||||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) {
|
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) {
|
||||||
sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL);
|
sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL);
|
||||||
|
@ -60,7 +60,7 @@ int posix_spawn(int *pid, const char *path,
|
||||||
sigfillset(&allsigs);
|
sigfillset(&allsigs);
|
||||||
for (s = 0; sigismember(&allsigs, s); s++) {
|
for (s = 0; sigismember(&allsigs, s); s++) {
|
||||||
if (sigismember(&attrp->posix_attr_sigdefault, s)) {
|
if (sigismember(&attrp->posix_attr_sigdefault, s)) {
|
||||||
if (sigaction(s, &dfl, NULL) == -1) _exit(127);
|
if (sigaction(s, &dfl, NULL) == -1) _Exit(127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,28 +68,28 @@ int posix_spawn(int *pid, const char *path,
|
||||||
if (file_actions) {
|
if (file_actions) {
|
||||||
for (p = *file_actions; *p; p = strchr(p, ')') + 1) {
|
for (p = *file_actions; *p; p = strchr(p, ')') + 1) {
|
||||||
if (!strncmp(p, "close(", 6)) {
|
if (!strncmp(p, "close(", 6)) {
|
||||||
if (sscanf(p + 6, "%d)", &fd) != 1) _exit(127);
|
if (sscanf(p + 6, "%d)", &fd) != 1) _Exit(127);
|
||||||
if (close(fd) == -1) _exit(127);
|
if (close(fd) == -1) _Exit(127);
|
||||||
} else if (!strncmp(p, "dup2(", 5)) {
|
} else if (!strncmp(p, "dup2(", 5)) {
|
||||||
if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _exit(127);
|
if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _Exit(127);
|
||||||
if (dup2(fd, newfd) == -1) _exit(127);
|
if (dup2(fd, newfd) == -1) _Exit(127);
|
||||||
} else if (!strncmp(p, "open(", 5)) {
|
} else if (!strncmp(p, "open(", 5)) {
|
||||||
if (sscanf(p + 5, "%d,", &fd) != 1) _exit(127);
|
if (sscanf(p + 5, "%d,", &fd) != 1) _Exit(127);
|
||||||
p = strchr(p, ',') + 1;
|
p = strchr(p, ',') + 1;
|
||||||
q = strchr(p, '*');
|
q = strchr(p, '*');
|
||||||
if (!q || q - p + 1 > PATH_MAX) _exit(127);
|
if (!q || q - p + 1 > PATH_MAX) _Exit(127);
|
||||||
strncpy(opath, p, q - p);
|
strncpy(opath, p, q - p);
|
||||||
opath[q - p] = '\0';
|
opath[q - p] = '\0';
|
||||||
if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _exit(127);
|
if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _Exit(127);
|
||||||
if (close(fd) == -1 && errno != EBADF) _exit(127);
|
if (close(fd) == -1 && errno != EBADF) _Exit(127);
|
||||||
tempfd = open(opath, oflag, mode);
|
tempfd = open(opath, oflag, mode);
|
||||||
if (tempfd == -1) _exit(127);
|
if (tempfd == -1) _Exit(127);
|
||||||
if (tempfd != fd) {
|
if (tempfd != fd) {
|
||||||
if (dup2(tempfd, fd) == -1) _exit(127);
|
if (dup2(tempfd, fd) == -1) _Exit(127);
|
||||||
if (close(tempfd) == -1) _exit(127);
|
if (close(tempfd) == -1) _Exit(127);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,17 +97,17 @@ int posix_spawn(int *pid, const char *path,
|
||||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) {
|
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) {
|
||||||
if (sched_setscheduler(0, attrp->posix_attr_schedpolicy,
|
if (sched_setscheduler(0, attrp->posix_attr_schedpolicy,
|
||||||
&attrp->posix_attr_schedparam) == -1) {
|
&attrp->posix_attr_schedparam) == -1) {
|
||||||
_exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) {
|
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) {
|
||||||
if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) {
|
if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) {
|
||||||
_exit(127);
|
_Exit(127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
execve(path, argv, envp);
|
execve(path, argv, envp);
|
||||||
_exit(127);
|
_Exit(127);
|
||||||
} else {
|
} else {
|
||||||
if (*pid == -1) return errno;
|
if (*pid == -1) return errno;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,19 +29,17 @@
|
||||||
* @param fd is vetted by close()
|
* @param fd is vetted by close()
|
||||||
*/
|
*/
|
||||||
int __zipos_close(int fd) {
|
int __zipos_close(int fd) {
|
||||||
|
int rc;
|
||||||
struct ZiposHandle *h;
|
struct ZiposHandle *h;
|
||||||
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
|
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()) {
|
if (!IsWindows()) {
|
||||||
sys_close(fd);
|
rc = sys_close(fd);
|
||||||
} else {
|
} else {
|
||||||
CloseHandle(h->handle);
|
rc = 0; /* no system file descriptor needed on nt */
|
||||||
}
|
}
|
||||||
if (!__vforked) {
|
if (!__vforked) {
|
||||||
free(h->freeme);
|
free(h->freeme);
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,30 +28,23 @@
|
||||||
#define HANDLE ((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle)
|
#define HANDLE ((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle)
|
||||||
|
|
||||||
int __zipos_fcntl(int fd, int cmd, uintptr_t arg) {
|
int __zipos_fcntl(int fd, int cmd, uintptr_t arg) {
|
||||||
|
int rc;
|
||||||
if (cmd == F_GETFD) {
|
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) {
|
if (g_fds.p[fd].flags & O_CLOEXEC) {
|
||||||
return FD_CLOEXEC;
|
rc = FD_CLOEXEC;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
} else if (cmd == F_SETFD) {
|
} 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) {
|
if (arg & FD_CLOEXEC) {
|
||||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||||
return FD_CLOEXEC;
|
rc = FD_CLOEXEC;
|
||||||
} else {
|
} else {
|
||||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||||
return 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZTRACE("__zipos_fcntl(%.*s, %d, 0x%x) → EINVAL",
|
rc = einval();
|
||||||
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
|
|
||||||
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), cmd, arg);
|
|
||||||
return einval();
|
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,13 +29,10 @@
|
||||||
*/
|
*/
|
||||||
int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) {
|
int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) {
|
||||||
int rc;
|
int rc;
|
||||||
if (!st) return efault();
|
if (st) {
|
||||||
if (!(rc = __zipos_stat_impl(__zipos_get(), h->cfile, st))) {
|
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;
|
|
||||||
} else {
|
} else {
|
||||||
return rc;
|
rc = efault();
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/alloca.h"
|
#include "libc/mem/alloca.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -84,16 +85,10 @@ struct Zipos *__zipos_get(void) {
|
||||||
zipos.cdir = cdir;
|
zipos.cdir = cdir;
|
||||||
} else {
|
} else {
|
||||||
munmap(map, size);
|
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);
|
close(fd);
|
||||||
} else {
|
|
||||||
ZTRACE("__zipos_get(%s) → open %s", program_executable_name,
|
|
||||||
strerror(errno));
|
|
||||||
}
|
}
|
||||||
once = true;
|
once = true;
|
||||||
sigprocmask(SIG_SETMASK, &old, 0);
|
sigprocmask(SIG_SETMASK, &old, 0);
|
||||||
|
|
|
@ -30,26 +30,25 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
|
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
|
||||||
int64_t i;
|
int64_t rc;
|
||||||
switch (whence) {
|
switch (whence) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
i = offset;
|
rc = offset;
|
||||||
break;
|
break;
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
i = h->pos + offset;
|
rc = h->pos + offset;
|
||||||
break;
|
break;
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
i = h->size - offset;
|
rc = h->size - offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return einval();
|
rc = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (i < 0) {
|
if (rc >= 0) {
|
||||||
return einval();
|
h->pos = rc;
|
||||||
|
} else {
|
||||||
|
rc = einval();
|
||||||
}
|
}
|
||||||
h->pos = i;
|
return rc;
|
||||||
ZTRACE("__zipos_lseek(%.*s, %d)",
|
|
||||||
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
|
|
||||||
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), i);
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ int __zipos_notat(int dirfd, const char *path) {
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (!path) return efault();
|
if (!path) return efault();
|
||||||
if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) {
|
if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) {
|
||||||
ZTRACE("__zipos_notat(%d, %s) → EINVAL", dirfd, path);
|
|
||||||
return einval();
|
return einval();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -124,7 +124,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
||||||
h->mem = NULL;
|
h->mem = NULL;
|
||||||
}
|
}
|
||||||
if (h->mem) {
|
if (h->mem) {
|
||||||
if ((fd = dup(2)) != -1) {
|
if ((fd = IsWindows() ? __reservefd() : dup(2)) != -1) {
|
||||||
if (__ensurefds(fd) != -1) {
|
if (__ensurefds(fd) != -1) {
|
||||||
h->handle = g_fds.p[fd].handle;
|
h->handle = g_fds.p[fd].handle;
|
||||||
g_fds.p[fd].kind = kFdZip;
|
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
|
* @note don't call open() from signal handlers
|
||||||
*/
|
*/
|
||||||
int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
|
int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
|
||||||
int fd;
|
int rc;
|
||||||
ssize_t cf;
|
ssize_t cf;
|
||||||
sigset_t oldmask;
|
sigset_t oldmask;
|
||||||
struct Zipos *zipos;
|
struct Zipos *zipos;
|
||||||
if ((flags & O_ACCMODE) != O_RDONLY) return einval();
|
if ((flags & O_ACCMODE) == O_RDONLY) {
|
||||||
if ((zipos = __zipos_get())) {
|
if ((zipos = __zipos_get())) {
|
||||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||||
fd = __zipos_load(zipos, cf, flags, mode);
|
rc = __zipos_load(zipos, cf, flags, mode);
|
||||||
ZTRACE("__zipos_open(%.*s)", name->len, name->path);
|
} else {
|
||||||
|
rc = enoent();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ZTRACE("__zipos_open(%.*s) enoent", name->len, name->path);
|
rc = enoexec();
|
||||||
fd = enoent();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fd = enoexec();
|
rc = einval();
|
||||||
ZTRACE("__zipos_open(%.*s) enoexec", name->len, name->path);
|
|
||||||
}
|
}
|
||||||
return fd;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,5 @@ ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov,
|
||||||
memcpy(iov[i].iov_base, h->mem + y, b);
|
memcpy(iov[i].iov_base, h->mem + y, b);
|
||||||
}
|
}
|
||||||
if (opt_offset == -1) h->pos = y;
|
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;
|
return y - x;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,18 +28,21 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int __zipos_stat(const struct ZiposUri *name, struct stat *st) {
|
int __zipos_stat(const struct ZiposUri *name, struct stat *st) {
|
||||||
|
int rc;
|
||||||
ssize_t cf;
|
ssize_t cf;
|
||||||
struct Zipos *zipos;
|
struct Zipos *zipos;
|
||||||
if (!st) return efault();
|
if (st) {
|
||||||
if ((zipos = __zipos_get())) {
|
if ((zipos = __zipos_get())) {
|
||||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||||
return __zipos_stat_impl(zipos, cf, st);
|
rc = __zipos_stat_impl(zipos, cf, st);
|
||||||
|
} else {
|
||||||
|
rc = enoent();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ZTRACE("__zipos_stat(%.*s) -> enoent", name->len, name->path);
|
rc = enoexec();
|
||||||
return enoent();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZTRACE("__zipos_stat(%.*s) → enoexec", name->len, name->path);
|
rc = efault();
|
||||||
return enoexec();
|
|
||||||
}
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
||||||
#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/strace.internal.h"
|
|
||||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
#if DEBUGSYS
|
|
||||||
#define ZTRACE(FMT, ...) kprintf("ZIP: " FMT "\n", ##__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define ZTRACE(FMT, ...) (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct stat;
|
struct stat;
|
||||||
struct iovec;
|
struct iovec;
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,15 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
#include "libc/fmt/fmt.h"
|
||||||
#include "libc/nt/errors.h"
|
#include "libc/nt/errors.h"
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
TEST(__dos2errno, test) {
|
TEST(__dos2errno, test) {
|
||||||
|
EXPECT_EQ(0, __dos2errno(0));
|
||||||
EXPECT_EQ(EACCES, __dos2errno(kNtErrorSectorNotFound));
|
EXPECT_EQ(EACCES, __dos2errno(kNtErrorSectorNotFound));
|
||||||
EXPECT_EQ(EADDRNOTAVAIL, __dos2errno(kNtErrorInvalidNetname));
|
EXPECT_EQ(EADDRNOTAVAIL, __dos2errno(kNtErrorInvalidNetname));
|
||||||
}
|
}
|
13
third_party/make/lib/dup2.c
vendored
13
third_party/make/lib/dup2.c
vendored
|
@ -28,19 +28,6 @@
|
||||||
|
|
||||||
# if defined _WIN32 && ! defined __CYGWIN__
|
# if defined _WIN32 && ! defined __CYGWIN__
|
||||||
|
|
||||||
/* Get declarations of the native Windows API functions. */
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
|
||||||
# include "msvc-inval.h"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Get _get_osfhandle. */
|
|
||||||
# if GNULIB_MSVC_NOTHROW
|
|
||||||
# include "msvc-nothrow.h"
|
|
||||||
# else
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||||
static int
|
static int
|
||||||
dup2_nothrow (int fd, int desired_fd)
|
dup2_nothrow (int fd, int desired_fd)
|
||||||
|
|
214
third_party/make/lib/getprogname.c
vendored
214
third_party/make/lib/getprogname.c
vendored
|
@ -1,4 +1,3 @@
|
||||||
/* clang-format off */
|
|
||||||
/* Program name management.
|
/* Program name management.
|
||||||
Copyright (C) 2016-2020 Free Software Foundation, Inc.
|
Copyright (C) 2016-2020 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
@ -15,228 +14,17 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
#include "third_party/make/src/config.h"
|
#include "third_party/make/src/config.h"
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "third_party/make/lib/getprogname.h"
|
#include "third_party/make/lib/getprogname.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef _AIX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __MVS__
|
|
||||||
# ifndef _OPEN_SYS
|
|
||||||
# define _OPEN_SYS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __hpux
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __sgi
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "third_party/make/lib/dirname.h"
|
#include "third_party/make/lib/dirname.h"
|
||||||
|
|
||||||
#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
|
|
||||||
char const *
|
char const *
|
||||||
getprogname (void)
|
getprogname (void)
|
||||||
{
|
{
|
||||||
# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
|
|
||||||
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
|
|
||||||
return program_invocation_short_name;
|
return program_invocation_short_name;
|
||||||
# elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
|
|
||||||
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
|
|
||||||
return last_component (program_invocation_name);
|
|
||||||
# elif HAVE_GETEXECNAME /* Solaris */
|
|
||||||
/* https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */
|
|
||||||
const char *p = getexecname ();
|
|
||||||
if (!p)
|
|
||||||
p = "?";
|
|
||||||
return last_component (p);
|
|
||||||
# elif HAVE_DECL___ARGV /* mingw, MSVC */
|
|
||||||
/* https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv */
|
|
||||||
const char *p = __argv && __argv[0] ? __argv[0] : "?";
|
|
||||||
return last_component (p);
|
|
||||||
# elif HAVE_VAR___PROGNAME /* OpenBSD, Android, QNX */
|
|
||||||
/* https://man.openbsd.org/style.9 */
|
|
||||||
/* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */
|
|
||||||
/* Be careful to declare this only when we absolutely need it
|
|
||||||
(OpenBSD 5.1), rather than when it's available. Otherwise,
|
|
||||||
its mere declaration makes program_invocation_short_name
|
|
||||||
malfunction (have zero length) with Fedora 25's glibc. */
|
|
||||||
extern char *__progname;
|
|
||||||
const char *p = __progname;
|
|
||||||
# if defined __ANDROID__
|
|
||||||
return last_component (p);
|
|
||||||
# else
|
|
||||||
return p && p[0] ? p : "?";
|
|
||||||
# endif
|
|
||||||
# elif _AIX /* AIX */
|
|
||||||
/* Idea by Bastien ROUCARIÈS,
|
|
||||||
https://lists.gnu.org/r/bug-gnulib/2010-12/msg00095.html
|
|
||||||
Reference: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/getprocs.htm
|
|
||||||
*/
|
|
||||||
static char *p;
|
|
||||||
static int first = 1;
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
first = 0;
|
|
||||||
pid_t pid = getpid ();
|
|
||||||
struct procentry64 procs;
|
|
||||||
p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1)
|
|
||||||
? strdup (procs.pi_comm)
|
|
||||||
: NULL);
|
|
||||||
if (!p)
|
|
||||||
p = "?";
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
# elif defined __hpux
|
|
||||||
static char *p;
|
|
||||||
static int first = 1;
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
first = 0;
|
|
||||||
pid_t pid = getpid ();
|
|
||||||
struct pst_status status;
|
|
||||||
if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
|
|
||||||
{
|
|
||||||
char *ucomm = status.pst_ucomm;
|
|
||||||
char *cmd = status.pst_cmd;
|
|
||||||
if (strlen (ucomm) < PST_UCOMMLEN - 1)
|
|
||||||
p = ucomm;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* ucomm is truncated to length PST_UCOMMLEN - 1.
|
|
||||||
Look at cmd instead. */
|
|
||||||
char *space = strchr (cmd, ' ');
|
|
||||||
if (space != NULL)
|
|
||||||
*space = '\0';
|
|
||||||
p = strrchr (cmd, '/');
|
|
||||||
if (p != NULL)
|
|
||||||
p++;
|
|
||||||
else
|
|
||||||
p = cmd;
|
|
||||||
if (strlen (p) > PST_UCOMMLEN - 1
|
|
||||||
&& memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
|
|
||||||
/* p is less truncated than ucomm. */
|
|
||||||
;
|
|
||||||
else
|
|
||||||
p = ucomm;
|
|
||||||
}
|
|
||||||
p = strdup (p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# if !defined __LP64__
|
|
||||||
/* Support for 32-bit programs running in 64-bit HP-UX.
|
|
||||||
The documented way to do this is to use the same source code
|
|
||||||
as above, but in a compilation unit where '#define _PSTAT64 1'
|
|
||||||
is in effect. I prefer a single compilation unit; the struct
|
|
||||||
size and the offsets are not going to change. */
|
|
||||||
char status64[1216];
|
|
||||||
if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
|
|
||||||
{
|
|
||||||
char *ucomm = status64 + 288;
|
|
||||||
char *cmd = status64 + 168;
|
|
||||||
if (strlen (ucomm) < PST_UCOMMLEN - 1)
|
|
||||||
p = ucomm;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* ucomm is truncated to length PST_UCOMMLEN - 1.
|
|
||||||
Look at cmd instead. */
|
|
||||||
char *space = strchr (cmd, ' ');
|
|
||||||
if (space != NULL)
|
|
||||||
*space = '\0';
|
|
||||||
p = strrchr (cmd, '/');
|
|
||||||
if (p != NULL)
|
|
||||||
p++;
|
|
||||||
else
|
|
||||||
p = cmd;
|
|
||||||
if (strlen (p) > PST_UCOMMLEN - 1
|
|
||||||
&& memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
|
|
||||||
/* p is less truncated than ucomm. */
|
|
||||||
;
|
|
||||||
else
|
|
||||||
p = ucomm;
|
|
||||||
}
|
|
||||||
p = strdup (p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
if (!p)
|
|
||||||
p = "?";
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
# elif __MVS__ /* z/OS */
|
|
||||||
/* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */
|
|
||||||
static char *p = "?";
|
|
||||||
static int first = 1;
|
|
||||||
if (first)
|
|
||||||
{
|
|
||||||
pid_t pid = getpid ();
|
|
||||||
int token;
|
|
||||||
W_PSPROC buf;
|
|
||||||
first = 0;
|
|
||||||
memset (&buf, 0, sizeof(buf));
|
|
||||||
buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG);
|
|
||||||
buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN);
|
|
||||||
buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN);
|
|
||||||
if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr)
|
|
||||||
{
|
|
||||||
for (token = 0; token >= 0;
|
|
||||||
token = w_getpsent (token, &buf, sizeof(buf)))
|
|
||||||
{
|
|
||||||
if (token > 0 && buf.ps_pid == pid)
|
|
||||||
{
|
|
||||||
char *s = strdup (last_component (buf.ps_pathptr));
|
|
||||||
if (s)
|
|
||||||
p = s;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free (buf.ps_cmdptr);
|
|
||||||
free (buf.ps_conttyptr);
|
|
||||||
free (buf.ps_pathptr);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
# elif defined __sgi /* IRIX */
|
|
||||||
char filename[50];
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
sprintf (filename, "/proc/pinfo/%d", (int) getpid ());
|
|
||||||
fd = open (filename, O_RDONLY);
|
|
||||||
if (0 <= fd)
|
|
||||||
{
|
|
||||||
prpsinfo_t buf;
|
|
||||||
int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
|
|
||||||
close (fd);
|
|
||||||
if (ioctl_ok)
|
|
||||||
{
|
|
||||||
char *name = buf.pr_fname;
|
|
||||||
size_t namesize = sizeof buf.pr_fname;
|
|
||||||
/* It may not be NUL-terminated. */
|
|
||||||
char *namenul = memchr (name, '\0', namesize);
|
|
||||||
size_t namelen = namenul ? namenul - name : namesize;
|
|
||||||
char *namecopy = malloc (namelen + 1);
|
|
||||||
if (namecopy)
|
|
||||||
{
|
|
||||||
namecopy[namelen] = '\0';
|
|
||||||
return memcpy (namecopy, name, namelen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
# else
|
|
||||||
# error "getprogname module not ported to this OS"
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hey Emacs!
|
* Hey Emacs!
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
|
|
1415
third_party/make/lib/glob.c
vendored
1415
third_party/make/lib/glob.c
vendored
File diff suppressed because it is too large
Load diff
54
third_party/make/lib/malloc.c
vendored
54
third_party/make/lib/malloc.c
vendored
|
@ -1,54 +0,0 @@
|
||||||
/* clang-format off */
|
|
||||||
/* malloc() function that is glibc compatible.
|
|
||||||
|
|
||||||
Copyright (C) 1997-1998, 2006-2007, 2009-2020 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 3, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
/* written by Jim Meyering and Bruno Haible */
|
|
||||||
|
|
||||||
#define _GL_USE_STDLIB_ALLOC 1
|
|
||||||
/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */
|
|
||||||
#ifdef malloc
|
|
||||||
# define NEED_MALLOC_GNU 1
|
|
||||||
# undef malloc
|
|
||||||
/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */
|
|
||||||
#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU
|
|
||||||
# define NEED_MALLOC_GNU 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Allocate an N-byte block of memory from the heap.
|
|
||||||
If N is zero, allocate a 1-byte block. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
rpl_malloc (size_t n)
|
|
||||||
{
|
|
||||||
void *result;
|
|
||||||
|
|
||||||
#if NEED_MALLOC_GNU
|
|
||||||
if (n == 0)
|
|
||||||
n = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = malloc (n);
|
|
||||||
|
|
||||||
#if !HAVE_MALLOC_POSIX
|
|
||||||
if (result == NULL)
|
|
||||||
errno = ENOMEM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
|
@ -477,7 +477,6 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
||||||
LOGIFNEG1(sigaction(SIGQUIT, &savequit, NULL));
|
LOGIFNEG1(sigaction(SIGQUIT, &savequit, NULL));
|
||||||
LOGIFNEG1(sigprocmask(SIG_SETMASK, &savemask, NULL));
|
LOGIFNEG1(sigprocmask(SIG_SETMASK, &savemask, NULL));
|
||||||
free(pids);
|
free(pids);
|
||||||
kprintf("nocommit%n");
|
|
||||||
return exitcode;
|
return exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1240,7 +1240,10 @@ static void WaitAll(void) {
|
||||||
if ((pid = wait4(-1, &ws, 0, &ru)) != -1) {
|
if ((pid = wait4(-1, &ws, 0, &ru)) != -1) {
|
||||||
HandleWorkerExit(pid, ws, &ru);
|
HandleWorkerExit(pid, ws, &ru);
|
||||||
} else {
|
} else {
|
||||||
if (errno == ECHILD) break;
|
if (errno == ECHILD) {
|
||||||
|
errno = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
if (killed) {
|
if (killed) {
|
||||||
killed = false;
|
killed = false;
|
||||||
|
@ -1248,6 +1251,7 @@ static void WaitAll(void) {
|
||||||
WARNF("(srvr) redbean shall terminate harder");
|
WARNF("(srvr) redbean shall terminate harder");
|
||||||
LOGIFNEG1(kill(0, SIGTERM));
|
LOGIFNEG1(kill(0, SIGTERM));
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DIEF("(srvr) wait error: %m");
|
DIEF("(srvr) wait error: %m");
|
||||||
|
@ -1267,8 +1271,14 @@ static void ReapZombies(void) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (errno == ECHILD) break;
|
if (errno == ECHILD) {
|
||||||
if (errno == EINTR) continue;
|
errno = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
DIEF("(srvr) wait error: %m");
|
DIEF("(srvr) wait error: %m");
|
||||||
}
|
}
|
||||||
} while (!terminated);
|
} while (!terminated);
|
||||||
|
@ -1298,6 +1308,7 @@ static ssize_t WritevAll(int fd, struct iovec *iov, int iovlen) {
|
||||||
}
|
}
|
||||||
} while (wrote);
|
} while (wrote);
|
||||||
} else if (errno == EINTR) {
|
} else if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
LockInc(&shared->c.writeinterruputs);
|
LockInc(&shared->c.writeinterruputs);
|
||||||
if (killed || (meltdown && nowl() - startread > 2)) {
|
if (killed || (meltdown && nowl() - startread > 2)) {
|
||||||
return total ? total : -1;
|
return total ? total : -1;
|
||||||
|
@ -1319,8 +1330,10 @@ static int TlsFlush(struct TlsBio *bio, const unsigned char *buf, size_t len) {
|
||||||
if (WritevAll(bio->fd, v, 2) != -1) {
|
if (WritevAll(bio->fd, v, 2) != -1) {
|
||||||
if (bio->c > 0) bio->c = 0;
|
if (bio->c > 0) bio->c = 0;
|
||||||
} else if (errno == EINTR) {
|
} else if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||||
} else if (errno == EAGAIN) {
|
} else if (errno == EAGAIN) {
|
||||||
|
errno = 0;
|
||||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||||
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
||||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||||
|
@ -1363,8 +1376,10 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
||||||
v[1].iov_len = sizeof(bio->t);
|
v[1].iov_len = sizeof(bio->t);
|
||||||
while ((r = readv(bio->fd, v, 2)) == -1) {
|
while ((r = readv(bio->fd, v, 2)) == -1) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||||
} else if (errno == EAGAIN) {
|
} else if (errno == EAGAIN) {
|
||||||
|
errno = 0;
|
||||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||||
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
||||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||||
|
@ -1406,6 +1421,7 @@ static ssize_t SslRead(int fd, void *buf, size_t size) {
|
||||||
} else if (rc == MBEDTLS_ERR_SSL_WANT_READ) {
|
} else if (rc == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||||
errno = EINTR;
|
errno = EINTR;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
|
errno = 0;
|
||||||
} else {
|
} else {
|
||||||
WARNF("(ssl) %s SslRead error -0x%04x", DescribeClient(), -rc);
|
WARNF("(ssl) %s SslRead error -0x%04x", DescribeClient(), -rc);
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
|
@ -2249,6 +2265,7 @@ static ssize_t Send(struct iovec *iov, int iovlen) {
|
||||||
} else if (errno == EAGAIN) {
|
} else if (errno == EAGAIN) {
|
||||||
LockInc(&shared->c.writetimeouts);
|
LockInc(&shared->c.writetimeouts);
|
||||||
WARNF("(rsp) %s write timeout", DescribeClient());
|
WARNF("(rsp) %s write timeout", DescribeClient());
|
||||||
|
errno = 0;
|
||||||
} else {
|
} else {
|
||||||
LockInc(&shared->c.writeerrors);
|
LockInc(&shared->c.writeerrors);
|
||||||
WARNF("(rsp) %s write error: %m", DescribeClient());
|
WARNF("(rsp) %s write error: %m", DescribeClient());
|
||||||
|
@ -2662,6 +2679,7 @@ static void LaunchBrowser(const char *path) {
|
||||||
}
|
}
|
||||||
while (wait4(pid, &ws, 0, 0) == -1) {
|
while (wait4(pid, &ws, 0, 0) == -1) {
|
||||||
CHECK_EQ(EINTR, errno);
|
CHECK_EQ(EINTR, errno);
|
||||||
|
errno = 0;
|
||||||
}
|
}
|
||||||
sigaction(SIGINT, &saveint, 0);
|
sigaction(SIGINT, &saveint, 0);
|
||||||
sigaction(SIGQUIT, &savequit, 0);
|
sigaction(SIGQUIT, &savequit, 0);
|
||||||
|
@ -5941,6 +5959,7 @@ static ssize_t SendString(const char *s) {
|
||||||
if ((rc = writer(client, &iov, 1)) != -1 || errno != EINTR) {
|
if ((rc = writer(client, &iov, 1)) != -1 || errno != EINTR) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6132,6 +6151,7 @@ static char *OpenAsset(struct Asset *a) {
|
||||||
return HandleMapFailed(a, fd);
|
return HandleMapFailed(a, fd);
|
||||||
}
|
}
|
||||||
} else if (errno == EINTR) {
|
} else if (errno == EINTR) {
|
||||||
|
errno = 0;
|
||||||
goto OpenAgain;
|
goto OpenAgain;
|
||||||
} else {
|
} else {
|
||||||
return HandleOpenFail(a);
|
return HandleOpenFail(a);
|
||||||
|
@ -6639,7 +6659,6 @@ static bool StreamResponse(char *p) {
|
||||||
static bool HandleMessageAcutal(void) {
|
static bool HandleMessageAcutal(void) {
|
||||||
int rc;
|
int rc;
|
||||||
char *p;
|
char *p;
|
||||||
g_syscount = 0;
|
|
||||||
if ((rc = ParseHttpMessage(&msg, inbuf.p, amtread)) != -1) {
|
if ((rc = ParseHttpMessage(&msg, inbuf.p, amtread)) != -1) {
|
||||||
if (!rc) return false;
|
if (!rc) return false;
|
||||||
hdrsize = rc;
|
hdrsize = rc;
|
||||||
|
@ -6769,6 +6788,7 @@ static void HandleMessages(void) {
|
||||||
}
|
}
|
||||||
} else if (errno == EINTR) {
|
} else if (errno == EINTR) {
|
||||||
LockInc(&shared->c.readinterrupts);
|
LockInc(&shared->c.readinterrupts);
|
||||||
|
errno = 0;
|
||||||
} else if (errno == EAGAIN) {
|
} else if (errno == EAGAIN) {
|
||||||
LockInc(&shared->c.readtimeouts);
|
LockInc(&shared->c.readtimeouts);
|
||||||
if (amtread) SendTimeout();
|
if (amtread) SendTimeout();
|
||||||
|
@ -6943,6 +6963,7 @@ static void HandleConnection(size_t i) {
|
||||||
} else {
|
} else {
|
||||||
DIEF("(srvr) %s accept error: %m", DescribeServer());
|
DIEF("(srvr) %s accept error: %m", DescribeServer());
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandlePoll(void) {
|
static void HandlePoll(void) {
|
||||||
|
@ -6965,6 +6986,7 @@ static void HandlePoll(void) {
|
||||||
} else {
|
} else {
|
||||||
DIEF("(srvr) poll error: %m");
|
DIEF("(srvr) poll error: %m");
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RestoreApe(void) {
|
static void RestoreApe(void) {
|
||||||
|
|
Loading…
Reference in a new issue