mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 08:12:28 +00:00
Make improvements
- You can now run `make -j8 toolchain` on Windows - You can now run `make -j` on MacOS ARM64 and BSD OSes - You can now use our Emacs dev environment on MacOS/Windows - Fix bug where the x16 register was being corrupted by --ftrace - The programs under build/bootstrap/ are updated as fat binaries - The Makefile now explains how to download cosmocc-0.0.12 toolchain - The build scripts under bin/ now support "cosmo" branded toolchains - stat() now goes faster on Windows (shaves 100ms off `make` latency) - Code cleanup and added review on the Windows signal checking code - posix_spawnattr_setrlimit() now works around MacOS ARM64 bugs - Landlock Make now favors posix_spawn() on non-Linux/OpenBSD - posix_spawn() now has better --strace logging on Windows - fstatat() can now avoid EACCES in more cases on Windows - fchmod() can now change the readonly bit on Windows
This commit is contained in:
parent
06c6baaf50
commit
c9fecf3a55
109 changed files with 1188 additions and 454 deletions
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describebacktrace.internal.h"
|
||||
|
@ -28,9 +29,11 @@
|
|||
*/
|
||||
void __assert_fail(const char *expr, const char *file, int line) {
|
||||
char ibuf[12];
|
||||
sigset_t m = __sig_block();
|
||||
FormatInt32(ibuf, line);
|
||||
tinyprint(2, file, ":", ibuf, ": assert(", expr, ") failed (",
|
||||
program_invocation_short_name, " ",
|
||||
DescribeBacktrace(__builtin_frame_address(0)), ")\n", NULL);
|
||||
__sig_unblock(m);
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
|
||||
#include "libc/thread/thread.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
|
@ -26,23 +27,6 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
// code size optimization
|
||||
// <sync libc/sysv/consts.sh>
|
||||
#define _O_APPEND 0x00000400 // kNtFileAppendData
|
||||
#define _O_CREAT 0x00000040 // kNtOpenAlways
|
||||
#define _O_EXCL 0x00000080 // kNtCreateNew
|
||||
#define _O_TRUNC 0x00000200 // kNtCreateAlways
|
||||
#define _O_DIRECTORY 0x00010000 // kNtFileFlagBackupSemantics
|
||||
#define _O_UNLINK 0x04000100 // kNtFileAttributeTemporary|DeleteOnClose
|
||||
#define _O_DIRECT 0x00004000 // kNtFileFlagNoBuffering
|
||||
#define _O_NONBLOCK 0x00000800 // kNtFileFlagWriteThrough (not sent to win32)
|
||||
#define _O_RANDOM 0x80000000 // kNtFileFlagRandomAccess
|
||||
#define _O_SEQUENTIAL 0x40000000 // kNtFileFlagSequentialScan
|
||||
#define _O_COMPRESSED 0x20000000 // kNtFileAttributeCompressed
|
||||
#define _O_INDEXED 0x10000000 // !kNtFileAttributeNotContentIndexed
|
||||
#define _O_CLOEXEC 0x00080000
|
||||
// </sync libc/sysv/consts.sh>
|
||||
|
||||
textwindows int GetNtOpenFlags(int flags, int mode, uint32_t *out_perm,
|
||||
uint32_t *out_share, uint32_t *out_disp,
|
||||
uint32_t *out_attr) {
|
||||
|
|
22
libc/calls/createfileflags.internal.h
Normal file
22
libc/calls/createfileflags.internal.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_CREATEFILEFLAGS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_CREATEFILEFLAGS_INTERNAL_H_
|
||||
|
||||
// code size optimization
|
||||
// <sync libc/sysv/consts.sh>
|
||||
#define _O_APPEND 0x00000400 // kNtFileAppendData
|
||||
#define _O_CREAT 0x00000040 // kNtOpenAlways
|
||||
#define _O_EXCL 0x00000080 // kNtCreateNew
|
||||
#define _O_TRUNC 0x00000200 // kNtCreateAlways
|
||||
#define _O_DIRECTORY 0x00010000 // kNtFileFlagBackupSemantics
|
||||
#define _O_UNLINK 0x04000100 // kNtFileAttributeTemporary|DeleteOnClose
|
||||
#define _O_DIRECT 0x00004000 // kNtFileFlagNoBuffering
|
||||
#define _O_NONBLOCK 0x00000800 // kNtFileFlagWriteThrough (not sent to win32)
|
||||
#define _O_RANDOM 0x80000000 // kNtFileFlagRandomAccess
|
||||
#define _O_SEQUENTIAL 0x40000000 // kNtFileFlagSequentialScan
|
||||
#define _O_COMPRESSED 0x20000000 // kNtFileAttributeCompressed
|
||||
#define _O_INDEXED 0x10000000 // !kNtFileAttributeNotContentIndexed
|
||||
#define _O_NOFOLLOW 0x00020000 // kNtFileFlagOpenReparsePoint
|
||||
#define _O_CLOEXEC 0x00080000
|
||||
// </sync libc/sysv/consts.sh>
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_CREATEFILEFLAGS_INTERNAL_H_ */
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
|
@ -65,10 +66,10 @@ static textwindows int sys_dup_nt_impl(int oldfd, int newfd, int flags,
|
|||
kNtDuplicateSameAccess)) {
|
||||
g_fds.p[newfd] = g_fds.p[oldfd];
|
||||
g_fds.p[newfd].handle = handle;
|
||||
if (flags & O_CLOEXEC) {
|
||||
g_fds.p[newfd].flags |= O_CLOEXEC;
|
||||
if (flags & _O_CLOEXEC) {
|
||||
g_fds.p[newfd].flags |= _O_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[newfd].flags &= ~O_CLOEXEC;
|
||||
g_fds.p[newfd].flags &= ~_O_CLOEXEC;
|
||||
}
|
||||
rc = newfd;
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
|
@ -41,17 +42,17 @@ static textwindows int sys_fadvise_nt_impl(int fd, uint64_t offset,
|
|||
h1 = g_fds.p[fd].handle;
|
||||
mode = g_fds.p[fd].mode;
|
||||
flags = g_fds.p[fd].flags;
|
||||
flags &= ~(O_SEQUENTIAL | O_RANDOM);
|
||||
flags &= ~(_O_SEQUENTIAL | _O_RANDOM);
|
||||
|
||||
switch (advice) {
|
||||
case MADV_NORMAL:
|
||||
break;
|
||||
case MADV_RANDOM:
|
||||
flags |= O_RANDOM;
|
||||
flags |= _O_RANDOM;
|
||||
break;
|
||||
case MADV_WILLNEED:
|
||||
case MADV_SEQUENTIAL:
|
||||
flags |= O_SEQUENTIAL;
|
||||
flags |= _O_SEQUENTIAL;
|
||||
break;
|
||||
default:
|
||||
return einval();
|
||||
|
|
57
libc/calls/fchmod-nt.c
Normal file
57
libc/calls/fchmod-nt.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/struct/filebasicinfo.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_fchmod_nt(int fd, uint32_t mode) {
|
||||
|
||||
// validate file descriptor
|
||||
if (fd + 0u >= g_fds.n) return ebadf();
|
||||
if (g_fds.p[fd].kind == kFdEmpty) return ebadf();
|
||||
|
||||
// get current information
|
||||
struct NtFileBasicInfo fbi;
|
||||
if (!GetFileInformationByHandleEx(g_fds.p[fd].handle, kNtFileBasicInfo, &fbi,
|
||||
sizeof(fbi))) {
|
||||
return __winerr();
|
||||
}
|
||||
|
||||
// change attributes
|
||||
if (mode & 0222) {
|
||||
fbi.FileAttributes &= ~kNtFileAttributeReadonly;
|
||||
} else {
|
||||
fbi.FileAttributes |= kNtFileAttributeReadonly;
|
||||
}
|
||||
|
||||
// set new attributes
|
||||
if (!SetFileInformationByHandle(g_fds.p[fd].handle, kNtFileBasicInfo, &fbi,
|
||||
sizeof(fbi))) {
|
||||
return __winerr();
|
||||
}
|
||||
|
||||
// all good
|
||||
return 0;
|
||||
}
|
|
@ -17,18 +17,32 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Changes file permissions via open()'d file descriptor.
|
||||
*
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @raise EROFS if `fd` is a `/zip/...` file
|
||||
* @asyncsignalsafe
|
||||
* @see chmod()
|
||||
*/
|
||||
int fchmod(int fd, uint32_t mode) {
|
||||
// TODO(jart): Windows
|
||||
return sys_fchmod(fd, mode);
|
||||
int rc;
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
rc = erofs();
|
||||
} else if (IsLinux() || IsXnu() || IsFreebsd() || IsOpenbsd() || IsNetbsd()) {
|
||||
rc = sys_fchmod(fd, mode);
|
||||
} else if (IsWindows()) {
|
||||
rc = sys_fchmod_nt(fd, mode);
|
||||
} else {
|
||||
rc = enosys();
|
||||
}
|
||||
STRACE("fchmod(%d, %#o) → %d% m", fd, mode, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/struct/flock.h"
|
||||
|
@ -318,7 +319,7 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
|
|||
|
||||
static textwindows int sys_fcntl_nt_dupfd(int fd, int cmd, int start) {
|
||||
if (start < 0) return einval();
|
||||
return sys_dup_nt(fd, -1, (cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0), start);
|
||||
return sys_dup_nt(fd, -1, (cmd == F_DUPFD_CLOEXEC ? _O_CLOEXEC : 0), start);
|
||||
}
|
||||
|
||||
textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
|
||||
|
@ -329,21 +330,21 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
|
|||
__isfdkind(fd, kFdConsole) || //
|
||||
__isfdkind(fd, kFdDevNull)) {
|
||||
if (cmd == F_GETFL) {
|
||||
rc = g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_DIRECT | O_NONBLOCK |
|
||||
O_RANDOM | O_SEQUENTIAL);
|
||||
rc = g_fds.p[fd].flags & (O_ACCMODE | _O_APPEND | _O_DIRECT |
|
||||
_O_NONBLOCK | _O_RANDOM | _O_SEQUENTIAL);
|
||||
} else if (cmd == F_SETFL) {
|
||||
rc = sys_fcntl_nt_setfl(fd, arg);
|
||||
} else if (cmd == F_GETFD) {
|
||||
if (g_fds.p[fd].flags & O_CLOEXEC) {
|
||||
if (g_fds.p[fd].flags & _O_CLOEXEC) {
|
||||
rc = FD_CLOEXEC;
|
||||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
} else if (cmd == F_SETFD) {
|
||||
if (arg & FD_CLOEXEC) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
g_fds.p[fd].flags |= _O_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
g_fds.p[fd].flags &= ~_O_CLOEXEC;
|
||||
}
|
||||
rc = 0;
|
||||
} else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) {
|
||||
|
|
|
@ -36,9 +36,8 @@ textwindows int sys_fdatasync_nt(int fd, bool fake) {
|
|||
// kNtGenericWrite access, and MSDN doesn't document it.
|
||||
return 0;
|
||||
}
|
||||
if (_check_cancel() == -1) return -1;
|
||||
if (_check_signal(false) == -1) return -1;
|
||||
if (fake) return 0;
|
||||
if (_check_signal(false) == -1) return -1;
|
||||
return FlushFileBuffers(g_fds.p[fd].handle) ? 0 : __winerr();
|
||||
}
|
||||
|
||||
|
|
|
@ -107,11 +107,12 @@ textwindows int sys_fstat_nt(int fd, struct stat *st) {
|
|||
case kFdSocket:
|
||||
return sys_fstat_nt_socket(g_fds.p[fd].kind, st);
|
||||
default:
|
||||
return sys_fstat_nt_handle(g_fds.p[fd].handle, st);
|
||||
return sys_fstat_nt_handle(g_fds.p[fd].handle, 0, st);
|
||||
}
|
||||
}
|
||||
|
||||
textwindows int sys_fstat_nt_handle(int64_t handle, struct stat *out_st) {
|
||||
textwindows int sys_fstat_nt_handle(int64_t handle, const char16_t *path,
|
||||
struct stat *out_st) {
|
||||
struct stat st = {0};
|
||||
|
||||
// Always set st_blksize to avoid divide by zero issues.
|
||||
|
@ -143,7 +144,7 @@ textwindows int sys_fstat_nt_handle(int64_t handle, struct stat *out_st) {
|
|||
}
|
||||
st.st_mode = 0444 & ~umask;
|
||||
if ((wst.dwFileAttributes & kNtFileAttributeDirectory) ||
|
||||
IsWindowsExecutable(handle)) {
|
||||
IsWindowsExecutable(handle, path)) {
|
||||
st.st_mode |= 0111 & ~umask;
|
||||
}
|
||||
st.st_flags = wst.dwFileAttributes;
|
||||
|
|
|
@ -74,10 +74,11 @@ TryAgain:
|
|||
((flags & AT_SYMLINK_NOFOLLOW) ? kNtFileFlagOpenReparsePoint
|
||||
: 0),
|
||||
0)) != -1) {
|
||||
rc = st ? sys_fstat_nt_handle(fh, st) : 0;
|
||||
rc = st ? sys_fstat_nt_handle(fh, path16, st) : 0;
|
||||
CloseHandle(fh);
|
||||
} else if (dwDesiredAccess == kNtFileGenericRead &&
|
||||
GetLastError() == kNtErrorSharingViolation) {
|
||||
(GetLastError() == kNtErrorAccessDenied ||
|
||||
GetLastError() == kNtErrorSharingViolation)) {
|
||||
dwDesiredAccess = kNtFileReadAttributes;
|
||||
errno = e;
|
||||
goto TryAgain;
|
||||
|
|
94
libc/calls/getrandom-metal.c
Normal file
94
libc/calls/getrandom-metal.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/asmflag.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
static bool GetRandomRdseed(uint64_t *out) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) {
|
||||
*out = x;
|
||||
return true;
|
||||
}
|
||||
asm volatile("pause");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetRandomRdrand(uint64_t *out) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) {
|
||||
*out = x;
|
||||
return true;
|
||||
}
|
||||
asm volatile("pause");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t GetRandomCpu(char *p, size_t n, int f, bool impl(uint64_t *)) {
|
||||
uint64_t x;
|
||||
size_t i, j;
|
||||
for (i = 0; i < n; i += j) {
|
||||
TryAgain:
|
||||
if (!impl(&x)) {
|
||||
if (f || i >= 256) break;
|
||||
goto TryAgain;
|
||||
}
|
||||
for (j = 0; j < 8 && i + j < n; ++j) {
|
||||
p[i + j] = x;
|
||||
x >>= 8;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
ssize_t sys_getrandom_metal(char *p, size_t n, int f) {
|
||||
if (f & GRND_RANDOM) {
|
||||
if (X86_HAVE(RDSEED)) {
|
||||
return GetRandomCpu(p, n, f, GetRandomRdseed);
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
} else {
|
||||
if (X86_HAVE(RDRND)) {
|
||||
return GetRandomCpu(p, n, f, GetRandomRdrand);
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -55,78 +55,10 @@
|
|||
__static_yoink("rdrand_init");
|
||||
|
||||
int sys_getentropy(void *, size_t) asm("sys_getrandom");
|
||||
ssize_t sys_getrandom_metal(char *, size_t, int);
|
||||
|
||||
static bool have_getrandom;
|
||||
|
||||
static bool GetRandomRdseed(uint64_t *out) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdseed\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) {
|
||||
*out = x;
|
||||
return true;
|
||||
}
|
||||
asm volatile("pause");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetRandomRdrand(uint64_t *out) {
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) {
|
||||
*out = x;
|
||||
return true;
|
||||
}
|
||||
asm volatile("pause");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t GetRandomCpu(char *p, size_t n, int f, bool impl(uint64_t *)) {
|
||||
uint64_t x;
|
||||
size_t i, j;
|
||||
for (i = 0; i < n; i += j) {
|
||||
TryAgain:
|
||||
if (!impl(&x)) {
|
||||
if (f || i >= 256) break;
|
||||
goto TryAgain;
|
||||
}
|
||||
for (j = 0; j < 8 && i + j < n; ++j) {
|
||||
p[i + j] = x;
|
||||
x >>= 8;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static ssize_t GetRandomMetal(char *p, size_t n, int f) {
|
||||
if (f & GRND_RANDOM) {
|
||||
if (X86_HAVE(RDSEED)) {
|
||||
return GetRandomCpu(p, n, f, GetRandomRdseed);
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
} else {
|
||||
if (X86_HAVE(RDRND)) {
|
||||
return GetRandomCpu(p, n, f, GetRandomRdrand);
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void GetRandomEntropy(char *p, size_t n) {
|
||||
unassert(n <= 256);
|
||||
if (sys_getentropy(p, n)) notpossible;
|
||||
|
@ -181,8 +113,10 @@ ssize_t __getrandom(void *p, size_t n, unsigned f) {
|
|||
}
|
||||
} else if (IsFreebsd() || IsNetbsd()) {
|
||||
rc = GetRandomBsd(p, n, GetRandomArnd);
|
||||
#ifdef __x86_64__
|
||||
} else if (IsMetal()) {
|
||||
rc = GetRandomMetal(p, n, f);
|
||||
rc = sys_getrandom_metal(p, n, f);
|
||||
#endif
|
||||
} else {
|
||||
BEGIN_CANCELATION_POINT;
|
||||
rc = GetDevUrandom(p, n);
|
||||
|
|
|
@ -24,11 +24,11 @@ int __ensurefds(int);
|
|||
uint32_t sys_getuid_nt(void);
|
||||
int __ensurefds_unlocked(int);
|
||||
void __printfds(struct Fd *, size_t);
|
||||
int IsWindowsExecutable(int64_t);
|
||||
int CountConsoleInputBytes(void);
|
||||
int FlushConsoleInputBytes(void);
|
||||
int64_t GetConsoleInputHandle(void);
|
||||
int64_t GetConsoleOutputHandle(void);
|
||||
int IsWindowsExecutable(int64_t, const char16_t *);
|
||||
void InterceptTerminalCommands(const char *, size_t);
|
||||
|
||||
forceinline int64_t __getfdhandleactual(int fd) {
|
||||
|
|
|
@ -36,8 +36,10 @@ textwindows int _check_cancel(void) {
|
|||
|
||||
textwindows int _check_signal(bool restartable) {
|
||||
int status;
|
||||
if (_check_cancel() == -1) return -1;
|
||||
if (!_weaken(__sig_check)) return 0;
|
||||
if (!(status = _weaken(__sig_check)())) return 0;
|
||||
if (_check_cancel() == -1) return -1;
|
||||
if (status == 2 && restartable) return 0;
|
||||
return eintr();
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ static int ioctl_fionread(int fd, uint32_t *arg) {
|
|||
*arg = avail;
|
||||
return 0;
|
||||
} else if (GetLastError() == kNtErrorBrokenPipe) {
|
||||
*arg = 0; // win32 can give epipe on reader end
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
|
|
|
@ -108,7 +108,7 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
|||
0)) != -1) {
|
||||
unassert(GetFileInformationByHandle(hFile, &wst));
|
||||
if ((wst.dwFileAttributes & kNtFileAttributeDirectory) ||
|
||||
IsWindowsExecutable(hFile)) {
|
||||
IsWindowsExecutable(hFile, pathname)) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = eacces();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
|
@ -56,31 +57,31 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
|||
// implement no follow flag
|
||||
// you can't open symlinks; use readlink
|
||||
// this flag only applies to the final path component
|
||||
// if O_NOFOLLOW_ANY is passed (-1 on NT) it'll be rejected later
|
||||
// if _O_NOFOLLOW_ANY is passed (-1 on NT) it'll be rejected later
|
||||
uint32_t fattr = GetFileAttributes(path16);
|
||||
if (flags & O_NOFOLLOW) {
|
||||
if (flags & _O_NOFOLLOW) {
|
||||
if (fattr != -1u && (fattr & kNtFileAttributeReparsePoint)) {
|
||||
return eloop();
|
||||
}
|
||||
flags &= ~O_NOFOLLOW; // don't actually pass this to win32
|
||||
flags &= ~_O_NOFOLLOW; // don't actually pass this to win32
|
||||
}
|
||||
|
||||
// handle some obvious cases while we have the attributes
|
||||
// we should ideally resolve symlinks ourself before doing this
|
||||
if (fattr != -1u) {
|
||||
if (fattr & kNtFileAttributeDirectory) {
|
||||
if ((flags & O_ACCMODE) != O_RDONLY || (flags & O_CREAT)) {
|
||||
if ((flags & O_ACCMODE) != O_RDONLY || (flags & _O_CREAT)) {
|
||||
// tried to open directory for writing. note that our
|
||||
// undocumented O_TMPFILE support on windows requires that a
|
||||
// undocumented _O_TMPFILE support on windows requires that a
|
||||
// filename be passed, rather than a directory like linux.
|
||||
return eisdir();
|
||||
}
|
||||
// on posix, the o_directory flag is an advisory safeguard that
|
||||
// isn't required. on windows, it's mandatory for opening a dir
|
||||
flags |= O_DIRECTORY;
|
||||
flags |= _O_DIRECTORY;
|
||||
} else if (!(fattr & kNtFileAttributeReparsePoint)) {
|
||||
// we know for certain file isn't a directory
|
||||
if (flags & O_DIRECTORY) {
|
||||
if (flags & _O_DIRECTORY) {
|
||||
return enotdir();
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +187,7 @@ textwindows int sys_open_nt(int dirfd, const char *file, uint32_t flags,
|
|||
ssize_t rc;
|
||||
BLOCK_SIGNALS;
|
||||
__fds_lock();
|
||||
if (!(flags & O_CREAT)) mode = 0;
|
||||
if (!(flags & _O_CREAT)) mode = 0;
|
||||
if ((rc = fd = __reservefd_unlocked(-1)) != -1) {
|
||||
if (startswith(file, "/dev/")) {
|
||||
if (!strcmp(file + 5, "tty")) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
|
@ -45,11 +46,13 @@ static textwindows int _park_thread(uint32_t msdelay, sigset_t waitmask,
|
|||
pthread_cleanup_push((void *)CloseHandle, (void *)sem);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM, memory_order_release);
|
||||
om = __sig_beginwait(waitmask);
|
||||
if ((rc = _check_cancel()) != -1 && (rc = _check_signal(restartable)) != -1) {
|
||||
unassert((wi = WaitForSingleObject(sem, msdelay)) != -1u);
|
||||
if (restartable && !(pt->pt_flags & PT_RESTARTABLE)) rc = eintr();
|
||||
rc |= _check_signal(restartable);
|
||||
if (rc == -1 && errno == EINTR) _check_cancel();
|
||||
if ((rc = _check_signal(restartable)) != -1) {
|
||||
if ((wi = WaitForSingleObject(sem, msdelay)) != -1u) {
|
||||
if (restartable && !(pt->pt_flags & PT_RESTARTABLE)) rc = eintr();
|
||||
rc |= _check_signal(restartable);
|
||||
} else {
|
||||
rc = __winerr();
|
||||
}
|
||||
}
|
||||
__sig_finishwait(om);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_CPU, memory_order_release);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
|
@ -729,7 +730,7 @@ static textwindows int WaitForConsole(struct Fd *f, sigset_t waitmask) {
|
|||
ms = __ttyconf.vtime * 100;
|
||||
}
|
||||
}
|
||||
if (f->flags & O_NONBLOCK) {
|
||||
if (f->flags & _O_NONBLOCK) {
|
||||
return eagain(); // standard unix non-blocking
|
||||
}
|
||||
pt = _pthread_self();
|
||||
|
@ -738,12 +739,14 @@ static textwindows int WaitForConsole(struct Fd *f, sigset_t waitmask) {
|
|||
pthread_cleanup_push((void *)CloseHandle, (void *)sem);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM, memory_order_release);
|
||||
m = __sig_beginwait(waitmask);
|
||||
if ((rc = _check_cancel()) != -1 && (rc = _check_signal(true)) != -1) {
|
||||
if ((rc = _check_signal(true)) != -1) {
|
||||
int64_t hands[2] = {sem, __keystroke.cin};
|
||||
unassert(WaitForMultipleObjects(2, hands, 0, ms) != -1u);
|
||||
if (~pt->pt_flags & PT_RESTARTABLE) rc = eintr();
|
||||
rc |= _check_signal(true);
|
||||
if (rc == -1 && errno == EINTR) _check_cancel();
|
||||
if (WaitForMultipleObjects(2, hands, 0, ms) != -1u) {
|
||||
if (!(pt->pt_flags & PT_RESTARTABLE)) rc = eintr();
|
||||
rc |= _check_signal(true);
|
||||
} else {
|
||||
rc = __winerr();
|
||||
}
|
||||
}
|
||||
__sig_finishwait(m);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_CPU, memory_order_release);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
|
@ -140,15 +141,16 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
|||
pt->pt_flags |= PT_RESTARTABLE;
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_IO, memory_order_release);
|
||||
m = __sig_beginwait(waitmask);
|
||||
if (f->flags & O_NONBLOCK) {
|
||||
if (f->flags & _O_NONBLOCK) {
|
||||
CancelIoEx(handle, &overlap);
|
||||
eagained = true;
|
||||
} else if (_check_cancel()) {
|
||||
CancelIoEx(handle, &overlap);
|
||||
canceled = true;
|
||||
} else if (_check_signal(true)) {
|
||||
CancelIoEx(handle, &overlap);
|
||||
eintered = true;
|
||||
if (errno == ECANCELED) {
|
||||
canceled = true;
|
||||
} else {
|
||||
eintered = true;
|
||||
}
|
||||
} else {
|
||||
WaitForSingleObject(overlap.hEvent, -1u);
|
||||
}
|
||||
|
@ -197,7 +199,7 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
|||
// it's also fine to do nothing here; punt to next cancelation point
|
||||
if (GetLastError() == kNtErrorOperationAborted) {
|
||||
if (_check_cancel() == -1) return ecanceled();
|
||||
if (!eintered && _check_signal(false)) return eintr();
|
||||
if (!eintered && _check_signal(false)) return -1;
|
||||
}
|
||||
|
||||
// if we chose to process a pending signal earlier then we preserve
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/createfileflags.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
|
@ -36,8 +37,9 @@ textwindows int sys_fcntl_nt_setfl(int fd, unsigned flags) {
|
|||
// - O_DIRECT works but haven't tested
|
||||
//
|
||||
// the other bits are ignored.
|
||||
unsigned allowed = O_APPEND | O_SEQUENTIAL | O_RANDOM | O_DIRECT | O_NONBLOCK;
|
||||
unsigned needreo = O_APPEND | O_SEQUENTIAL | O_RANDOM | O_DIRECT;
|
||||
unsigned allowed =
|
||||
_O_APPEND | _O_SEQUENTIAL | _O_RANDOM | _O_DIRECT | _O_NONBLOCK;
|
||||
unsigned needreo = _O_APPEND | _O_SEQUENTIAL | _O_RANDOM | _O_DIRECT;
|
||||
unsigned newflag = (g_fds.p[fd].flags & ~allowed) | (flags & allowed);
|
||||
|
||||
if (g_fds.p[fd].kind == kFdFile &&
|
||||
|
|
|
@ -33,9 +33,7 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/describebacktrace.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/popcnt.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
|
@ -105,7 +103,7 @@ static textwindows int __sig_getter(struct CosmoTib *tib, atomic_ulong *sigs) {
|
|||
pending = atomic_load_explicit(sigs, memory_order_acquire);
|
||||
masked = atomic_load_explicit(&tib->tib_sigmask, memory_order_acquire);
|
||||
if ((deliverable = pending & ~masked)) {
|
||||
sig = _bsf(deliverable) + 1;
|
||||
sig = _bsfl(deliverable) + 1;
|
||||
bit = 1ull << (sig - 1);
|
||||
if (atomic_fetch_and_explicit(sigs, ~bit, memory_order_acq_rel) & bit) {
|
||||
return sig;
|
||||
|
@ -263,7 +261,7 @@ textwindows void __sig_cancel(struct PosixThread *pt, int sig, unsigned flags) {
|
|||
WakeByAddressSingle(blocker);
|
||||
}
|
||||
|
||||
// the user's signal handler callback is composed with this trampoline
|
||||
// the user's signal handler callback is wrapped with this trampoline
|
||||
static textwindows wontreturn void __sig_tramp(struct SignalFrame *sf) {
|
||||
int sig = sf->si.si_signo;
|
||||
struct CosmoTib *tib = __get_tls();
|
||||
|
|
|
@ -9,7 +9,7 @@ int sys_fstat(int, struct stat *);
|
|||
int sys_fstatat(int, const char *, struct stat *, int);
|
||||
int sys_fstat_nt(int, struct stat *);
|
||||
int sys_fstat_nt_special(int, struct stat *);
|
||||
int sys_fstat_nt_handle(int64_t, struct stat *);
|
||||
int sys_fstat_nt_handle(int64_t, const char16_t *, struct stat *);
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, int);
|
||||
int sys_lstat_nt(const char *, struct stat *);
|
||||
int sys_fstat_metal(int, struct stat *);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UTSNAME_H_
|
||||
|
||||
#define SYS_NMLN 321
|
||||
#define SYS_NMLN 150
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
|
|
@ -12,6 +12,7 @@ int sys_execve_nt(const char *, char *const[], char *const[]);
|
|||
int sys_faccessat_nt(int, const char *, int, uint32_t);
|
||||
int sys_fadvise_nt(int, uint64_t, uint64_t, int);
|
||||
int sys_fchdir_nt(int);
|
||||
int sys_fchmod_nt(int, uint32_t);
|
||||
int sys_fchmodat_nt(int, const char *, uint32_t, int);
|
||||
int sys_fcntl_nt(int, int, uintptr_t);
|
||||
int sys_fdatasync_nt(int, bool);
|
||||
|
|
|
@ -91,7 +91,12 @@ errno_t ttyname_r(int fd, char *buf, size_t size) {
|
|||
} else if (IsWindows()) {
|
||||
res = sys_ttyname_nt(fd, buf, size);
|
||||
} else {
|
||||
res = ENOSYS;
|
||||
// TODO(jart): Use that fstat(dev/ino) + readdir(/dev/) trick.
|
||||
if (strlcpy(buf, "/dev/tty", size) < size) {
|
||||
res = 0;
|
||||
} else {
|
||||
res = ERANGE;
|
||||
}
|
||||
}
|
||||
errno = e;
|
||||
STRACE("ttyname_r(%d, %#.*hhs) → %s", fd, (int)size, buf,
|
||||
|
|
|
@ -18,14 +18,57 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tab.internal.h"
|
||||
#include "third_party/linenoise/linenoise.h"
|
||||
|
||||
#define EXT(s) READ32LE(s "\0\0")
|
||||
|
||||
static bool IsGraph(wint_t c) {
|
||||
return 0x21 <= c && c <= 0x7E;
|
||||
}
|
||||
|
||||
static uint32_t GetFileExtension(const char16_t *s) {
|
||||
uint32_t w;
|
||||
size_t i, n;
|
||||
n = s ? strlen16(s) : 0;
|
||||
for (i = w = 0; n--;) {
|
||||
wint_t c = s[n];
|
||||
if (!IsGraph(c)) return 0;
|
||||
if (c == '.') break;
|
||||
if (++i > 4) return 0;
|
||||
w <<= 8;
|
||||
w |= kToLower[c];
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// checks if file should be considered an executable on windows
|
||||
textwindows int IsWindowsExecutable(int64_t handle) {
|
||||
textwindows int IsWindowsExecutable(int64_t handle, const char16_t *path) {
|
||||
|
||||
// fast path known file extensions
|
||||
// shaves away 100ms of gnu make latency in cosmo monorepo
|
||||
uint32_t ext;
|
||||
if (!IsTiny() && (ext = GetFileExtension(path))) {
|
||||
if (ext == EXT("c") || // c code
|
||||
ext == EXT("cc") || // c++ code
|
||||
ext == EXT("h") || // c/c++ header
|
||||
ext == EXT("s") || // assembly code
|
||||
ext == EXT("o")) { // object file
|
||||
return false;
|
||||
}
|
||||
if (ext == EXT("com") || // mz executable
|
||||
ext == EXT("exe") || // mz executable
|
||||
ext == EXT("sh")) { // bourne shells
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// read first two bytes of file
|
||||
// access() and stat() aren't cancelation points
|
||||
|
|
|
@ -146,7 +146,6 @@ typedef struct {
|
|||
} axdx_t;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __chibicc__
|
||||
#define va_list __builtin_va_list
|
||||
#define va_arg(ap, type) __builtin_va_arg(ap, type)
|
||||
|
@ -620,12 +619,6 @@ void abort(void) wontreturn;
|
|||
do { \
|
||||
} while (0)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define _Vector_size(k) __attribute__((__vector_size__(k)))
|
||||
#else
|
||||
#define _Vector_size(k) [k]
|
||||
#endif
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
#define textstartup _Section(".text.startup")
|
||||
#define textexit _Section(".text.exit")
|
||||
|
|
|
@ -48,10 +48,25 @@ CreateFile(const char16_t *lpFileName, //
|
|||
int64_t opt_hTemplateFile) {
|
||||
int64_t hHandle;
|
||||
uint32_t micros = 1;
|
||||
char buf_accessflags[512];
|
||||
(void)buf_accessflags;
|
||||
char buf_shareflags[64];
|
||||
(void)buf_shareflags;
|
||||
char buf_secattr[32];
|
||||
(void)buf_secattr;
|
||||
char buf_flagattr[256];
|
||||
(void)buf_flagattr;
|
||||
TryAgain:
|
||||
hHandle = __imp_CreateFileW(lpFileName, dwDesiredAccess, dwShareMode,
|
||||
opt_lpSecurity, dwCreationDisposition,
|
||||
dwFlagsAndAttributes, opt_hTemplateFile);
|
||||
NTTRACE("CreateFile(%#hs, %s, %s, %s, %s, %s, %ld) → {%ld, %d}", lpFileName,
|
||||
(DescribeNtFileAccessFlags)(buf_accessflags, dwDesiredAccess),
|
||||
(DescribeNtFileShareFlags)(buf_shareflags, dwShareMode),
|
||||
(DescribeNtSecurityAttributes)(buf_secattr, opt_lpSecurity),
|
||||
DescribeNtCreationDisposition(dwCreationDisposition),
|
||||
(DescribeNtFileFlagAttr)(buf_flagattr, dwFlagsAndAttributes),
|
||||
opt_hTemplateFile, hHandle, __imp_GetLastError());
|
||||
if (hHandle == -1) {
|
||||
switch (__imp_GetLastError()) {
|
||||
case kNtErrorPipeBusy:
|
||||
|
@ -77,12 +92,5 @@ TryAgain:
|
|||
}
|
||||
__winerr();
|
||||
}
|
||||
NTTRACE("CreateFile(%#hs, %s, %s, %s, %s, %s, %ld) → %ld% m", lpFileName,
|
||||
DescribeNtFileAccessFlags(dwDesiredAccess),
|
||||
DescribeNtFileShareFlags(dwShareMode),
|
||||
DescribeNtSecurityAttributes(opt_lpSecurity),
|
||||
DescribeNtCreationDisposition(dwCreationDisposition),
|
||||
DescribeNtFileFlagAttr(dwFlagsAndAttributes), opt_hTemplateFile,
|
||||
hHandle);
|
||||
return hHandle;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
#include "libc/nt/thread.h"
|
||||
|
||||
__msabi extern typeof(CreateThread) *const __imp_CreateThread;
|
||||
__msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
||||
|
||||
/**
|
||||
* Opens file on the New Technology.
|
||||
|
@ -41,9 +43,10 @@ CreateThread(const struct NtSecurityAttributes *lpThreadAttributes,
|
|||
int64_t hHandle;
|
||||
hHandle = __imp_CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress,
|
||||
lpParameter, dwCreationFlags, opt_lpThreadId);
|
||||
NTTRACE("CreateThread(%s, %'zu, %t, %p, %s, %p) → %ld% m",
|
||||
NTTRACE("CreateThread(%s, %'zu, %t, %p, %s, %p) → {%ld, %d}",
|
||||
DescribeNtSecurityAttributes(lpThreadAttributes), dwStackSize,
|
||||
lpStartAddress, lpParameter,
|
||||
DescribeThreadCreateFlags(dwCreationFlags), opt_lpThreadId, hHandle);
|
||||
DescribeThreadCreateFlags(dwCreationFlags), opt_lpThreadId, hHandle,
|
||||
__imp_GetLastError());
|
||||
return hHandle;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
|
||||
__msabi extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers;
|
||||
__msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
||||
|
||||
/**
|
||||
* Flushes buffers of specified file to disk.
|
||||
|
@ -36,6 +38,7 @@ __msabi extern typeof(FlushFileBuffers) *const __imp_FlushFileBuffers;
|
|||
textwindows bool32 FlushFileBuffers(int64_t hFile) {
|
||||
bool32 ok;
|
||||
ok = __imp_FlushFileBuffers(hFile);
|
||||
NTTRACE("FlushFileBuffers(%ld) → %hhhd% m", hFile, ok);
|
||||
NTTRACE("FlushFileBuffers(%ld) → {%hhhd, %d}", hFile, ok,
|
||||
__imp_GetLastError());
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,11 @@
|
|||
#define kPid "TracerPid:\t"
|
||||
|
||||
static textwindows bool IsBeingDebugged(void) {
|
||||
#ifdef __x86_64__
|
||||
return !!NtGetPeb()->BeingDebugged;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
#if defined(__x86_64__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
typedef char __intrin_xmm_t _Vector_size(16) forcealign(16) mayalias;
|
||||
typedef char __intrin_xmm_t
|
||||
__attribute__((__vector_size__(16), __aligned__(16), __may_alias__));
|
||||
|
||||
#define INTRIN_SSEVEX_X_X_X_(PURE, ISA, OP, FLAGS, A, B, C) \
|
||||
do { \
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(ReOpenFile) *const __imp_ReOpenFile;
|
||||
__msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
||||
|
||||
/**
|
||||
* Reopens file on the New Technology.
|
||||
|
@ -34,9 +36,10 @@ int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess,
|
|||
int64_t hHandle;
|
||||
hHandle = __imp_ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode,
|
||||
dwFlagsAndAttributes);
|
||||
NTTRACE("ReOpenFile(%ld, %s, %s, %s) → %ld% m", hOriginalFile,
|
||||
NTTRACE("ReOpenFile(%ld, %s, %s, %s) → {%ld, %d}", hOriginalFile,
|
||||
DescribeNtFileAccessFlags(dwDesiredAccess),
|
||||
DescribeNtFileShareFlags(dwShareMode),
|
||||
DescribeNtFileFlagAttr(dwFlagsAndAttributes), hHandle);
|
||||
DescribeNtFileFlagAttr(dwFlagsAndAttributes), hHandle,
|
||||
__imp_GetLastError());
|
||||
return hHandle;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(TerminateProcess) *const __imp_TerminateProcess;
|
||||
__msabi extern typeof(GetLastError) *const __imp_GetLastError;
|
||||
|
||||
/**
|
||||
* Terminates the specified process and all of its threads.
|
||||
|
@ -30,6 +31,7 @@ __msabi extern typeof(TerminateProcess) *const __imp_TerminateProcess;
|
|||
textwindows bool32 TerminateProcess(int64_t hProcess, uint32_t uWaitStatus) {
|
||||
bool32 ok;
|
||||
ok = __imp_TerminateProcess(hProcess, uWaitStatus);
|
||||
NTTRACE("TerminateProcess(%ld, %u) → %hhhd% m", hProcess, uWaitStatus, ok);
|
||||
NTTRACE("TerminateProcess(%ld, %u) → {%hhhd, %d}", hProcess, uWaitStatus, ok,
|
||||
__imp_GetLastError());
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
|
@ -26,14 +27,15 @@ __msabi extern typeof(WaitForMultipleObjects)
|
|||
|
||||
/**
|
||||
* Waits for handles to change status.
|
||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||
*
|
||||
* @return -1u on error w/ GetLastError()
|
||||
* @raise kNtErrorInvalidParameter if `bWaitAll` and `lpHandles` has dupes
|
||||
*/
|
||||
uint32_t WaitForMultipleObjects(uint32_t nCount, const int64_t *lpHandles,
|
||||
bool32 bWaitAll, uint32_t dwMilliseconds) {
|
||||
uint32_t x;
|
||||
x = __imp_WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds);
|
||||
if (x == -1u) __winerr();
|
||||
POLLTRACE("WaitForMultipleObjects(%ld, %p, %hhhd, %'d) → %d% m", nCount,
|
||||
lpHandles, bWaitAll, dwMilliseconds, x);
|
||||
POLLTRACE("WaitForMultipleObjects(%ld, %p, %hhhd, %'d) → %d %d", nCount,
|
||||
lpHandles, bWaitAll, dwMilliseconds, x, GetLastError());
|
||||
return x;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
|
@ -30,7 +31,7 @@ __msabi extern typeof(WaitForSingleObject) *const __imp_WaitForSingleObject;
|
|||
uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds) {
|
||||
uint32_t rc;
|
||||
rc = __imp_WaitForSingleObject(hHandle, dwMilliseconds);
|
||||
POLLTRACE("WaitForSingleObject(%ld, %'d) → %d% m", hHandle, dwMilliseconds,
|
||||
rc);
|
||||
POLLTRACE("WaitForSingleObject(%ld, %'d) → %d %d", hHandle, dwMilliseconds,
|
||||
rc, GetLastError());
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ static relegated void __oncrash_impl(int sig, struct siginfo *si,
|
|||
free(mem);
|
||||
}
|
||||
b->p[b->n - 1] = '\n';
|
||||
sys_write(2, b->p, MIN(b->i, b->n));
|
||||
klog(b->p, MIN(b->i, b->n));
|
||||
}
|
||||
|
||||
relegated void __oncrash(int sig, struct siginfo *si, void *arg) {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -151,10 +152,11 @@ static textwindows bool spawnfds_exists(struct SpawnFds *fds, int fildes) {
|
|||
return fildes + 0u < fds->n && fds->p[fildes].kind;
|
||||
}
|
||||
|
||||
static textwindows void spawnfds_close(struct SpawnFds *fds, int fildes) {
|
||||
static textwindows errno_t spawnfds_close(struct SpawnFds *fds, int fildes) {
|
||||
if (spawnfds_exists(fds, fildes)) {
|
||||
fds->p[fildes] = (struct Fd){0};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static textwindows errno_t spawnfds_dup2(struct SpawnFds *fds, int fildes,
|
||||
|
@ -181,8 +183,8 @@ static textwindows errno_t spawnfds_dup2(struct SpawnFds *fds, int fildes,
|
|||
}
|
||||
|
||||
static textwindows errno_t spawnfds_open(struct SpawnFds *fds, int64_t dirhand,
|
||||
int fildes, const char *path,
|
||||
int oflag, int mode) {
|
||||
const char *path, int oflag, int mode,
|
||||
int fildes) {
|
||||
int64_t h;
|
||||
errno_t err;
|
||||
char16_t path16[PATH_MAX];
|
||||
|
@ -283,42 +285,47 @@ static textwindows errno_t posix_spawn_nt_impl(
|
|||
// apply user file actions
|
||||
if (file_actions) {
|
||||
for (struct _posix_faction *a = *file_actions; a && !err; a = a->next) {
|
||||
char errno_buf[30];
|
||||
char oflags_buf[128];
|
||||
char openmode_buf[15];
|
||||
(void)errno_buf;
|
||||
(void)oflags_buf;
|
||||
(void)openmode_buf;
|
||||
switch (a->action) {
|
||||
case _POSIX_SPAWN_CLOSE:
|
||||
spawnfds_close(&fds, a->fildes);
|
||||
err = spawnfds_close(&fds, a->fildes);
|
||||
STRACE("spawnfds_close(%d) → %s", a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_DUP2:
|
||||
err = spawnfds_dup2(&fds, a->fildes, a->newfildes);
|
||||
if (err) {
|
||||
STRACE("spawnfds_dup2(%d, %d) failed", a->fildes, a->newfildes);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_dup2(%d, %d) → %s", a->fildes, a->newfildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_OPEN:
|
||||
err = spawnfds_open(&fds, dirhand, a->fildes, a->path, a->oflag,
|
||||
a->mode);
|
||||
if (err) {
|
||||
STRACE("spawnfds_open(%d, %#s) failed", a->fildes, a->path);
|
||||
goto ReturnErr;
|
||||
}
|
||||
err = spawnfds_open(&fds, dirhand, a->path, a->oflag, a->mode,
|
||||
a->fildes);
|
||||
STRACE("spawnfds_open(%#s, %s, %s, %d) → %s", a->path,
|
||||
(DescribeOpenFlags)(oflags_buf, a->oflag),
|
||||
(DescribeOpenMode)(openmode_buf, a->oflag, a->mode), a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_CHDIR:
|
||||
err = spawnfds_chdir(&fds, dirhand, a->path, &dirhand);
|
||||
if (err) {
|
||||
STRACE("spawnfds_chdir(%#s) failed", a->path);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_chdir(%#s) → %s", a->path,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
case _POSIX_SPAWN_FCHDIR:
|
||||
err = spawnfds_fchdir(&fds, a->fildes, &dirhand);
|
||||
if (err) {
|
||||
STRACE("spawnfds_fchdir(%d) failed", a->fildes);
|
||||
goto ReturnErr;
|
||||
}
|
||||
STRACE("spawnfds_fchdir(%d) → %s", a->fildes,
|
||||
(DescribeErrno)(errno_buf, err));
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
if (err) {
|
||||
goto ReturnErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,9 +579,13 @@ errno_t posix_spawn(int *pid, const char *path,
|
|||
}
|
||||
}
|
||||
if (flags & POSIX_SPAWN_SETRLIMIT) {
|
||||
for (int rez = 0; rez <= ARRAYLEN((*attrp)->rlim); ++rez) {
|
||||
if ((*attrp)->rlimset & (1u << rez)) {
|
||||
if (setrlimit(rez, (*attrp)->rlim + rez)) {
|
||||
int rlimset = (*attrp)->rlimset;
|
||||
while (rlimset) {
|
||||
int resource = _bsf(rlimset);
|
||||
rlimset &= ~(1u << resource);
|
||||
if (setrlimit(resource, (*attrp)->rlim + resource)) {
|
||||
// MacOS ARM64 RLIMIT_STACK always returns EINVAL
|
||||
if (!IsXnuSilicon()) {
|
||||
goto ChildFailed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ struct _posix_spawna {
|
|||
bool schedparam_isset;
|
||||
bool schedpolicy_isset;
|
||||
int pgroup;
|
||||
int rlimset;
|
||||
int schedpolicy;
|
||||
int rlimset;
|
||||
struct sched_param schedparam;
|
||||
sigset_t sigmask;
|
||||
sigset_t sigdefault;
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions,
|
||||
int fildes) {
|
||||
if (fildes < 0) return EBADF;
|
||||
if (IsWindows() && fildes > 2) return 0;
|
||||
return __posix_spawn_add_file_action(file_actions,
|
||||
(struct _posix_faction){
|
||||
.action = _POSIX_SPAWN_CLOSE,
|
||||
|
|
|
@ -26,14 +26,12 @@
|
|||
*
|
||||
* @param file_actions was initialized by posix_spawn_file_actions_init()
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise ENOMEM if we require more vespene gas
|
||||
* @raise EBADF if 'fildes' or `newfildes` is negative
|
||||
* @raise ENOTSUP if `newfildes` isn't 0, 1, or 2 on Windows
|
||||
* @raise ENOMEM if insufficient memory was available
|
||||
*/
|
||||
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions,
|
||||
int fildes, int newfildes) {
|
||||
if (fildes < 0 || newfildes < 0) return EBADF;
|
||||
if (IsWindows() && newfildes > 2) return ENOTSUP;
|
||||
return __posix_spawn_add_file_action(file_actions,
|
||||
(struct _posix_faction){
|
||||
.action = _POSIX_SPAWN_DUP2,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/proc/posix_spawn.h"
|
||||
#include "libc/proc/posix_spawn.internal.h"
|
||||
#include "libc/stdio/sysparam.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
|
||||
/**
|
||||
* Gets resource limit for spawned process.
|
||||
|
@ -31,7 +33,7 @@
|
|||
*/
|
||||
int posix_spawnattr_getrlimit(const posix_spawnattr_t *attr, int resource,
|
||||
struct rlimit *rlim) {
|
||||
if ((0 <= resource && resource < ARRAYLEN((*attr)->rlim))) {
|
||||
if (0 <= resource && resource < MIN(RLIM_NLIMITS, ARRAYLEN((*attr)->rlim))) {
|
||||
if (((*attr)->rlimset & (1u << resource))) {
|
||||
*rlim = (*attr)->rlim[resource];
|
||||
return 0;
|
||||
|
|
|
@ -37,9 +37,10 @@
|
|||
*/
|
||||
int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) {
|
||||
if (flags &
|
||||
~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF |
|
||||
POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSCHEDPARAM |
|
||||
POSIX_SPAWN_SETSCHEDULER | POSIX_SPAWN_SETSID)) {
|
||||
~(POSIX_SPAWN_USEVFORK | POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP |
|
||||
POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK |
|
||||
POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER |
|
||||
POSIX_SPAWN_SETSID | POSIX_SPAWN_SETRLIMIT)) {
|
||||
return EINVAL;
|
||||
}
|
||||
(*attr)->flags = flags;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/proc/posix_spawn.h"
|
||||
#include "libc/proc/posix_spawn.internal.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
|
||||
/**
|
||||
* Sets resource limit on spawned process.
|
||||
|
@ -32,7 +33,7 @@
|
|||
*/
|
||||
int posix_spawnattr_setrlimit(posix_spawnattr_t *attr, int resource,
|
||||
const struct rlimit *rlim) {
|
||||
if (0 <= resource && resource < ARRAYLEN((*attr)->rlim)) {
|
||||
if (0 <= resource && resource < MIN(RLIM_NLIMITS, ARRAYLEN((*attr)->rlim))) {
|
||||
(*attr)->flags |= POSIX_SPAWN_SETRLIMIT;
|
||||
(*attr)->rlimset |= 1u << resource;
|
||||
(*attr)->rlim[resource] = *rlim;
|
||||
|
|
|
@ -103,12 +103,8 @@ static textwindows dontinstrument uint32_t __proc_worker(void *arg) {
|
|||
__proc_unlock();
|
||||
|
||||
// wait for win32 to report any status change
|
||||
millis = n == 64 ? __SIG_PROC_INTERVAL_MS : -1u;
|
||||
i = WaitForMultipleObjects(n, handles, false, millis);
|
||||
if (i == -1u) {
|
||||
STRACE("PROC WORKER DYING: WAIT FAILED: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
millis = n == 64 ? 20 : -1u;
|
||||
unassert((i = WaitForMultipleObjects(n, handles, false, millis)) != -1u);
|
||||
i &= ~kNtWaitAbandoned;
|
||||
if (!i || i == kNtWaitTimeout) continue;
|
||||
GetExitCodeProcess(handles[i], &status);
|
||||
|
|
|
@ -68,14 +68,15 @@ ftrace_hook:
|
|||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
adrp x16,__ftrace
|
||||
ldr w16,[x16,#:lo12:__ftrace]
|
||||
cmp w16,0
|
||||
ble 1f
|
||||
stp x29,x30,[sp,-384]!
|
||||
mov x29,sp
|
||||
|
||||
stp x0,x1,[sp,16]
|
||||
|
||||
adrp x0,__ftrace
|
||||
ldr w0,[x0,#:lo12:__ftrace]
|
||||
cmp w0,0
|
||||
ble 1f
|
||||
|
||||
stp x2,x3,[sp,32]
|
||||
stp x4,x5,[sp,48]
|
||||
stp x6,x7,[sp,64]
|
||||
|
@ -83,12 +84,12 @@ ftrace_hook:
|
|||
stp x10,x11,[sp,96]
|
||||
stp x12,x13,[sp,112]
|
||||
stp x14,x15,[sp,128]
|
||||
str x19,[sp,160]
|
||||
stp x16,x19,[sp,160]
|
||||
stp x20,x21,[sp,176]
|
||||
stp x22,x23,[sp,192]
|
||||
stp x24,x25,[sp,208]
|
||||
stp x26,x27,[sp,224]
|
||||
str x28,[sp,240]
|
||||
stp x17,x28,[sp,240]
|
||||
stp q0,q1,[sp,256]
|
||||
stp q2,q3,[sp,288]
|
||||
stp q4,q5,[sp,320]
|
||||
|
@ -96,27 +97,27 @@ ftrace_hook:
|
|||
|
||||
bl ftracer
|
||||
|
||||
ldp x0,x1,[sp,16]
|
||||
ldp x2,x3,[sp,32]
|
||||
ldp x4,x5,[sp,48]
|
||||
ldp x6,x7,[sp,64]
|
||||
ldp x8,x9,[sp,80]
|
||||
ldp x10,x11,[sp,96]
|
||||
ldp x12,x13,[sp,112]
|
||||
ldp x14,x15,[sp,128]
|
||||
ldr x19,[sp,160]
|
||||
ldp x20,x21,[sp,176]
|
||||
ldp x22,x23,[sp,192]
|
||||
ldp x24,x25,[sp,208]
|
||||
ldp x26,x27,[sp,224]
|
||||
ldr x28,[sp,240]
|
||||
ldp q0,q1,[sp,256]
|
||||
ldp q2,q3,[sp,288]
|
||||
ldp q4,q5,[sp,320]
|
||||
ldp q6,q7,[sp,352]
|
||||
ldp q4,q5,[sp,320]
|
||||
ldp q2,q3,[sp,288]
|
||||
ldp q0,q1,[sp,256]
|
||||
ldp x17,x28,[sp,240]
|
||||
ldp x26,x27,[sp,224]
|
||||
ldp x24,x25,[sp,208]
|
||||
ldp x22,x23,[sp,192]
|
||||
ldp x20,x21,[sp,176]
|
||||
ldp x16,x19,[sp,160]
|
||||
ldp x14,x15,[sp,128]
|
||||
ldp x12,x13,[sp,112]
|
||||
ldp x10,x11,[sp,96]
|
||||
ldp x8,x9,[sp,80]
|
||||
ldp x6,x7,[sp,64]
|
||||
ldp x4,x5,[sp,48]
|
||||
ldp x2,x3,[sp,32]
|
||||
|
||||
1: ldp x0,x1,[sp,16]
|
||||
ldp x29,x30,[sp],384
|
||||
1: ret
|
||||
ret
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
.endfn ftrace_hook,globl,hidden
|
||||
|
|
|
@ -90,12 +90,13 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
|||
if (nonblock) {
|
||||
CancelWinsockBlock(handle, &overlap);
|
||||
eagained = true;
|
||||
} else if (_check_cancel()) {
|
||||
CancelWinsockBlock(handle, &overlap);
|
||||
canceled = true;
|
||||
} else if (_check_signal(true)) {
|
||||
CancelWinsockBlock(handle, &overlap);
|
||||
eintered = true;
|
||||
if (errno == ECANCELED) {
|
||||
canceled = true;
|
||||
} else {
|
||||
eintered = true;
|
||||
}
|
||||
} else {
|
||||
status = WSAWaitForMultipleEvents(1, &overlap.hEvent, 0,
|
||||
srwtimeout ? srwtimeout : -1u, 0);
|
||||
|
@ -142,7 +143,7 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
|||
}
|
||||
if (GetLastError() == kNtErrorOperationAborted) {
|
||||
if (_check_cancel() == -1) return ecanceled();
|
||||
if (!eintered && _check_signal(false)) return eintr();
|
||||
if (!eintered && _check_signal(false)) return -1;
|
||||
}
|
||||
if (eintered) {
|
||||
return eintr();
|
||||
|
|
|
@ -57,7 +57,7 @@ dontinline long systemfive_cancellable(void) {
|
|||
return systemfive_cancel();
|
||||
}
|
||||
#if IsModeDbg()
|
||||
if (!(pth->flags & PT_INCANCEL)) {
|
||||
if (!(pth->pt_flags & PT_INCANCEL)) {
|
||||
if (_weaken(report_cancelation_point)) {
|
||||
_weaken(report_cancelation_point)();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue