mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Fix bugs and make improvements
- Get clone() working on FreeBSD - Increase some Python build quotas - Add more atomic builtins to chibicc - Fix ASAN poisoning of alloca() memory - Make MODE= mandatory link path tinier - Improve the examples folder a little bit - Start working on some more resource limits - Make the linenoise auto-complete UI as good as GNU readline - Update compile.com, avoiding AVX codegen on non-AVX systems - Make sure empty path to syscalls like opendir raises ENOENT - Correctly polyfill ENOENT vs. ENOTDIR on the New Technology - Port bestline's paredit features to //third_party/linenoise - Remove workarounds for RHEL 5.0 bugs that were fixed in 5.1
This commit is contained in:
parent
c3fb624647
commit
ae638c0850
181 changed files with 2994 additions and 1367 deletions
5
Makefile
5
Makefile
|
@ -60,7 +60,7 @@
|
|||
# build/config.mk
|
||||
|
||||
SHELL = /bin/sh
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win7 win10
|
||||
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win7 win10 xnu
|
||||
SANITY := $(shell build/sanitycheck $$PPID)
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -107,7 +107,6 @@ include libc/fmt/fmt.mk #─┘
|
|||
include libc/calls/calls.mk #─┐
|
||||
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
|
||||
include libc/crt/crt.mk # │ You can issue system calls
|
||||
include libc/thread/thread.mk # │
|
||||
include libc/rand/rand.mk # │
|
||||
include libc/unicode/unicode.mk # │
|
||||
include third_party/dlmalloc/dlmalloc.mk #─┘
|
||||
|
@ -115,6 +114,7 @@ include libc/mem/mem.mk #─┐
|
|||
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
|
||||
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
|
||||
include libc/time/time.mk # │ You can finally call malloc()
|
||||
include libc/thread/thread.mk # │
|
||||
include libc/alg/alg.mk # │
|
||||
include libc/stdio/stdio.mk # │
|
||||
include third_party/libcxx/libcxx.mk # │
|
||||
|
@ -177,6 +177,7 @@ include test/libc/intrin/test.mk
|
|||
include test/libc/mem/test.mk
|
||||
include test/libc/nexgen32e/test.mk
|
||||
include test/libc/runtime/test.mk
|
||||
include test/libc/thread/test.mk
|
||||
include test/libc/sock/test.mk
|
||||
include test/libc/bits/test.mk
|
||||
include test/libc/str/test.mk
|
||||
|
|
Binary file not shown.
52
examples/crashreport2.c
Normal file
52
examples/crashreport2.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileoverview CTRL+\ debugging example
|
||||
*
|
||||
* make -j8 -O o//examples/crashreport2.com
|
||||
* o//examples/crashreport2.com
|
||||
*
|
||||
* Assuming you call ShowCrashReports() from main(), you can press
|
||||
* `CTRL+\` at anny time to generate a `SIGQUIT` message that lets you
|
||||
* debug wrongness and freezups.
|
||||
*
|
||||
* On supported platforms, this will cause GDB to automatically attach.
|
||||
* The nice thing about this, is you can start stepping through your
|
||||
* code at the precice instruction where the interrupt happened. See
|
||||
* `libc/log/attachdebugger.c` to see how it works.
|
||||
*
|
||||
* If you wish to suppress the auto-GDB behavior, then:
|
||||
*
|
||||
* export GDB=
|
||||
*
|
||||
* Or alternatively:
|
||||
*
|
||||
* extern int __isworker;
|
||||
* __isworker = true;
|
||||
*
|
||||
* Will cause your `SIGQUIT` handler to just print a crash report
|
||||
* instead. This is useful for production software that might be running
|
||||
* in a terminal environment like GNU Screen, but it's not desirable to
|
||||
* have ten worker processes trying to attach GDB at once.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
volatile int64_t x;
|
||||
ShowCrashReports();
|
||||
printf("please press ctrl+\\ and see what happens...\n");
|
||||
sigsuspend(0);
|
||||
printf("\n\n");
|
||||
printf("congratulations! your program is now resuming\n");
|
||||
return 0;
|
||||
}
|
|
@ -44,8 +44,8 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
// clang-format off
|
||||
|
||||
/* clang-format off */
|
||||
#define DICT "usr/share/dict/hangman"
|
||||
#define MAXERR 7
|
||||
#define MINSCORE 0
|
||||
|
|
72
examples/rlimit.c
Normal file
72
examples/rlimit.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/color.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/rlim.h"
|
||||
#include "libc/sysv/consts/rlimit.h"
|
||||
|
||||
/**
|
||||
* @fileoverview tool for printing and changing system resource limits
|
||||
*
|
||||
* This is what you do if you want to not accidentally bomb your system
|
||||
* with runaway code. If you haven't accidentally bombed your UNIX
|
||||
* system before then you're not pushing it hard enough.
|
||||
*/
|
||||
|
||||
static void SetLimit(int resource, uint64_t soft, uint64_t hard) {
|
||||
struct rlimit old;
|
||||
struct rlimit lim = {soft, hard};
|
||||
if (resource == 127) return;
|
||||
if (setrlimit(resource, &lim) == -1) {
|
||||
if (!getrlimit(resource, &old)) {
|
||||
lim.rlim_max = MIN(hard, old.rlim_max);
|
||||
lim.rlim_cur = MIN(soft, lim.rlim_max);
|
||||
if (!setrlimit(resource, &lim)) {
|
||||
fprintf(stderr, "%snote: setrlimit(%s) downgraded to {%,ld, %,ld}\n",
|
||||
__strace_rlimit_name(resource), lim.rlim_cur, lim.rlim_max);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "error: setrlimit(%s, %,ld, %,ld) failed %m%n",
|
||||
__strace_rlimit_name(resource), soft, hard);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, rc;
|
||||
struct rlimit rlim;
|
||||
|
||||
// // example of how you might change the limits
|
||||
// SetLimit(RLIMIT_CPU, 3, 33);
|
||||
// SetLimit(RLIMIT_NPROC, 4, 128);
|
||||
// SetLimit(RLIMIT_NOFILE, 32, 128);
|
||||
// SetLimit(RLIMIT_SIGPENDING, 16, 1024);
|
||||
// SetLimit(RLIMIT_AS, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024);
|
||||
// SetLimit(RLIMIT_RSS, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024);
|
||||
// SetLimit(RLIMIT_DATA, 8 * 1024 * 1024, 1l * 1024 * 1024 * 1024);
|
||||
// SetLimit(RLIMIT_FSIZE, 8 * 1000 * 1000, 1l * 1000 * 1000 * 1000);
|
||||
|
||||
for (i = 0; i < RLIM_NLIMITS; ++i) {
|
||||
rc = getrlimit(i, &rlim);
|
||||
printf("setrlimit(%-20s, %,16ld, %,16ld) → %d %s\n",
|
||||
__strace_rlimit_name(i), rlim.rlim_cur, rlim.rlim_max, rc,
|
||||
!rc ? "" : strerror(errno));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -16,12 +16,22 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
|
||||
/**
|
||||
* @fileoverview How to change CPU state on signal delivery
|
||||
*
|
||||
* This program redefines division by zero so that it has a definition.
|
||||
* The definition is the meaning of life, the universe, and everything.
|
||||
* Normally crash signals like `SIGSEGV`, `SIGILL`, and `SIGFPE` aren't
|
||||
* recoverable. This example shows how it actually can be done with Xed
|
||||
* and this example should work on all supported platforms even Windows
|
||||
*/
|
||||
|
||||
void handler(int sig, siginfo_t *si, ucontext_t *ctx) {
|
||||
struct XedDecodedInst xedd;
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64);
|
||||
xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15);
|
||||
ctx->uc_mcontext.rip += xedd.length;
|
||||
ctx->uc_mcontext.rax = 42;
|
||||
ctx->uc_mcontext.rax = 42; // set the DIV result registers rdx:rax
|
||||
ctx->uc_mcontext.rdx = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ int chdir(const char *);
|
|||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t);
|
||||
int chroot(const char *);
|
||||
int clone(int (*)(void *), void *, int, void *, ...);
|
||||
int close(int);
|
||||
int closedir(DIR *);
|
||||
int creat(const char *, uint32_t);
|
||||
|
@ -169,6 +168,7 @@ int sched_yield(void);
|
|||
int setegid(uint32_t);
|
||||
int seteuid(uint32_t);
|
||||
int setgid(int);
|
||||
int setpgrp(void);
|
||||
int setpgid(int, int);
|
||||
int setpriority(int, unsigned, int);
|
||||
int setregid(uint32_t, uint32_t);
|
||||
|
@ -206,7 +206,7 @@ long ptrace(int, ...);
|
|||
long telldir(DIR *);
|
||||
long times(struct tms *);
|
||||
size_t GetFileSize(const char *);
|
||||
size_t getfiledescriptorsize(int);
|
||||
ssize_t getfiledescriptorsize(int);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t lseek(int, int64_t, unsigned);
|
||||
|
@ -233,6 +233,8 @@ void rewinddir(DIR *);
|
|||
void sync(void);
|
||||
int getloadavg(double *, int);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
int clone(int (*)(void *), void *, size_t, int, void *, int *, void *, size_t,
|
||||
int *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » formatting ─╬─│┼
|
||||
|
|
|
@ -110,6 +110,7 @@ o/$(MODE)/libc/calls/execle.o \
|
|||
o/$(MODE)/libc/calls/execlp.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-sysv.o \
|
||||
o/$(MODE)/libc/calls/readlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/mkntenvblock.o: \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
|
|
@ -31,6 +31,7 @@ textwindows int sys_chdir_nt(const char *path) {
|
|||
int e, ms, err, len;
|
||||
char16_t path16[PATH_MAX], var[4];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
if (!len) return enoent();
|
||||
if (len && path16[len - 1] != u'\\') {
|
||||
if (len + 2 > PATH_MAX) return enametoolong();
|
||||
path16[len + 0] = u'\\';
|
||||
|
|
|
@ -42,16 +42,6 @@ textwindows struct DirectMap sys_mmap_nt(void *addr, size_t size, int prot,
|
|||
const struct NtSecurityAttributes *sec;
|
||||
struct NtProcessMemoryCountersEx memcount;
|
||||
|
||||
#if _NT_RLIMIT_PWSS_MB
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(), &memcount, sizeof(memcount))) {
|
||||
if (memcount.PeakWorkingSetSize > _NT_RLIMIT_PWSS_MB * 1048576ull) {
|
||||
kprintf("error: PeakWorkingSetSize %'ldmb exceeded %'ldmb limit%n",
|
||||
memcount.PeakWorkingSetSize / 1048576, (long)_NT_RLIMIT_PWSS_MB);
|
||||
_Exit(201);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fd != -1) {
|
||||
handle = g_fds.p[fd].handle;
|
||||
} else {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,15 +20,13 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) {
|
||||
static bool once, demodernize;
|
||||
int olderr, fd;
|
||||
if (!once) {
|
||||
olderr = errno;
|
||||
fd = __sys_dup3(oldfd, newfd, flags);
|
||||
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
|
||||
if (fd == -1 && errno == ENOSYS) {
|
||||
STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301");
|
||||
demodernize = true;
|
||||
once = true;
|
||||
|
|
|
@ -42,6 +42,17 @@ static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
textwindows dontinline int64_t __fix_enotdir3(int64_t rc, char16_t *path1,
|
||||
char16_t *path2) {
|
||||
if (rc == -1 && errno == kNtErrorPathNotFound) {
|
||||
if ((!path1 || !SubpathExistsThatsNotDirectory(path1)) &&
|
||||
(!path2 || !SubpathExistsThatsNotDirectory(path2))) {
|
||||
errno = kNtErrorFileNotFound;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// WIN32 doesn't distinguish between ENOTDIR and ENOENT. UNIX strictly
|
||||
// requires that a directory component *exists* but is not a directory
|
||||
// whereas WIN32 will return ENOTDIR if a dir label simply isn't found
|
||||
|
@ -54,10 +65,5 @@ static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) {
|
|||
// dangling symbolic link.
|
||||
//
|
||||
textwindows int64_t __fix_enotdir(int64_t rc, char16_t *path) {
|
||||
if (rc == -1 && errno == kNtErrorPathNotFound) {
|
||||
if (!SubpathExistsThatsNotDirectory(path)) {
|
||||
errno = kNtErrorFileNotFound;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return __fix_enotdir3(rc, path, 0);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
/**
|
||||
* Returns information about file, via open()'d descriptor.
|
||||
*
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstat(int fd, struct stat *st) {
|
||||
|
|
|
@ -39,8 +39,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
|||
0)) != -1) {
|
||||
rc = st ? sys_fstat_nt(fh, st) : 0;
|
||||
CloseHandle(fh);
|
||||
return rc;
|
||||
} else {
|
||||
return __winerr();
|
||||
rc = __winerr();
|
||||
}
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,10 @@ textwindows int sys_ftruncate_nt(int64_t handle, uint64_t length) {
|
|||
bool32 ok;
|
||||
int64_t tell;
|
||||
tell = -1;
|
||||
if (SetFilePointerEx(handle, 0, &tell, kNtFileCurrent)) {
|
||||
if ((ok = SetFilePointerEx(handle, 0, &tell, kNtFileCurrent))) {
|
||||
ok = SetFilePointerEx(handle, length, NULL, kNtFileBegin) &&
|
||||
SetEndOfFile(handle);
|
||||
SetFilePointerEx(handle, tell, NULL, kNtFileBegin);
|
||||
return ok ? 0 : __winerr();
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
return ok ? 0 : __winerr();
|
||||
}
|
||||
|
|
|
@ -29,14 +29,15 @@
|
|||
|
||||
char *sys_getcwd_xnu(char *res, size_t size) {
|
||||
int fd;
|
||||
struct stat st[2];
|
||||
union metastat st[2];
|
||||
char buf[XNU_MAXPATHLEN], *ret = NULL;
|
||||
if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) {
|
||||
if (sys_fstat(fd, &st[0]) != -1) {
|
||||
if (st[0].st_dev && st[0].st_ino) {
|
||||
if (__sys_fstat(fd, &st[0]) != -1) {
|
||||
if (METASTAT(st[0], st_dev) && METASTAT(st[0], st_ino)) {
|
||||
if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) {
|
||||
if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
|
||||
if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) {
|
||||
if (__sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
|
||||
if (METASTAT(st[0], st_dev) == METASTAT(st[1], st_dev) &&
|
||||
METASTAT(st[0], st_ino) == METASTAT(st[1], st_ino)) {
|
||||
if (memccpy(res, buf, '\0', size)) {
|
||||
ret = res;
|
||||
} else {
|
||||
|
|
|
@ -16,20 +16,65 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/metastat.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/struct/filestandardinformation.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Determines size of open file.
|
||||
*
|
||||
* @return file byte length, or -1ul w/ errno
|
||||
* This function is equivalent to:
|
||||
*
|
||||
* struct stat st;
|
||||
* !fstat(fd, &st) ? st.st_size : -1
|
||||
*
|
||||
* Except faster on BSD/Windows and a much smaller link size.
|
||||
*
|
||||
* @return file byte length, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t getfiledescriptorsize(int fd) {
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) return SIZE_MAX;
|
||||
return st.st_size;
|
||||
ssize_t getfiledescriptorsize(int fd) {
|
||||
int e;
|
||||
ssize_t rc;
|
||||
union metastat st;
|
||||
struct NtFileStandardInformation info;
|
||||
e = errno;
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
if (weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &st.cosmo) !=
|
||||
-1) {
|
||||
rc = st.cosmo.st_size;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else if (IsMetal()) {
|
||||
rc = -1;
|
||||
} else if (!IsWindows()) {
|
||||
if (!__sys_fstat(fd, &st)) {
|
||||
rc = METASTAT(st, st_size);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (GetFileInformationByHandleEx(g_fds.p[fd].handle, kNtFileStandardInfo,
|
||||
&info, sizeof(info))) {
|
||||
rc = info.EndOfFile;
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
STRACE("getfiledescriptorsize(%d) → %'zd% m", fd, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* Returns the byte length of file by path.
|
||||
*
|
||||
* @return number of bytes, or -1ul w/ errno
|
||||
* @see getfiledescriptorsize
|
||||
* @see getfiledescriptorsize()
|
||||
*/
|
||||
size_t GetFileSize(const char *pathname) {
|
||||
struct stat st;
|
||||
|
|
|
@ -131,6 +131,7 @@ i32 __sys_getrusage(i32, struct rusage *) hidden;
|
|||
i32 __sys_munmap(void *, u64) hidden;
|
||||
i32 __sys_openat(i32, const char *, i32, u32) hidden;
|
||||
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||
i32 __sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden;
|
||||
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
||||
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
||||
i32 sys_chdir(const char *) hidden;
|
||||
|
@ -197,7 +198,7 @@ i32 sys_setsid(void) hidden;
|
|||
i32 sys_setuid(i32) hidden;
|
||||
i32 sys_sigaction(i32, const void *, void *, i64, i64) hidden;
|
||||
i32 sys_sigaltstack(const void *, void *) hidden;
|
||||
i32 sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden;
|
||||
i32 sys_sigprocmask(i32, const sigset *, sigset *) hidden;
|
||||
i32 sys_sigqueue(i32, i32, const union sigval) hidden;
|
||||
i32 sys_sigqueueinfo(i32, const siginfo_t *) hidden;
|
||||
i32 sys_sigsuspend(const sigset *, u64) hidden;
|
||||
|
@ -326,6 +327,7 @@ int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int64_t __fix_enotdir(int64_t, char16_t *) hidden;
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden;
|
||||
bool _check_interrupts(bool, struct Fd *) hidden;
|
||||
void _check_sigchld(void) hidden;
|
||||
void _check_sigalrm(void) hidden;
|
||||
|
|
|
@ -30,7 +30,7 @@ textwindows int sys_linkat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
|||
if (CreateHardLink(newpath16, oldpath16, NULL)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
return __fix_enotdir3(__winerr(), newpath16, oldpath16);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
|
|
|
@ -29,6 +29,7 @@ int __mkntpathat(int dirfd, const char *path, int flags,
|
|||
char16_t dir[PATH_MAX];
|
||||
uint32_t dirlen, filelen;
|
||||
if ((filelen = __mkntpath2(path, file, flags)) == -1) return -1;
|
||||
if (!filelen) return enoent();
|
||||
if (file[0] != u'\\' && dirfd != AT_FDCWD) { /* ProTip: \\?\C:\foo */
|
||||
if (!__isfdkind(dirfd, kFdFile)) return ebadf();
|
||||
dirlen = GetFinalPathNameByHandle(g_fds.p[dirfd].handle, dir, ARRAYLEN(dir),
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
||||
/**
|
||||
* Unmaps memory directly with system.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
||||
if (!cr) return;
|
||||
ctx->uc_flags = cr->EFlags;
|
||||
ctx->uc_mcontext.gregs[REG_EFL] = cr->EFlags;
|
||||
ctx->uc_mcontext.eflags = cr->EFlags;
|
||||
ctx->uc_mcontext.rax = cr->Rax;
|
||||
ctx->uc_mcontext.rbx = cr->Rbx;
|
||||
ctx->uc_mcontext.rcx = cr->Rcx;
|
||||
|
@ -52,7 +52,7 @@ textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
|||
textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
|
||||
if (!cr) return;
|
||||
cr->EFlags = ctx->uc_flags;
|
||||
cr->EFlags = ctx->uc_mcontext.gregs[REG_EFL];
|
||||
cr->EFlags = ctx->uc_mcontext.eflags;
|
||||
cr->Rax = ctx->uc_mcontext.rax;
|
||||
cr->Rbx = ctx->uc_mcontext.rbx;
|
||||
cr->Rcx = ctx->uc_mcontext.rcx;
|
||||
|
|
|
@ -93,5 +93,5 @@ textwindows int ntspawn(
|
|||
}
|
||||
if (block) UnmapViewOfFile(block);
|
||||
if (handle) CloseHandle(handle);
|
||||
return rc;
|
||||
return __fix_enotdir(rc, prog16);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
|
|||
int64_t hin, hout;
|
||||
int reader, writer;
|
||||
char16_t pipename[64];
|
||||
if (!pipefd) return efault();
|
||||
CreatePipeName(pipename);
|
||||
if ((reader = __reservefd(-1)) == -1) return -1;
|
||||
if ((writer = __reservefd(-1)) == -1) {
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
*
|
||||
* @param fd is (reader, writer)
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @raise EFAULT if pipefd is NULL or an invalid address
|
||||
* @raise EMFILE if RLIMIT_NOFILE is exceedde
|
||||
* @asyncsignalsafe
|
||||
* @see pipe2()
|
||||
*/
|
||||
int pipe(int pipefd[hasatleast 2]) {
|
||||
int rc;
|
||||
if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) {
|
||||
if (!pipefd || (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) {
|
||||
// needed for windows which is polyfilled
|
||||
// needed for xnu and netbsd which don't take an argument
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_pipe(pipefd);
|
||||
|
|
|
@ -19,16 +19,15 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
#define __NR_pipe2_linux 0x0125 /*RHEL5:CVE-2010-3301*/
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int32_t sys_pipe2(int pipefd[hasatleast 2], unsigned flags) {
|
||||
int rc, olderr;
|
||||
if (!flags) goto OldSkool;
|
||||
olderr = errno;
|
||||
rc = __sys_pipe2(pipefd, flags);
|
||||
if ((rc == -1 && errno == ENOSYS) ||
|
||||
(SupportsLinux() && rc == __NR_pipe2_linux)) {
|
||||
if (rc == -1 && errno == ENOSYS) {
|
||||
errno = olderr;
|
||||
OldSkool:
|
||||
if ((rc = sys_pipe(pipefd)) != -1) {
|
||||
|
|
|
@ -20,20 +20,22 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Creates file-less file descriptors for interprocess communication.
|
||||
*
|
||||
* @param pipefd is used to return (reader, writer) file descriptors
|
||||
* @param flags can have O_CLOEXEC, O_NONBLOCK, O_DIRECT
|
||||
* @param flags can have O_CLOEXEC or O_DIRECT or O_NONBLOCK
|
||||
* @return 0 on success, or -1 w/ errno and pipefd isn't modified
|
||||
*/
|
||||
int pipe2(int pipefd[hasatleast 2], int flags) {
|
||||
int rc;
|
||||
if (!pipefd) {
|
||||
rc = efault();
|
||||
} else if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) {
|
||||
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) {
|
||||
return einval();
|
||||
} else if (!pipefd ||
|
||||
(IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_pipe2(pipefd, flags);
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_preadv_linux 0x0127
|
||||
|
||||
/**
|
||||
* Reads with maximum generality.
|
||||
*
|
||||
|
@ -76,14 +74,6 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
|
|||
once = true;
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "preadv", "ENOSYS");
|
||||
} else if (IsLinux() && rc == __NR_preadv_linux) {
|
||||
if (__iovec_size(iov, iovlen) < __NR_preadv_linux) {
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "preadv", "RHEL5:CVE-2010-3301");
|
||||
once = true;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
once = true;
|
||||
return rc;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
|
@ -46,7 +47,7 @@
|
|||
|
||||
char program_executable_name[SIZE];
|
||||
|
||||
static textwindows bool GetNtExePath(char executable[SIZE]) {
|
||||
static textwindows bool GetNtExePath(char exe[SIZE]) {
|
||||
bool32 rc;
|
||||
uint64_t w;
|
||||
wint_t x, y;
|
||||
|
@ -54,7 +55,7 @@ static textwindows bool GetNtExePath(char executable[SIZE]) {
|
|||
char16_t path16[PATH_MAX + 1];
|
||||
path16[0] = 0;
|
||||
rc = GetModuleFileName(0, path16, ARRAYLEN(path16));
|
||||
STRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||
NTTRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||
if (!rc) return false;
|
||||
for (i = j = 0; (x = path16[i++] & 0xffff);) {
|
||||
if (!IsUcs2(x)) {
|
||||
|
@ -64,47 +65,49 @@ static textwindows bool GetNtExePath(char executable[SIZE]) {
|
|||
if (x == '\\') x = '/';
|
||||
w = tpenc(x);
|
||||
do {
|
||||
executable[j] = w;
|
||||
exe[j] = w;
|
||||
if (++j == SIZE) {
|
||||
return false;
|
||||
}
|
||||
} while ((w >>= 8));
|
||||
}
|
||||
executable[j] = 0;
|
||||
exe[j] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ReadProgramExecutableName(char executable[SIZE], char *argv0,
|
||||
static void ReadProgramExecutableName(char exe[SIZE], char *argv0,
|
||||
uintptr_t *auxv) {
|
||||
int e;
|
||||
size_t m;
|
||||
ssize_t n;
|
||||
int cmd[4];
|
||||
char *p, *t;
|
||||
if (IsWindows() && GetNtExePath(executable)) {
|
||||
return;
|
||||
}
|
||||
for (p = 0; *auxv; auxv += 2) {
|
||||
if (*auxv == AT_EXECFN) {
|
||||
p = (char *)auxv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
if (!p) p = argv0;
|
||||
if (p) {
|
||||
if (!_isabspath(p)) {
|
||||
if (getcwd(executable, SIZE - 1)) {
|
||||
n = strlen(executable);
|
||||
executable[n++] = '/';
|
||||
e = errno;
|
||||
if (!IsWindows() || !GetNtExePath(exe)) {
|
||||
for (p = 0; *auxv; auxv += 2) {
|
||||
if (*auxv == AT_EXECFN) {
|
||||
p = (char *)auxv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; *p; ++p) {
|
||||
if (n + 1 < SIZE) {
|
||||
executable[n++] = *p;
|
||||
n = 0;
|
||||
if (!p) p = argv0;
|
||||
if (p) {
|
||||
if (!_isabspath(p)) {
|
||||
if (getcwd(exe, SIZE - 1)) {
|
||||
n = strlen(exe);
|
||||
exe[n++] = '/';
|
||||
}
|
||||
}
|
||||
for (; *p; ++p) {
|
||||
if (n + 1 < SIZE) {
|
||||
exe[n++] = *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
exe[n] = 0;
|
||||
}
|
||||
executable[n] = 0;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,14 +127,9 @@ static void ReadProgramExecutableName(char executable[SIZE], char *argv0,
|
|||
* @see program_invocation_name
|
||||
*/
|
||||
char *GetProgramExecutableName(void) {
|
||||
int e;
|
||||
static bool once;
|
||||
char executable[SIZE];
|
||||
if (!once) {
|
||||
e = errno;
|
||||
ReadProgramExecutableName(executable, __argv[0], __auxv);
|
||||
errno = e;
|
||||
__stpcpy(program_executable_name, executable);
|
||||
ReadProgramExecutableName(program_executable_name, __argv[0], __auxv);
|
||||
once = true;
|
||||
}
|
||||
return program_executable_name;
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_pwritev_linux 0x0128
|
||||
|
||||
/**
|
||||
* Writes data from multiple buffers to offset.
|
||||
*
|
||||
|
@ -80,15 +78,6 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
|||
once = true;
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS");
|
||||
} else if (IsLinux() && rc == __NR_pwritev_linux) {
|
||||
if (__iovec_size(iov, iovlen) < __NR_pwritev_linux) {
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "pwritev",
|
||||
"RHEL5:CVE-2010-3301");
|
||||
once = true;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
once = true;
|
||||
return rc;
|
||||
|
|
|
@ -16,30 +16,21 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
||||
size_t size, ssize_t offset) {
|
||||
uint32_t err, got, avail;
|
||||
uint32_t got, avail;
|
||||
struct NtOverlapped overlap;
|
||||
if (GetFileType(fd->handle) == kNtFileTypePipe) {
|
||||
for (;;) {
|
||||
|
@ -60,14 +51,16 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
|||
_offset2overlap(fd->handle, offset, &overlap))) {
|
||||
return got;
|
||||
}
|
||||
err = GetLastError();
|
||||
// make sure read() returns 0 on broken pipe
|
||||
if (err == kNtErrorBrokenPipe) return 0;
|
||||
// make sure read() returns 0 on closing named pipe
|
||||
if (err == kNtErrorNoData) return 0;
|
||||
// make sure pread() returns 0 if we start reading after EOF
|
||||
if (err == kNtErrorHandleEof) return 0;
|
||||
return __winerr();
|
||||
switch (GetLastError()) {
|
||||
case kNtErrorBrokenPipe: // broken pipe
|
||||
case kNtErrorNoData: // closing named pipe
|
||||
case kNtErrorHandleEof: // pread read past EOF
|
||||
return 0; //
|
||||
case kNtErrorAccessDenied: // read doesn't return EACCESS
|
||||
return ebadf(); //
|
||||
default:
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
|
||||
textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov,
|
||||
|
|
|
@ -22,16 +22,10 @@
|
|||
/**
|
||||
* Reads symbolic link.
|
||||
*
|
||||
* This does *not* nul-terminate the buffer.
|
||||
*
|
||||
* It is recommended that malloc() be linked into your program when
|
||||
* using this function. Otherwise the buffer should be larger. It should
|
||||
* also be noted that, without malloc, long names with many astral plane
|
||||
* characters might not decode properly.
|
||||
*
|
||||
* @param path must be a symbolic link pathname
|
||||
* @param buf will receive symbolic link contents, and won't be modified
|
||||
* unless the function succeeds (with the exception of no-malloc nt)
|
||||
* and this buffer will *not* be nul-terminated
|
||||
* @return number of bytes written to buf, or -1 w/ errno; if the
|
||||
* return is equal to bufsiz then truncation may have occurred
|
||||
* @see readlinkat(AT_FDCWD, ...) for modern version of this
|
||||
|
|
|
@ -16,22 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fsctl.h"
|
||||
#include "libc/nt/enum/io.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/reparsedatabuffer.h"
|
||||
|
@ -45,25 +37,15 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
ssize_t rc;
|
||||
uint64_t w;
|
||||
wint_t x, y;
|
||||
void *freeme;
|
||||
volatile char *memory;
|
||||
uint32_t i, j, n, mem;
|
||||
char16_t path16[PATH_MAX], *p;
|
||||
struct NtReparseDataBuffer *rdb;
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (weaken(malloc)) {
|
||||
mem = 16384;
|
||||
rdb = weaken(malloc)(mem);
|
||||
freeme = rdb;
|
||||
} else if (bufsiz >= sizeof(struct NtReparseDataBuffer) + 16) {
|
||||
mem = bufsiz;
|
||||
rdb = (struct NtReparseDataBuffer *)buf;
|
||||
freeme = 0;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() needs bigger buffer malloc() to be yoinked");
|
||||
return enomem();
|
||||
}
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
mem = 16384;
|
||||
memory = alloca(mem);
|
||||
for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0;
|
||||
rdb = (struct NtReparseDataBuffer *)memory;
|
||||
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
|
||||
kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics,
|
||||
0)) != -1) {
|
||||
|
@ -99,26 +81,17 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
w >>= 8;
|
||||
} while (w);
|
||||
}
|
||||
if (freeme || (intptr_t)(buf + j) <= (intptr_t)(p + i)) {
|
||||
rc = j;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() too many astral codepoints");
|
||||
rc = enametoolong();
|
||||
}
|
||||
rc = j;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() should have kNtIoReparseTagSymlink");
|
||||
rc = einval();
|
||||
}
|
||||
} else {
|
||||
assert(errno == EINVAL);
|
||||
rc = -1;
|
||||
}
|
||||
CloseHandle(h);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
if (freeme && weaken(free)) {
|
||||
weaken(free)(freeme);
|
||||
rc = __fix_enotdir(-1, path16);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
|
@ -33,16 +29,12 @@
|
|||
*
|
||||
* This does *not* nul-terminate the buffer.
|
||||
*
|
||||
* It is recommended that malloc() be linked into your program when
|
||||
* using this function. Otherwise the buffer should be larger. It should
|
||||
* also be noted that, without malloc, long names with many astral plane
|
||||
* characters might not decode properly.
|
||||
*
|
||||
* @param dirfd is normally AT_FDCWD but if it's an open directory and
|
||||
* file is a relative path, then file is opened relative to dirfd
|
||||
* @param path must be a symbolic link pathname
|
||||
* @param buf will receive symbolic link contents, and won't be modified
|
||||
* unless the function succeeds (with the exception of no-malloc nt)
|
||||
* and this buffer will *not* be nul-terminated
|
||||
* @return number of bytes written to buf, or -1 w/ errno; if the
|
||||
* return is equal to bufsiz then truncation may have occurred
|
||||
* @error EINVAL if path isn't a symbolic link
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
/**
|
||||
* Moves file the Unix way.
|
||||
*
|
||||
* This is generally an atomic operation with the file system, since all
|
||||
* it's doing is changing a name associated with an inode. However, that
|
||||
* means rename() doesn't permit your `oldpathname` and `newpathname` to
|
||||
* be on separate file systems, in which case this returns EXDEV. That's
|
||||
* also the case on Windows.
|
||||
*
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
|
|
|
@ -19,12 +19,9 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/movefileexflags.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
const char *newpath) {
|
||||
char16_t oldpath16[PATH_MAX];
|
||||
char16_t newpath16[PATH_MAX];
|
||||
if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) == -1 ||
|
||||
|
@ -34,6 +31,6 @@ textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
|||
if (MoveFileEx(oldpath16, newpath16, kNtMovefileReplaceExisting)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
return __fix_enotdir3(-1, oldpath16, newpath16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
/**
|
||||
* Renames files relative to directories.
|
||||
*
|
||||
* This is generally an atomic operation with the file system, since all
|
||||
* it's doing is changing a name associated with an inode. However, that
|
||||
* means rename() doesn't permit your `oldpathname` and `newpathname` to
|
||||
* be on separate file systems, in which case this returns EXDEV. That's
|
||||
* also the case on Windows.
|
||||
*
|
||||
* @param olddirfd is normally AT_FDCWD but if it's an open directory
|
||||
* and oldpath is relative, then oldpath become relative to dirfd
|
||||
* @param newdirfd is normally AT_FDCWD but if it's an open directory
|
||||
|
|
26
libc/calls/setpgrp.c
Normal file
26
libc/calls/setpgrp.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
/**
|
||||
* Sets the process group ID.
|
||||
*/
|
||||
int setpgrp(void) {
|
||||
return setpgid(0, 0);
|
||||
}
|
|
@ -44,11 +44,20 @@
|
|||
* when the hard limit is exceeded. It works everywhere but Windows
|
||||
*
|
||||
* - `RLIMIT_NPROC` limits the number of simultaneous processes and it
|
||||
* should work on all platforms except Windows.
|
||||
* should work on all platforms except Windows. Please be advised it
|
||||
* limits the process, with respect to the activities of the user id
|
||||
* as a whole.
|
||||
*
|
||||
* - `RLIMIT_NOFILE` limits the number of open file descriptors and it
|
||||
* should work on all platforms except Windows (TODO)
|
||||
*
|
||||
* The rlimit magnums differ for each platform but occupy the interval
|
||||
* zero through `RLIM_NLIMITS`. Usually they're set to `RLIM_INFINITY`
|
||||
* which is `-1` on Linux/Windows, and `LONG_MAX` on BSDs. In any case
|
||||
* they're both very large numbers under the Cosmopolitan unsigned ABI
|
||||
* because struct rlimit uses uint64_t. The special magnum 127 is used
|
||||
* for constant values that aren't supported by the host platform.
|
||||
*
|
||||
* @param rlim specifies new resource limit
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @see libc/sysv/consts.sh
|
||||
|
|
|
@ -149,7 +149,11 @@ static textwindows bool __sig_deliver(bool restartable, int sig, int si_code,
|
|||
* Returns true if signal default action is to end process.
|
||||
*/
|
||||
static textwindows bool __sig_isfatal(int sig) {
|
||||
return sig != SIGCHLD;
|
||||
if (sig == SIGCHLD || sig == SIGURG || sig == SIGWINCH) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#undef sigaction
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
STATIC_YOINK("strsignal"); // for kprintf()
|
||||
#endif
|
||||
|
@ -75,9 +77,9 @@ union metasigaction {
|
|||
struct sigaction_xnu_out xnu_out;
|
||||
};
|
||||
|
||||
void __sigenter_netbsd(int, void *, void *);
|
||||
void __sigenter_freebsd(int, void *, void *);
|
||||
void __sigenter_openbsd(int, void *, void *);
|
||||
void __sigenter_netbsd(int, void *, void *) hidden;
|
||||
void __sigenter_freebsd(int, void *, void *) hidden;
|
||||
void __sigenter_openbsd(int, void *, void *) hidden;
|
||||
|
||||
static void sigaction_cosmo2native(union metasigaction *sa) {
|
||||
if (!sa) return;
|
||||
|
@ -279,7 +281,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
* `SA_NOMASK` for this flag, which means the same thing.
|
||||
*
|
||||
* - `SA_NOCLDWAIT`: Changes `SIGCHLD` so the zombie is gone and you
|
||||
* can't call `wait()` anymore; similar to SIGCHLD + SIG_IGN but may
|
||||
* can't call `wait()` anymore; similar but may
|
||||
* still deliver the SIGCHLD.
|
||||
*
|
||||
* - `SA_NOCLDSTOP`: Lets you set `SIGCHLD` handler that's only notified
|
||||
|
@ -435,7 +437,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||
int rc;
|
||||
char buf[2][128];
|
||||
if (sig == SIGKILL || sig == SIGSTOP) {
|
||||
|
|
|
@ -45,10 +45,9 @@ void _check_sigchld(void) {
|
|||
STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
|
||||
return;
|
||||
}
|
||||
if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN) {
|
||||
STRACE("killing zombie fd=%d handle=%ld", pids[i], handles[i]);
|
||||
CloseHandle(handles[i]);
|
||||
__releasefd(pids[i]);
|
||||
if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN ||
|
||||
__sighandrvas[SIGCHLD] == (intptr_t)SIG_DFL) {
|
||||
STRACE("new zombie fd=%d handle=%ld", pids[i], handles[i]);
|
||||
return;
|
||||
}
|
||||
if (__sighandflags[SIGCHLD] & SA_NOCLDWAIT) {
|
||||
|
|
|
@ -21,68 +21,13 @@
|
|||
#include "libc/calls/struct/sigaction-freebsd.internal.h"
|
||||
#include "libc/calls/struct/siginfo-netbsd.internal.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/ucontext-netbsd.internal.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
#define RDI 0
|
||||
#define RSI 1
|
||||
#define RDX 2
|
||||
#define R10 6
|
||||
#define R8 4
|
||||
#define R9 5
|
||||
#define RCX 3
|
||||
#define R11 7
|
||||
#define R12 8
|
||||
#define R13 9
|
||||
#define R14 10
|
||||
#define R15 11
|
||||
#define RBP 12
|
||||
#define RBX 13
|
||||
#define RAX 14
|
||||
#define GS 15
|
||||
#define FS 16
|
||||
#define ES 17
|
||||
#define DS 18
|
||||
#define TRAP 19
|
||||
#define ERR 20
|
||||
#define RIP 21
|
||||
#define CS 22
|
||||
#define RFLAGS 23
|
||||
#define RSP 24
|
||||
#define SS 25
|
||||
|
||||
union sigval_netbsd {
|
||||
int32_t sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
struct sigset_netbsd {
|
||||
uint32_t __bits[4];
|
||||
};
|
||||
|
||||
struct stack_netbsd {
|
||||
void *ss_sp;
|
||||
size_t ss_size;
|
||||
int32_t ss_flags;
|
||||
};
|
||||
|
||||
struct mcontext_netbsd {
|
||||
int64_t __gregs[26];
|
||||
int64_t _mc_tlsbase;
|
||||
struct FpuState __fpregs;
|
||||
};
|
||||
|
||||
struct ucontext_netbsd {
|
||||
uint32_t uc_flags;
|
||||
struct ucontext_netbsd *uc_link;
|
||||
struct sigset_netbsd uc_sigmask;
|
||||
struct stack_netbsd uc_stack;
|
||||
struct mcontext_netbsd uc_mcontext;
|
||||
};
|
||||
|
||||
void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
||||
struct ucontext_netbsd *ctx) {
|
||||
int rva, flags;
|
||||
|
@ -109,50 +54,50 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
|
||||
memcpy(&uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
uc.uc_mcontext.rdi = ctx->uc_mcontext.__gregs[RDI];
|
||||
uc.uc_mcontext.rsi = ctx->uc_mcontext.__gregs[RSI];
|
||||
uc.uc_mcontext.rdx = ctx->uc_mcontext.__gregs[RDX];
|
||||
uc.uc_mcontext.rcx = ctx->uc_mcontext.__gregs[RCX];
|
||||
uc.uc_mcontext.r8 = ctx->uc_mcontext.__gregs[R8];
|
||||
uc.uc_mcontext.r9 = ctx->uc_mcontext.__gregs[R9];
|
||||
uc.uc_mcontext.rax = ctx->uc_mcontext.__gregs[RAX];
|
||||
uc.uc_mcontext.rbx = ctx->uc_mcontext.__gregs[RBX];
|
||||
uc.uc_mcontext.rbp = ctx->uc_mcontext.__gregs[RBP];
|
||||
uc.uc_mcontext.r10 = ctx->uc_mcontext.__gregs[R10];
|
||||
uc.uc_mcontext.r11 = ctx->uc_mcontext.__gregs[R11];
|
||||
uc.uc_mcontext.r12 = ctx->uc_mcontext.__gregs[R12];
|
||||
uc.uc_mcontext.r13 = ctx->uc_mcontext.__gregs[R13];
|
||||
uc.uc_mcontext.r14 = ctx->uc_mcontext.__gregs[R14];
|
||||
uc.uc_mcontext.r15 = ctx->uc_mcontext.__gregs[R15];
|
||||
uc.uc_mcontext.trapno = ctx->uc_mcontext.__gregs[TRAP];
|
||||
uc.uc_mcontext.fs = ctx->uc_mcontext.__gregs[FS];
|
||||
uc.uc_mcontext.gs = ctx->uc_mcontext.__gregs[GS];
|
||||
uc.uc_mcontext.err = ctx->uc_mcontext.__gregs[ERR];
|
||||
uc.uc_mcontext.rip = ctx->uc_mcontext.__gregs[RIP];
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.__gregs[RSP];
|
||||
uc.uc_mcontext.rdi = ctx->uc_mcontext.rdi;
|
||||
uc.uc_mcontext.rsi = ctx->uc_mcontext.rsi;
|
||||
uc.uc_mcontext.rdx = ctx->uc_mcontext.rdx;
|
||||
uc.uc_mcontext.rcx = ctx->uc_mcontext.rcx;
|
||||
uc.uc_mcontext.r8 = ctx->uc_mcontext.r8;
|
||||
uc.uc_mcontext.r9 = ctx->uc_mcontext.r9;
|
||||
uc.uc_mcontext.rax = ctx->uc_mcontext.rax;
|
||||
uc.uc_mcontext.rbx = ctx->uc_mcontext.rbx;
|
||||
uc.uc_mcontext.rbp = ctx->uc_mcontext.rbp;
|
||||
uc.uc_mcontext.r10 = ctx->uc_mcontext.r10;
|
||||
uc.uc_mcontext.r11 = ctx->uc_mcontext.r11;
|
||||
uc.uc_mcontext.r12 = ctx->uc_mcontext.r12;
|
||||
uc.uc_mcontext.r13 = ctx->uc_mcontext.r13;
|
||||
uc.uc_mcontext.r14 = ctx->uc_mcontext.r14;
|
||||
uc.uc_mcontext.r15 = ctx->uc_mcontext.r15;
|
||||
uc.uc_mcontext.trapno = ctx->uc_mcontext.trapno;
|
||||
uc.uc_mcontext.fs = ctx->uc_mcontext.fs;
|
||||
uc.uc_mcontext.gs = ctx->uc_mcontext.gs;
|
||||
uc.uc_mcontext.err = ctx->uc_mcontext.err;
|
||||
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
|
||||
*uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs;
|
||||
((sigaction_f)(_base + rva))(sig, &si2, &uc);
|
||||
ctx->uc_mcontext.__gregs[RDI] = uc.uc_mcontext.rdi;
|
||||
ctx->uc_mcontext.__gregs[RSI] = uc.uc_mcontext.rsi;
|
||||
ctx->uc_mcontext.__gregs[RDX] = uc.uc_mcontext.rdx;
|
||||
ctx->uc_mcontext.__gregs[RCX] = uc.uc_mcontext.rcx;
|
||||
ctx->uc_mcontext.__gregs[R8] = uc.uc_mcontext.r8;
|
||||
ctx->uc_mcontext.__gregs[R9] = uc.uc_mcontext.r9;
|
||||
ctx->uc_mcontext.__gregs[RAX] = uc.uc_mcontext.rax;
|
||||
ctx->uc_mcontext.__gregs[RBX] = uc.uc_mcontext.rbx;
|
||||
ctx->uc_mcontext.__gregs[RBP] = uc.uc_mcontext.rbp;
|
||||
ctx->uc_mcontext.__gregs[R10] = uc.uc_mcontext.r10;
|
||||
ctx->uc_mcontext.__gregs[R11] = uc.uc_mcontext.r11;
|
||||
ctx->uc_mcontext.__gregs[R12] = uc.uc_mcontext.r12;
|
||||
ctx->uc_mcontext.__gregs[R13] = uc.uc_mcontext.r13;
|
||||
ctx->uc_mcontext.__gregs[R14] = uc.uc_mcontext.r14;
|
||||
ctx->uc_mcontext.__gregs[R15] = uc.uc_mcontext.r15;
|
||||
ctx->uc_mcontext.__gregs[TRAP] = uc.uc_mcontext.trapno;
|
||||
ctx->uc_mcontext.__gregs[FS] = uc.uc_mcontext.fs;
|
||||
ctx->uc_mcontext.__gregs[GS] = uc.uc_mcontext.gs;
|
||||
ctx->uc_mcontext.__gregs[ERR] = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.__gregs[RIP] = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.__gregs[RSP] = uc.uc_mcontext.rsp;
|
||||
ctx->uc_mcontext.rdi = uc.uc_mcontext.rdi;
|
||||
ctx->uc_mcontext.rsi = uc.uc_mcontext.rsi;
|
||||
ctx->uc_mcontext.rdx = uc.uc_mcontext.rdx;
|
||||
ctx->uc_mcontext.rcx = uc.uc_mcontext.rcx;
|
||||
ctx->uc_mcontext.r8 = uc.uc_mcontext.r8;
|
||||
ctx->uc_mcontext.r9 = uc.uc_mcontext.r9;
|
||||
ctx->uc_mcontext.rax = uc.uc_mcontext.rax;
|
||||
ctx->uc_mcontext.rbx = uc.uc_mcontext.rbx;
|
||||
ctx->uc_mcontext.rbp = uc.uc_mcontext.rbp;
|
||||
ctx->uc_mcontext.r10 = uc.uc_mcontext.r10;
|
||||
ctx->uc_mcontext.r11 = uc.uc_mcontext.r11;
|
||||
ctx->uc_mcontext.r12 = uc.uc_mcontext.r12;
|
||||
ctx->uc_mcontext.r13 = uc.uc_mcontext.r13;
|
||||
ctx->uc_mcontext.r14 = uc.uc_mcontext.r14;
|
||||
ctx->uc_mcontext.r15 = uc.uc_mcontext.r15;
|
||||
ctx->uc_mcontext.trapno = uc.uc_mcontext.trapno;
|
||||
ctx->uc_mcontext.fs = uc.uc_mcontext.fs;
|
||||
ctx->uc_mcontext.gs = uc.uc_mcontext.gs;
|
||||
ctx->uc_mcontext.err = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.rip = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.rsp = uc.uc_mcontext.rsp;
|
||||
ctx->uc_mcontext.__fpregs = *uc.uc_mcontext.fpregs;
|
||||
}
|
||||
}
|
||||
|
|
48
libc/calls/sigprocmask-sysv.c
Normal file
48
libc/calls/sigprocmask-sysv.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
int sys_sigprocmask(int how, const sigset_t *opt_set,
|
||||
sigset_t *opt_out_oldset) {
|
||||
int res, rc, arg1;
|
||||
sigset_t old = {0};
|
||||
const sigset_t *arg2;
|
||||
if (!IsOpenbsd()) {
|
||||
rc = __sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0, 8);
|
||||
} else {
|
||||
if (opt_set) {
|
||||
// openbsd only supports 32 signals so it passses them in a reg
|
||||
arg1 = how;
|
||||
arg2 = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||
} else {
|
||||
arg1 = how; // SIG_BLOCK
|
||||
arg2 = 0; // changes nothing
|
||||
}
|
||||
if ((res = __sys_sigprocmask(arg1, arg2, 0, 0)) != -1) {
|
||||
memcpy(&old, &res, sizeof(res));
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
if (rc != -1 && opt_out_oldset) {
|
||||
*opt_out_oldset = old;
|
||||
}
|
||||
return rc;
|
||||
}
|
|
@ -68,26 +68,11 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
|||
(opt_out_oldset &&
|
||||
!__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset))))) {
|
||||
rc = efault();
|
||||
} else if (IsLinux() || IsXnu() || IsFreebsd() || IsNetbsd()) {
|
||||
rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0, 8);
|
||||
} else if (IsOpenbsd()) {
|
||||
if (opt_set) {
|
||||
// openbsd only supports 32 signals so it passses them in a reg
|
||||
arg1 = how;
|
||||
arg2 = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||
} else {
|
||||
arg1 = how; // SIG_BLOCK
|
||||
arg2 = 0; // changes nothing
|
||||
}
|
||||
if ((res = sys_sigprocmask(arg1, arg2, 0, 0)) != -1) {
|
||||
memcpy(&old, &res, sizeof(res));
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else { // windows or metal
|
||||
} else if (IsMetal() || IsWindows()) {
|
||||
rc = __sig_mask(how, opt_set, &old);
|
||||
_check_interrupts(false, 0);
|
||||
} else {
|
||||
rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0);
|
||||
}
|
||||
if (rc != -1 && opt_out_oldset) {
|
||||
*opt_out_oldset = old;
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
|
||||
#define _NT_RLIMIT_PWSS_MB 1000 /* nocommit */
|
||||
#define _KERNTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||
#define _NTTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _KERNTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||
#define _NTTRACE 0 /* not configurable w/ flag yet */
|
||||
|
||||
#define STRACE_PROLOGUE "%rSYS %5P %'18T "
|
||||
|
||||
|
|
|
@ -24,9 +24,27 @@
|
|||
|
||||
const char *__strace_rlimit_name(int resource) {
|
||||
static char buf[12];
|
||||
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||
if (resource != 127) {
|
||||
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||
if (resource == RLIMIT_NPROC) return "RLIMIT_NPROC";
|
||||
if (resource == RLIMIT_NOFILE) return "RLIMIT_NOFILE";
|
||||
if (resource == RLIMIT_RSS) return "RLIMIT_RSS";
|
||||
if (resource == RLIMIT_DATA) return "RLIMIT_DATA";
|
||||
if (resource == RLIMIT_CORE) return "RLIMIT_CORE";
|
||||
if (resource == RLIMIT_STACK) return "RLIMIT_STACK";
|
||||
if (resource == RLIMIT_SIGPENDING) return "RLIMIT_SIGPENDING";
|
||||
if (resource == RLIMIT_MEMLOCK) return "RLIMIT_MEMLOCK";
|
||||
if (resource == RLIMIT_LOCKS) return "RLIMIT_LOCKS";
|
||||
if (resource == RLIMIT_MSGQUEUE) return "RLIMIT_MSGQUEUE";
|
||||
if (resource == RLIMIT_NICE) return "RLIMIT_NICE";
|
||||
if (resource == RLIMIT_RTPRIO) return "RLIMIT_RTPRIO";
|
||||
if (resource == RLIMIT_RTTIME) return "RLIMIT_RTTIME";
|
||||
if (resource == RLIMIT_SWAP) return "RLIMIT_SWAP";
|
||||
if (resource == RLIMIT_SBSIZE) return "RLIMIT_SBSIZE";
|
||||
if (resource == RLIMIT_NPTS) return "RLIMIT_NPTS";
|
||||
}
|
||||
FormatInt32(buf, resource);
|
||||
return buf;
|
||||
}
|
||||
|
@ -35,6 +53,6 @@ privileged const char *__strace_rlimit(char buf[64], size_t bufsize, int rc,
|
|||
const struct rlimit *rlim) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!rlim) return "NULL";
|
||||
ksnprintf(buf, bufsize, "{%'lu, %'lu}", rlim->rlim_cur, rlim->rlim_max);
|
||||
ksnprintf(buf, bufsize, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max);
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -325,6 +325,9 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff
|
||||
#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56
|
||||
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \
|
||||
(((uint64_t)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
|
||||
|
||||
#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0)
|
||||
#define BPF_LOCAL_STORAGE_GET_F_CREATE (1ULL << 0)
|
||||
#define BPF_SK_STORAGE_GET_F_CREATE BPF_LOCAL_STORAGE_GET_F_CREATE
|
||||
|
@ -352,7 +355,8 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_F_BROADCAST (1ULL << 3)
|
||||
#define BPF_F_EXCLUDE_INGRESS (1ULL << 4)
|
||||
|
||||
#define BPF_TAG_SIZE 8
|
||||
#define XDP_PACKET_HEADROOM 256
|
||||
#define BPF_TAG_SIZE 8
|
||||
|
||||
#define BPF_SOCK_OPS_RTO_CB_FLAG (1 << 0)
|
||||
#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1 << 1)
|
||||
|
@ -451,10 +455,176 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_REDIRECT 7
|
||||
#define BPF_LWT_REROUTE 128
|
||||
|
||||
#define XDP_PACKET_HEADROOM 256
|
||||
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \
|
||||
(((uint64_t)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
|
||||
#define BPF_FUNC_unspec 0
|
||||
#define BPF_FUNC_map_lookup_elem 1
|
||||
#define BPF_FUNC_map_update_elem 2
|
||||
#define BPF_FUNC_map_delete_elem 3
|
||||
#define BPF_FUNC_probe_read 4
|
||||
#define BPF_FUNC_ktime_get_ns 5
|
||||
#define BPF_FUNC_trace_printk 6
|
||||
#define BPF_FUNC_get_prandom_u32 7
|
||||
#define BPF_FUNC_get_smp_processor_id 8
|
||||
#define BPF_FUNC_skb_store_bytes 9
|
||||
#define BPF_FUNC_l3_csum_replace 10
|
||||
#define BPF_FUNC_l4_csum_replace 11
|
||||
#define BPF_FUNC_tail_call 12
|
||||
#define BPF_FUNC_clone_redirect 13
|
||||
#define BPF_FUNC_get_current_pid_tgid 14
|
||||
#define BPF_FUNC_get_current_uid_gid 15
|
||||
#define BPF_FUNC_get_current_comm 16
|
||||
#define BPF_FUNC_get_cgroup_classid 17
|
||||
#define BPF_FUNC_skb_vlan_push 18
|
||||
#define BPF_FUNC_skb_vlan_pop 19
|
||||
#define BPF_FUNC_skb_get_tunnel_key 20
|
||||
#define BPF_FUNC_skb_set_tunnel_key 21
|
||||
#define BPF_FUNC_perf_event_read 22
|
||||
#define BPF_FUNC_redirect 23
|
||||
#define BPF_FUNC_get_route_realm 24
|
||||
#define BPF_FUNC_perf_event_output 25
|
||||
#define BPF_FUNC_skb_load_bytes 26
|
||||
#define BPF_FUNC_get_stackid 27
|
||||
#define BPF_FUNC_csum_diff 28
|
||||
#define BPF_FUNC_skb_get_tunnel_opt 29
|
||||
#define BPF_FUNC_skb_set_tunnel_opt 30
|
||||
#define BPF_FUNC_skb_change_proto 31
|
||||
#define BPF_FUNC_skb_change_type 32
|
||||
#define BPF_FUNC_skb_under_cgroup 33
|
||||
#define BPF_FUNC_get_hash_recalc 34
|
||||
#define BPF_FUNC_get_current_task 35
|
||||
#define BPF_FUNC_probe_write_user 36
|
||||
#define BPF_FUNC_current_task_under_cgroup 37
|
||||
#define BPF_FUNC_skb_change_tail 38
|
||||
#define BPF_FUNC_skb_pull_data 39
|
||||
#define BPF_FUNC_csum_update 40
|
||||
#define BPF_FUNC_set_hash_invalid 41
|
||||
#define BPF_FUNC_get_numa_node_id 42
|
||||
#define BPF_FUNC_skb_change_head 43
|
||||
#define BPF_FUNC_xdp_adjust_head 44
|
||||
#define BPF_FUNC_probe_read_str 45
|
||||
#define BPF_FUNC_get_socket_cookie 46
|
||||
#define BPF_FUNC_get_socket_uid 47
|
||||
#define BPF_FUNC_set_hash 48
|
||||
#define BPF_FUNC_setsockopt 49
|
||||
#define BPF_FUNC_skb_adjust_room 50
|
||||
#define BPF_FUNC_redirect_map 51
|
||||
#define BPF_FUNC_sk_redirect_map 52
|
||||
#define BPF_FUNC_sock_map_update 53
|
||||
#define BPF_FUNC_xdp_adjust_meta 54
|
||||
#define BPF_FUNC_perf_event_read_value 55
|
||||
#define BPF_FUNC_perf_prog_read_value 56
|
||||
#define BPF_FUNC_getsockopt 57
|
||||
#define BPF_FUNC_override_return 58
|
||||
#define BPF_FUNC_sock_ops_cb_flags_set 59
|
||||
#define BPF_FUNC_msg_redirect_map 60
|
||||
#define BPF_FUNC_msg_apply_bytes 61
|
||||
#define BPF_FUNC_msg_cork_bytes 62
|
||||
#define BPF_FUNC_msg_pull_data 63
|
||||
#define BPF_FUNC_bind 64
|
||||
#define BPF_FUNC_xdp_adjust_tail 65
|
||||
#define BPF_FUNC_skb_get_xfrm_state 66
|
||||
#define BPF_FUNC_get_stack 67
|
||||
#define BPF_FUNC_skb_load_bytes_relative 68
|
||||
#define BPF_FUNC_fib_lookup 69
|
||||
#define BPF_FUNC_sock_hash_update 70
|
||||
#define BPF_FUNC_msg_redirect_hash 71
|
||||
#define BPF_FUNC_sk_redirect_hash 72
|
||||
#define BPF_FUNC_lwt_push_encap 73
|
||||
#define BPF_FUNC_lwt_seg6_store_bytes 74
|
||||
#define BPF_FUNC_lwt_seg6_adjust_srh 75
|
||||
#define BPF_FUNC_lwt_seg6_action 76
|
||||
#define BPF_FUNC_rc_repeat 77
|
||||
#define BPF_FUNC_rc_keydown 78
|
||||
#define BPF_FUNC_skb_cgroup_id 79
|
||||
#define BPF_FUNC_get_current_cgroup_id 80
|
||||
#define BPF_FUNC_get_local_storage 81
|
||||
#define BPF_FUNC_sk_select_reuseport 82
|
||||
#define BPF_FUNC_skb_ancestor_cgroup_id 83
|
||||
#define BPF_FUNC_sk_lookup_tcp 84
|
||||
#define BPF_FUNC_sk_lookup_udp 85
|
||||
#define BPF_FUNC_sk_release 86
|
||||
#define BPF_FUNC_map_push_elem 87
|
||||
#define BPF_FUNC_map_pop_elem 88
|
||||
#define BPF_FUNC_map_peek_elem 89
|
||||
#define BPF_FUNC_msg_push_data 90
|
||||
#define BPF_FUNC_msg_pop_data 91
|
||||
#define BPF_FUNC_rc_pointer_rel 92
|
||||
#define BPF_FUNC_spin_lock 93
|
||||
#define BPF_FUNC_spin_unlock 94
|
||||
#define BPF_FUNC_sk_fullsock 95
|
||||
#define BPF_FUNC_tcp_sock 96
|
||||
#define BPF_FUNC_skb_ecn_set_ce 97
|
||||
#define BPF_FUNC_get_listener_sock 98
|
||||
#define BPF_FUNC_skc_lookup_tcp 99
|
||||
#define BPF_FUNC_tcp_check_syncookie 100
|
||||
#define BPF_FUNC_sysctl_get_name 101
|
||||
#define BPF_FUNC_sysctl_get_current_value 102
|
||||
#define BPF_FUNC_sysctl_get_new_value 103
|
||||
#define BPF_FUNC_sysctl_set_new_value 104
|
||||
#define BPF_FUNC_strtol 105
|
||||
#define BPF_FUNC_strtoul 106
|
||||
#define BPF_FUNC_sk_storage_get 107
|
||||
#define BPF_FUNC_sk_storage_delete 108
|
||||
#define BPF_FUNC_send_signal 109
|
||||
#define BPF_FUNC_tcp_gen_syncookie 110
|
||||
#define BPF_FUNC_skb_output 111
|
||||
#define BPF_FUNC_probe_read_user 112
|
||||
#define BPF_FUNC_probe_read_kernel 113
|
||||
#define BPF_FUNC_probe_read_user_str 114
|
||||
#define BPF_FUNC_probe_read_kernel_str 115
|
||||
#define BPF_FUNC_tcp_send_ack 116
|
||||
#define BPF_FUNC_send_signal_thread 117
|
||||
#define BPF_FUNC_jiffies64 118
|
||||
#define BPF_FUNC_read_branch_records 119
|
||||
#define BPF_FUNC_get_ns_current_pid_tgid 120
|
||||
#define BPF_FUNC_xdp_output 121
|
||||
#define BPF_FUNC_get_netns_cookie 122
|
||||
#define BPF_FUNC_get_current_ancestor_cgroup_id 123
|
||||
#define BPF_FUNC_sk_assign 124
|
||||
#define BPF_FUNC_ktime_get_boot_ns 125
|
||||
#define BPF_FUNC_seq_printf 126
|
||||
#define BPF_FUNC_seq_write 127
|
||||
#define BPF_FUNC_sk_cgroup_id 128
|
||||
#define BPF_FUNC_sk_ancestor_cgroup_id 129
|
||||
#define BPF_FUNC_ringbuf_output 130
|
||||
#define BPF_FUNC_ringbuf_reserve 131
|
||||
#define BPF_FUNC_ringbuf_submit 132
|
||||
#define BPF_FUNC_ringbuf_discard 133
|
||||
#define BPF_FUNC_ringbuf_query 134
|
||||
#define BPF_FUNC_csum_level 135
|
||||
#define BPF_FUNC_skc_to_tcp6_sock 136
|
||||
#define BPF_FUNC_skc_to_tcp_sock 137
|
||||
#define BPF_FUNC_skc_to_tcp_timewait_sock 138
|
||||
#define BPF_FUNC_skc_to_tcp_request_sock 139
|
||||
#define BPF_FUNC_skc_to_udp6_sock 140
|
||||
#define BPF_FUNC_get_task_stack 141
|
||||
#define BPF_FUNC_load_hdr_opt 142
|
||||
#define BPF_FUNC_store_hdr_opt 143
|
||||
#define BPF_FUNC_reserve_hdr_opt 144
|
||||
#define BPF_FUNC_inode_storage_get 145
|
||||
#define BPF_FUNC_inode_storage_delete 146
|
||||
#define BPF_FUNC_d_path 147
|
||||
#define BPF_FUNC_copy_from_user 148
|
||||
#define BPF_FUNC_snprintf_btf 149
|
||||
#define BPF_FUNC_seq_printf_btf 150
|
||||
#define BPF_FUNC_skb_cgroup_classid 151
|
||||
#define BPF_FUNC_redirect_neigh 152
|
||||
#define BPF_FUNC_per_cpu_ptr 153
|
||||
#define BPF_FUNC_this_cpu_ptr 154
|
||||
#define BPF_FUNC_redirect_peer 155
|
||||
#define BPF_FUNC_task_storage_get 156
|
||||
#define BPF_FUNC_task_storage_delete 157
|
||||
#define BPF_FUNC_get_current_task_btf 158
|
||||
#define BPF_FUNC_bprm_opts_set 159
|
||||
#define BPF_FUNC_ktime_get_coarse_ns 160
|
||||
#define BPF_FUNC_ima_inode_hash 161
|
||||
#define BPF_FUNC_sock_from_file 162
|
||||
#define BPF_FUNC_check_mtu 163
|
||||
#define BPF_FUNC_for_each_map_elem 164
|
||||
#define BPF_FUNC_snprintf 165
|
||||
#define BPF_FUNC_sys_bpf 166
|
||||
#define BPF_FUNC_btf_find_by_name_kind 167
|
||||
#define BPF_FUNC_sys_close 168
|
||||
#define __BPF_FUNC_MAX_ID 169
|
||||
|
||||
#define __bpf_md_ptr(type, name) \
|
||||
union { \
|
||||
|
@ -1157,185 +1327,6 @@ struct btf_ptr {
|
|||
uint32_t flags;
|
||||
};
|
||||
|
||||
/* clang-format off */
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
FN(map_lookup_elem), \
|
||||
FN(map_update_elem), \
|
||||
FN(map_delete_elem), \
|
||||
FN(probe_read), \
|
||||
FN(ktime_get_ns), \
|
||||
FN(trace_printk), \
|
||||
FN(get_prandom_u32), \
|
||||
FN(get_smp_processor_id), \
|
||||
FN(skb_store_bytes), \
|
||||
FN(l3_csum_replace), \
|
||||
FN(l4_csum_replace), \
|
||||
FN(tail_call), \
|
||||
FN(clone_redirect), \
|
||||
FN(get_current_pid_tgid), \
|
||||
FN(get_current_uid_gid), \
|
||||
FN(get_current_comm), \
|
||||
FN(get_cgroup_classid), \
|
||||
FN(skb_vlan_push), \
|
||||
FN(skb_vlan_pop), \
|
||||
FN(skb_get_tunnel_key), \
|
||||
FN(skb_set_tunnel_key), \
|
||||
FN(perf_event_read), \
|
||||
FN(redirect), \
|
||||
FN(get_route_realm), \
|
||||
FN(perf_event_output), \
|
||||
FN(skb_load_bytes), \
|
||||
FN(get_stackid), \
|
||||
FN(csum_diff), \
|
||||
FN(skb_get_tunnel_opt), \
|
||||
FN(skb_set_tunnel_opt), \
|
||||
FN(skb_change_proto), \
|
||||
FN(skb_change_type), \
|
||||
FN(skb_under_cgroup), \
|
||||
FN(get_hash_recalc), \
|
||||
FN(get_current_task), \
|
||||
FN(probe_write_user), \
|
||||
FN(current_task_under_cgroup), \
|
||||
FN(skb_change_tail), \
|
||||
FN(skb_pull_data), \
|
||||
FN(csum_update), \
|
||||
FN(set_hash_invalid), \
|
||||
FN(get_numa_node_id), \
|
||||
FN(skb_change_head), \
|
||||
FN(xdp_adjust_head), \
|
||||
FN(probe_read_str), \
|
||||
FN(get_socket_cookie), \
|
||||
FN(get_socket_uid), \
|
||||
FN(set_hash), \
|
||||
FN(setsockopt), \
|
||||
FN(skb_adjust_room), \
|
||||
FN(redirect_map), \
|
||||
FN(sk_redirect_map), \
|
||||
FN(sock_map_update), \
|
||||
FN(xdp_adjust_meta), \
|
||||
FN(perf_event_read_value), \
|
||||
FN(perf_prog_read_value), \
|
||||
FN(getsockopt), \
|
||||
FN(override_return), \
|
||||
FN(sock_ops_cb_flags_set), \
|
||||
FN(msg_redirect_map), \
|
||||
FN(msg_apply_bytes), \
|
||||
FN(msg_cork_bytes), \
|
||||
FN(msg_pull_data), \
|
||||
FN(bind), \
|
||||
FN(xdp_adjust_tail), \
|
||||
FN(skb_get_xfrm_state), \
|
||||
FN(get_stack), \
|
||||
FN(skb_load_bytes_relative), \
|
||||
FN(fib_lookup), \
|
||||
FN(sock_hash_update), \
|
||||
FN(msg_redirect_hash), \
|
||||
FN(sk_redirect_hash), \
|
||||
FN(lwt_push_encap), \
|
||||
FN(lwt_seg6_store_bytes), \
|
||||
FN(lwt_seg6_adjust_srh), \
|
||||
FN(lwt_seg6_action), \
|
||||
FN(rc_repeat), \
|
||||
FN(rc_keydown), \
|
||||
FN(skb_cgroup_id), \
|
||||
FN(get_current_cgroup_id), \
|
||||
FN(get_local_storage), \
|
||||
FN(sk_select_reuseport), \
|
||||
FN(skb_ancestor_cgroup_id), \
|
||||
FN(sk_lookup_tcp), \
|
||||
FN(sk_lookup_udp), \
|
||||
FN(sk_release), \
|
||||
FN(map_push_elem), \
|
||||
FN(map_pop_elem), \
|
||||
FN(map_peek_elem), \
|
||||
FN(msg_push_data), \
|
||||
FN(msg_pop_data), \
|
||||
FN(rc_pointer_rel), \
|
||||
FN(spin_lock), \
|
||||
FN(spin_unlock), \
|
||||
FN(sk_fullsock), \
|
||||
FN(tcp_sock), \
|
||||
FN(skb_ecn_set_ce), \
|
||||
FN(get_listener_sock), \
|
||||
FN(skc_lookup_tcp), \
|
||||
FN(tcp_check_syncookie), \
|
||||
FN(sysctl_get_name), \
|
||||
FN(sysctl_get_current_value), \
|
||||
FN(sysctl_get_new_value), \
|
||||
FN(sysctl_set_new_value), \
|
||||
FN(strtol), \
|
||||
FN(strtoul), \
|
||||
FN(sk_storage_get), \
|
||||
FN(sk_storage_delete), \
|
||||
FN(send_signal), \
|
||||
FN(tcp_gen_syncookie), \
|
||||
FN(skb_output), \
|
||||
FN(probe_read_user), \
|
||||
FN(probe_read_kernel), \
|
||||
FN(probe_read_user_str), \
|
||||
FN(probe_read_kernel_str), \
|
||||
FN(tcp_send_ack), \
|
||||
FN(send_signal_thread), \
|
||||
FN(jiffies64), \
|
||||
FN(read_branch_records), \
|
||||
FN(get_ns_current_pid_tgid), \
|
||||
FN(xdp_output), \
|
||||
FN(get_netns_cookie), \
|
||||
FN(get_current_ancestor_cgroup_id), \
|
||||
FN(sk_assign), \
|
||||
FN(ktime_get_boot_ns), \
|
||||
FN(seq_printf), \
|
||||
FN(seq_write), \
|
||||
FN(sk_cgroup_id), \
|
||||
FN(sk_ancestor_cgroup_id), \
|
||||
FN(ringbuf_output), \
|
||||
FN(ringbuf_reserve), \
|
||||
FN(ringbuf_submit), \
|
||||
FN(ringbuf_discard), \
|
||||
FN(ringbuf_query), \
|
||||
FN(csum_level), \
|
||||
FN(skc_to_tcp6_sock), \
|
||||
FN(skc_to_tcp_sock), \
|
||||
FN(skc_to_tcp_timewait_sock), \
|
||||
FN(skc_to_tcp_request_sock), \
|
||||
FN(skc_to_udp6_sock), \
|
||||
FN(get_task_stack), \
|
||||
FN(load_hdr_opt), \
|
||||
FN(store_hdr_opt), \
|
||||
FN(reserve_hdr_opt), \
|
||||
FN(inode_storage_get), \
|
||||
FN(inode_storage_delete), \
|
||||
FN(d_path), \
|
||||
FN(copy_from_user), \
|
||||
FN(snprintf_btf), \
|
||||
FN(seq_printf_btf), \
|
||||
FN(skb_cgroup_classid), \
|
||||
FN(redirect_neigh), \
|
||||
FN(per_cpu_ptr), \
|
||||
FN(this_cpu_ptr), \
|
||||
FN(redirect_peer), \
|
||||
FN(task_storage_get), \
|
||||
FN(task_storage_delete), \
|
||||
FN(get_current_task_btf), \
|
||||
FN(bprm_opts_set), \
|
||||
FN(ktime_get_coarse_ns), \
|
||||
FN(ima_inode_hash), \
|
||||
FN(sock_from_file), \
|
||||
FN(check_mtu), \
|
||||
FN(for_each_map_elem), \
|
||||
FN(snprintf), \
|
||||
FN(sys_bpf), \
|
||||
FN(btf_find_by_name_kind), \
|
||||
FN(sys_close), \
|
||||
/* clang-format on */
|
||||
|
||||
#define __BPF_ENUM_FN(x) BPF_FUNC_##x
|
||||
enum bpf_func_id {
|
||||
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
|
||||
};
|
||||
#undef __BPF_ENUM_FN
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_BPF_H_ */
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
s="""
|
||||
BPF_SOCK_OPS_VOID,
|
||||
BPF_SOCK_OPS_TIMEOUT_INIT,
|
||||
BPF_SOCK_OPS_RWND_INIT,
|
||||
BPF_SOCK_OPS_TCP_CONNECT_CB,
|
||||
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
|
||||
BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
|
||||
BPF_SOCK_OPS_NEEDS_ECN,
|
||||
BPF_SOCK_OPS_BASE_RTT,
|
||||
BPF_SOCK_OPS_RTO_CB,
|
||||
BPF_SOCK_OPS_RETRANS_CB,
|
||||
BPF_SOCK_OPS_STATE_CB,
|
||||
BPF_SOCK_OPS_TCP_LISTEN_CB,
|
||||
BPF_SOCK_OPS_RTT_CB,
|
||||
BPF_SOCK_OPS_PARSE_HDR_OPT_CB,
|
||||
BPF_SOCK_OPS_HDR_OPT_LEN_CB,
|
||||
BPF_SOCK_OPS_WRITE_HDR_OPT_CB,
|
||||
"""
|
||||
|
||||
i = 0
|
||||
for x in s.replace(',','').split():
|
||||
print("#define %s %d" % (x, i))
|
||||
i += 1
|
84
libc/calls/struct/ucontext-netbsd.internal.h
Normal file
84
libc/calls/struct/ucontext-netbsd.internal.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
// clang-format off
|
||||
#include "libc/calls/ucontext.h"
|
||||
|
||||
#define __UCONTEXT_SIZE 784
|
||||
#define _UC_SIGMASK 0x01
|
||||
#define _UC_STACK 0x02
|
||||
#define _UC_CPU 0x04
|
||||
#define _UC_FPU 0x08
|
||||
#define _UC_TLSBASE 0x00080000
|
||||
#define _UC_SETSTACK 0x00010000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
|
||||
union sigval_netbsd {
|
||||
int32_t sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
struct sigset_netbsd {
|
||||
uint32_t __bits[4];
|
||||
};
|
||||
|
||||
struct stack_netbsd {
|
||||
void *ss_sp;
|
||||
size_t ss_size;
|
||||
int32_t ss_flags;
|
||||
};
|
||||
|
||||
struct mcontext_netbsd {
|
||||
union {
|
||||
struct {
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r12;
|
||||
uint64_t r13;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
uint64_t rbp;
|
||||
uint64_t rbx;
|
||||
uint64_t rax;
|
||||
uint64_t gs;
|
||||
uint64_t fs;
|
||||
uint64_t es;
|
||||
uint64_t ds;
|
||||
uint64_t trapno;
|
||||
uint64_t err;
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
};
|
||||
int64_t __gregs[26];
|
||||
};
|
||||
int64_t _mc_tlsbase;
|
||||
struct FpuState __fpregs;
|
||||
};
|
||||
|
||||
struct ucontext_netbsd {
|
||||
union {
|
||||
struct {
|
||||
uint32_t uc_flags; /* see _UC_* above */
|
||||
struct ucontext_netbsd *uc_link;
|
||||
struct sigset_netbsd uc_sigmask;
|
||||
struct stack_netbsd uc_stack;
|
||||
struct mcontext_netbsd uc_mcontext;
|
||||
};
|
||||
char __pad[__UCONTEXT_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_ */
|
|
@ -19,7 +19,11 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/once.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/symboliclink.h"
|
||||
#include "libc/nt/enum/tokeninformationclass.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
@ -27,27 +31,12 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/luid.h"
|
||||
#include "libc/nt/struct/tokenprivileges.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool g_can_symlink;
|
||||
__msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW;
|
||||
|
||||
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
const char *linkpath) {
|
||||
uint32_t flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
if (!g_can_symlink) return eacces();
|
||||
flags = isdirectory(target) ? kNtSymbolicLinkFlagDirectory : 0;
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
if (__mkntpath(target, target16) == -1) return -1;
|
||||
if (CreateSymbolicLink(linkpath16, target16, flags)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
|
||||
static textstartup bool EnableSymlink(void) {
|
||||
static bool AllowedToCreateSymlinks(void) {
|
||||
int64_t tok;
|
||||
struct NtLuid id;
|
||||
struct NtTokenPrivileges tp;
|
||||
|
@ -60,10 +49,45 @@ static textstartup bool EnableSymlink(void) {
|
|||
return GetLastError() != kNtErrorNotAllAssigned;
|
||||
}
|
||||
|
||||
static textstartup void g_can_symlink_init() {
|
||||
g_can_symlink = EnableSymlink();
|
||||
}
|
||||
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
const char *linkpath) {
|
||||
int targetlen;
|
||||
uint32_t attrs, flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
|
||||
const void *const g_can_symlink_ctor[] initarray = {
|
||||
g_can_symlink_init,
|
||||
};
|
||||
// convert the paths
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
if ((targetlen = __mkntpath(target, target16)) == -1) return -1;
|
||||
|
||||
// determine if we need directory flag
|
||||
if ((attrs = __imp_GetFileAttributesW(target16)) != -1u) {
|
||||
if (attrs & kNtFileAttributeDirectory) {
|
||||
flags = kNtSymbolicLinkFlagDirectory;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
} else {
|
||||
// win32 needs to know if it's a directory of a file symlink, but
|
||||
// that's hard to determine if we're creating a broken symlink so
|
||||
// we'll fall back to checking for trailing slash
|
||||
if (targetlen && target16[targetlen - 1] == '\\') {
|
||||
flags = kNtSymbolicLinkFlagDirectory;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// windows only lets administrators do this
|
||||
// even then we're required to ask for permission
|
||||
if (!_once(AllowedToCreateSymlinks())) {
|
||||
return eperm();
|
||||
}
|
||||
|
||||
// we can now proceed
|
||||
if (CreateSymbolicLink(linkpath16, target16, flags)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __fix_enotdir(-1, linkpath16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* @param target can be relative and needn't exist
|
||||
* @param linkpath is what gets created
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @note Windows NT only lets admins do this
|
||||
* @raise EPERM if a non-admin on Windows NT tries to use this
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int symlinkat(const char *target, int newdirfd, const char *linkpath) {
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
|
||||
textwindows int sys_truncate_nt(const char *path, uint64_t length) {
|
||||
int rc;
|
||||
bool32 ok;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL,
|
||||
kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1) {
|
||||
ok = sys_ftruncate_nt(fh, length);
|
||||
rc = sys_ftruncate_nt(fh, length);
|
||||
CloseHandle(fh);
|
||||
if (ok) return 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
return __winerr();
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -5,56 +5,6 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define REG_R8 REG_R8
|
||||
#define REG_R9 REG_R9
|
||||
#define REG_R10 REG_R10
|
||||
#define REG_R11 REG_R11
|
||||
#define REG_R12 REG_R12
|
||||
#define REG_R13 REG_R13
|
||||
#define REG_R14 REG_R14
|
||||
#define REG_R15 REG_R15
|
||||
#define REG_RDI REG_RDI
|
||||
#define REG_RSI REG_RSI
|
||||
#define REG_RBP REG_RBP
|
||||
#define REG_RBX REG_RBX
|
||||
#define REG_RDX REG_RDX
|
||||
#define REG_RAX REG_RAX
|
||||
#define REG_RCX REG_RCX
|
||||
#define REG_RSP REG_RSP
|
||||
#define REG_RIP REG_RIP
|
||||
#define REG_EFL REG_EFL
|
||||
#define REG_CSGSFS REG_CSGSFS
|
||||
#define REG_ERR REG_ERR
|
||||
#define REG_TRAPNO REG_TRAPNO
|
||||
#define REG_OLDMASK REG_OLDMASK
|
||||
#define REG_CR2 REG_CR2
|
||||
|
||||
enum GeneralRegister {
|
||||
REG_R8,
|
||||
REG_R9,
|
||||
REG_R10,
|
||||
REG_R11,
|
||||
REG_R12,
|
||||
REG_R13,
|
||||
REG_R14,
|
||||
REG_R15,
|
||||
REG_RDI,
|
||||
REG_RSI,
|
||||
REG_RBP,
|
||||
REG_RBX,
|
||||
REG_RDX,
|
||||
REG_RAX,
|
||||
REG_RCX,
|
||||
REG_RSP,
|
||||
REG_RIP,
|
||||
REG_EFL,
|
||||
REG_CSGSFS,
|
||||
REG_ERR,
|
||||
REG_TRAPNO,
|
||||
REG_OLDMASK,
|
||||
REG_CR2
|
||||
};
|
||||
|
||||
struct XmmRegister {
|
||||
uint64_t u64[2];
|
||||
};
|
||||
|
|
|
@ -140,5 +140,5 @@ textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
|
|||
// rc = SyncDirectory(dirfd, path16, n);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include "libc/time/time.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_utimensat_linux 0x118 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
||||
int flags) {
|
||||
int rc, olderr;
|
||||
|
@ -35,8 +33,7 @@ int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
|||
if (!IsXnu()) {
|
||||
olderr = errno;
|
||||
rc = __sys_utimensat(dirfd, path, ts, flags);
|
||||
if (((rc == -1 && errno == ENOSYS) || rc == __NR_utimensat_linux) &&
|
||||
dirfd == AT_FDCWD && !flags) {
|
||||
if ((rc == -1 && errno == ENOSYS) && dirfd == AT_FDCWD && !flags) {
|
||||
errno = olderr;
|
||||
if (ts) {
|
||||
tv[0].tv_sec = ts[0].tv_sec;
|
||||
|
|
|
@ -25,4 +25,4 @@
|
|||
*
|
||||
* By default no limit is imposed.
|
||||
*/
|
||||
size_t __virtualmax;
|
||||
size_t __virtualmax = -1;
|
||||
|
|
|
@ -16,22 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -44,16 +32,20 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
|
|||
_offset2overlap(g_fds.p[fd].handle, offset, &overlap))) {
|
||||
return sent;
|
||||
}
|
||||
err = GetLastError();
|
||||
// make sure write() raises SIGPIPE on broken pipe
|
||||
// make sure write() raises SIGPIPE on closing named pipe
|
||||
if (err == kNtErrorBrokenPipe || err == kNtErrorNoData) {
|
||||
__sig_raise(SIGPIPE, SI_KERNEL);
|
||||
return epipe();
|
||||
switch (GetLastError()) {
|
||||
// case kNtErrorInvalidHandle:
|
||||
// return ebadf(); /* handled by consts.sh */
|
||||
// case kNtErrorNotEnoughQuota:
|
||||
// return edquot(); /* handled by consts.sh */
|
||||
case kNtErrorBrokenPipe: // broken pipe
|
||||
case kNtErrorNoData: // closing named pipe
|
||||
__sig_raise(SIGPIPE, SI_KERNEL); //
|
||||
return epipe(); //
|
||||
case kNtErrorAccessDenied: // write doesn't return EACCESS
|
||||
return ebadf(); //
|
||||
default:
|
||||
return __winerr();
|
||||
}
|
||||
// kNtErrorInvalidHandle → EBADF (consts.sh)
|
||||
// kNtErrorNotEnoughQuota → EDQUOT (consts.sh; SetProcessWorkingSetSize)
|
||||
return __winerr();
|
||||
}
|
||||
|
||||
textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen,
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
|
@ -58,7 +59,7 @@ STATIC_YOINK("_init_asan");
|
|||
|
||||
#define ASAN_MORGUE_ITEMS 512
|
||||
#define ASAN_MORGUE_THRESHOLD 65536 // morgue memory O(ITEMS*THRESHOLD)
|
||||
#define ASAN_TRACE_ITEMS 16 // backtrace limit on malloc origin
|
||||
#define ASAN_TRACE_ITEMS 16 // backtrace limit on malloc origin
|
||||
|
||||
/**
|
||||
* @fileoverview Cosmopolitan Address Sanitizer Runtime.
|
||||
|
@ -156,9 +157,10 @@ struct ReportOriginHeap {
|
|||
bool __asan_noreentry;
|
||||
static struct AsanMorgue __asan_morgue;
|
||||
|
||||
static wontreturn void __asan_unreachable(void) {
|
||||
for (;;) __builtin_trap();
|
||||
}
|
||||
#define __asan_unreachable() \
|
||||
do { \
|
||||
for (;;) __builtin_trap(); \
|
||||
} while (0)
|
||||
|
||||
static int __asan_bsf(uint64_t x) {
|
||||
_Static_assert(sizeof(long long) == sizeof(uint64_t), "");
|
||||
|
@ -177,7 +179,8 @@ static uint64_t __asan_roundup2pow(uint64_t x) {
|
|||
static char *__asan_utf8cpy(char *p, unsigned c) {
|
||||
uint64_t z;
|
||||
z = tpenc(c);
|
||||
do *p++ = z;
|
||||
do
|
||||
*p++ = z;
|
||||
while ((z >>= 8));
|
||||
return p;
|
||||
}
|
||||
|
@ -921,7 +924,8 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) {
|
|||
if (!__asan_checka(SHADOW(bp), sizeof(*bp) >> 3).kind) {
|
||||
addr = bp->addr;
|
||||
if (addr == weakaddr("__gc") && weakaddr("__gc")) {
|
||||
do --gi;
|
||||
do
|
||||
--gi;
|
||||
while ((addr = garbage->p[gi].ret) == weakaddr("__gc"));
|
||||
}
|
||||
bt->p[i] = addr;
|
||||
|
@ -1172,10 +1176,7 @@ void __asan_stack_free(char *p, size_t size, int classid) {
|
|||
}
|
||||
|
||||
void __asan_handle_no_return(void) {
|
||||
uintptr_t stk, ssz;
|
||||
stk = (uintptr_t)__builtin_frame_address(0);
|
||||
ssz = GetStackSize();
|
||||
__asan_unpoison(stk, ROUNDUP(stk, ssz) - stk);
|
||||
__asan_unpoison(GetStackAddr(0), GetStackSize());
|
||||
}
|
||||
|
||||
void __asan_register_globals(struct AsanGlobal g[], int n) {
|
||||
|
@ -1239,14 +1240,14 @@ void __asan_unpoison_stack_memory(uintptr_t addr, size_t size) {
|
|||
__asan_unpoison(addr, size);
|
||||
}
|
||||
|
||||
void __asan_alloca_poison(uintptr_t addr, size_t size) {
|
||||
void __asan_alloca_poison(uintptr_t addr, uintptr_t size) {
|
||||
__asan_poison(addr - 32, 32, kAsanAllocaUnderrun);
|
||||
__asan_poison(addr + size, 32, kAsanAllocaOverrun);
|
||||
__asan_unpoison(addr, size);
|
||||
}
|
||||
|
||||
void __asan_allocas_unpoison(uintptr_t x, uintptr_t y) {
|
||||
if (x && x > y) __asan_unpoison(x, y - x);
|
||||
if (!x || x > y) return;
|
||||
__asan_memset((void *)((x >> 3) + 0x7fff8000), 0, (y - x) / 8);
|
||||
}
|
||||
|
||||
void *__asan_addr_is_in_fake_stack(void *fakestack, void *addr, void **beg,
|
||||
|
|
39
libc/intrin/createsymboliclink.greg.c
Normal file
39
libc/intrin/createsymboliclink.greg.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
||||
__msabi extern typeof(CreateSymbolicLink) *const __imp_CreateSymbolicLinkW;
|
||||
|
||||
/**
|
||||
* Creates symbolic link on the New Technology.
|
||||
* @note you need to elevate process privileges before calling this
|
||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||
*/
|
||||
bool32 CreateSymbolicLink(const char16_t *lpSymlinkFileName,
|
||||
const char16_t *lpTargetPathName, uint32_t dwFlags) {
|
||||
bool32 ok;
|
||||
ok = __imp_CreateSymbolicLinkW(lpSymlinkFileName, lpTargetPathName, dwFlags);
|
||||
if (!ok) __winerr();
|
||||
NTTRACE("CreateSymbolicLink(%#hs, %#hs, %s) → %hhhd% m", lpSymlinkFileName,
|
||||
lpTargetPathName, DescribeNtSymbolicLinkFlags(dwFlags), ok);
|
||||
return ok;
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(DeleteFile) *const __imp_DeleteFileW;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
|
||||
struct thatispacked DescribeFlags {
|
||||
unsigned flag;
|
||||
|
@ -26,7 +26,9 @@ const char *DescribeNtPipeOpenFlags(uint32_t);
|
|||
const char *DescribeNtPipeModeFlags(uint32_t);
|
||||
const char *DescribeNtFileShareFlags(uint32_t);
|
||||
const char *DescribeNtFileAccessFlags(uint32_t);
|
||||
const char *DescribeNtSymbolicLinkFlags(uint32_t);
|
||||
const char *DescribeNtProcessAccessFlags(uint32_t);
|
||||
const char *DescribeNtMoveFileInputFlags(uint32_t);
|
||||
const char *DescribeNtCreationDisposition(uint32_t);
|
||||
const char *DescribeNtConsoleModeInputFlags(uint32_t);
|
||||
const char *DescribeNtConsoleModeOutputFlags(uint32_t);
|
||||
|
|
37
libc/intrin/describentmovefileflags.greg.c
Normal file
37
libc/intrin/describentmovefileflags.greg.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/movefileexflags.h"
|
||||
|
||||
static const struct DescribeFlags kMoveFileInputFlags[] = {
|
||||
{kNtMovefileReplaceExisting, "ReplaceExisting"}, //
|
||||
{kNtMovefileCopyAllowed, "CopyAllowed"}, //
|
||||
{kNtMovefileDelayUntilReboot, "DelayUntilReboot"}, //
|
||||
{kNtMovefileWriteThrough, "WriteThrough"}, //
|
||||
{kNtMovefileCreateHardlink, "CreateHardlink"}, //
|
||||
{kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, //
|
||||
};
|
||||
|
||||
const char *DescribeNtMoveFileInputFlags(uint32_t x) {
|
||||
static char movefileflags[256];
|
||||
return DescribeFlags(movefileflags, sizeof(movefileflags),
|
||||
kMoveFileInputFlags, ARRAYLEN(kMoveFileInputFlags),
|
||||
"kNtMovefile", x);
|
||||
}
|
33
libc/intrin/describentsymboliclinkflags.greg.c
Normal file
33
libc/intrin/describentsymboliclinkflags.greg.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/symboliclink.h"
|
||||
|
||||
static const struct DescribeFlags kSymbolicLinkflags[] = {
|
||||
{kNtSymbolicLinkFlagDirectory, "Directory"}, //
|
||||
{kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, //
|
||||
};
|
||||
|
||||
const char *DescribeNtSymbolicLinkFlags(uint32_t x) {
|
||||
static char ntsymboliclinkflags[64];
|
||||
return DescribeFlags(ntsymboliclinkflags, sizeof(ntsymboliclinkflags),
|
||||
kSymbolicLinkflags, ARRAYLEN(kSymbolicLinkflags),
|
||||
"kNtSymbolicLinkFlag", x);
|
||||
}
|
|
@ -16,8 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/winthread.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
|
@ -31,6 +35,7 @@
|
|||
* @noreturn
|
||||
*/
|
||||
privileged wontreturn void _Exit1(int rc) {
|
||||
struct WinThread *wt;
|
||||
STRACE("_Exit1(%d)", rc);
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
asm volatile("syscall"
|
||||
|
@ -39,6 +44,10 @@ privileged wontreturn void _Exit1(int rc) {
|
|||
: "rcx", "r11", "memory");
|
||||
__builtin_unreachable();
|
||||
} else if (IsWindows()) {
|
||||
if ((wt = GetWinThread())) {
|
||||
__releasefd(wt->pid);
|
||||
weaken(free)(wt);
|
||||
}
|
||||
ExitThread(rc);
|
||||
}
|
||||
for (;;) {
|
||||
|
|
|
@ -28,7 +28,7 @@ __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW;
|
|||
/**
|
||||
* Gets file info on the New Technology.
|
||||
*
|
||||
* @return handle, or -1 on failure
|
||||
* @return handle, or -1u on failure
|
||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||
*/
|
||||
textwindows uint32_t GetFileAttributes(const char16_t *lpPathName) {
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
extern int __pid;
|
||||
#include "libc/runtime/internal.h"
|
||||
|
||||
/**
|
||||
* Returns process id.
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/tls.h"
|
||||
#include "libc/intrin/winthread.internal.h"
|
||||
#include "libc/nt/thread.h"
|
||||
|
||||
/**
|
||||
|
@ -27,6 +29,7 @@
|
|||
int gettid(void) {
|
||||
int rc;
|
||||
int64_t wut;
|
||||
struct WinThread *wt;
|
||||
|
||||
if (IsLinux()) {
|
||||
asm("syscall"
|
||||
|
@ -71,7 +74,11 @@ int gettid(void) {
|
|||
}
|
||||
|
||||
if (IsWindows()) {
|
||||
return GetCurrentThreadId();
|
||||
if ((wt = GetWinThread())) {
|
||||
return wt->pid;
|
||||
} else {
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
}
|
||||
|
||||
return getpid();
|
|
@ -64,8 +64,10 @@ o/$(MODE)/libc/intrin/kprintf.greg.o: \
|
|||
-ffreestanding \
|
||||
$(NO_MAGIC)
|
||||
|
||||
o/$(MODE)/libc/intrin/tls.greg.o \
|
||||
o/$(MODE)/libc/intrin/exit.greg.o \
|
||||
o/$(MODE)/libc/intrin/exit1.greg.o \
|
||||
o/$(MODE)/libc/intrin/gettid.greg.o \
|
||||
o/$(MODE)/libc/intrin/createfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/reopenfile.greg.o \
|
||||
o/$(MODE)/libc/intrin/deletefile.greg.o \
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// @fileoverview data structure for __dos2errno()
|
||||
|
@ -101,8 +102,8 @@ kDos2Errno:
|
|||
.e kNtErrorBadLength,EACCES
|
||||
.e kNtErrorBadNetpath,ENOENT
|
||||
.e kNtErrorBadNetName,ENOENT
|
||||
.e kNtErrorBadNetResp,ENETDOWN
|
||||
.e kNtErrorBadPathname,ENOENT
|
||||
.e kNtErrorBadNetResp,ENETDOWN
|
||||
.e kNtErrorFileExists,EEXIST
|
||||
.e kNtErrorCannotMake,EACCES
|
||||
.e kNtErrorCommitmentLimit,ENOMEM
|
||||
|
@ -118,6 +119,7 @@ kDos2Errno:
|
|||
.e kNtErrorHostDown,EHOSTUNREACH
|
||||
.e kNtErrorHostUnreachable,EHOSTUNREACH
|
||||
.e kNtErrorInsufficientBuffer,EFAULT
|
||||
.e kNtErrorNoaccess,EFAULT
|
||||
.e kNtErrorInvalidAddress,EADDRNOTAVAIL
|
||||
.e kNtErrorNotAReparsePoint,EINVAL
|
||||
.e kNtErrorInvalidFunction,EINVAL
|
||||
|
@ -130,7 +132,6 @@ kDos2Errno:
|
|||
.e kNtErrorNetworkAccessDenied,EACCES
|
||||
.e kNtErrorNetworkBusy,ENETDOWN
|
||||
.e kNtErrorNetworkUnreachable,ENETUNREACH
|
||||
.e kNtErrorNoaccess,EFAULT
|
||||
.e kNtErrorNonpagedSystemResources,ENOMEM
|
||||
.e kNtErrorNotEnoughMemory,ENOMEM
|
||||
.e kNtErrorNotEnoughQuota,ENOMEM
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
|
@ -54,7 +55,7 @@ struct Timestamps {
|
|||
unsigned long long start;
|
||||
};
|
||||
|
||||
extern int __pid;
|
||||
extern bool __threaded;
|
||||
unsigned long long __kbirth; // see fork-nt.c
|
||||
|
||||
privileged static struct Timestamps kenter(void) {
|
||||
|
@ -361,7 +362,12 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
|||
|
||||
case 'P':
|
||||
if (!__vforked) {
|
||||
x = __pid;
|
||||
if (!__threaded) {
|
||||
x = __pid;
|
||||
} else {
|
||||
// clone() is linked and it yoinks gettid()
|
||||
x = weaken(gettid)();
|
||||
}
|
||||
} else {
|
||||
asm volatile("syscall"
|
||||
: "=a"(x)
|
||||
|
@ -444,7 +450,8 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
|
|||
i = 0;
|
||||
m = (1 << base) - 1;
|
||||
if (hash && x) sign = hash;
|
||||
do z[i++ & 127] = abet[x & m];
|
||||
do
|
||||
z[i++ & 127] = abet[x & m];
|
||||
while ((x >>= base) || (pdot && i < prec));
|
||||
goto EmitNumber;
|
||||
|
||||
|
|
40
libc/intrin/movefileex.greg.c
Normal file
40
libc/intrin/movefileex.greg.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(MoveFileEx) *const __imp_MoveFileExW;
|
||||
|
||||
/**
|
||||
* Deletes existing empty directory.
|
||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||
*/
|
||||
textwindows bool32 MoveFileEx(const char16_t *lpExistingFileName,
|
||||
const char16_t *lpNewFileName, int dwFlags) {
|
||||
bool32 ok;
|
||||
ok = __imp_MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags);
|
||||
if (!ok) __winerr();
|
||||
NTTRACE("MoveFileEx(%#hs, %#hs, %s) → %hhhd% m", lpExistingFileName,
|
||||
lpNewFileName, DescribeNtMoveFileInputFlags(dwFlags), ok);
|
||||
return ok;
|
||||
}
|
21
libc/intrin/once.h
Normal file
21
libc/intrin/once.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_ONCE_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_ONCE_H_
|
||||
#include "libc/intrin/spinlock.h"
|
||||
|
||||
#define _once(x) \
|
||||
({ \
|
||||
typeof(x) oncerc; \
|
||||
static bool once; \
|
||||
static typeof(oncerc) onceresult; \
|
||||
_Alignas(64) static char oncelock; \
|
||||
_spinlock(&oncelock); \
|
||||
if (once) { \
|
||||
oncerc = onceresult; \
|
||||
} else { \
|
||||
oncerc = onceresult = x; \
|
||||
} \
|
||||
_spunlock(&oncelock); \
|
||||
oncerc; \
|
||||
})
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_ONCE_H_ */
|
7
libc/intrin/refcount.h
Normal file
7
libc/intrin/refcount.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_
|
||||
|
||||
#define _incref(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED)
|
||||
#define _decref(x) __atomic_sub_fetch(x, 1, __ATOMIC_SEQ_CST)
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_REFCOUNT_H_ */
|
|
@ -21,10 +21,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
void __releasefd(int fd) {
|
||||
_spinlock(&__fds_lock);
|
||||
if (0 <= fd && fd < g_fds.n) {
|
||||
_spinlock(&__fds_lock);
|
||||
g_fds.p[fd].kind = 0;
|
||||
g_fds.f = MIN(fd, g_fds.f);
|
||||
_spunlock(&__fds_lock);
|
||||
}
|
||||
_spunlock(&__fds_lock);
|
||||
}
|
|
@ -19,13 +19,12 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(RemoveDirectory) *const __imp_RemoveDirectoryW;
|
||||
|
||||
/**
|
||||
* Deletes existing empty directory.
|
||||
* Deletes existing empty directory on the New Technology.
|
||||
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
|
||||
*/
|
||||
textwindows bool32 RemoveDirectory(const char16_t *lpPathName) {
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 401 && \
|
||||
!defined(__STRICT_ANSI__)
|
||||
|
||||
#ifdef TINY
|
||||
#define _spinlock(lock) \
|
||||
do { \
|
||||
while (__sync_lock_test_and_set(lock, 1)) { \
|
||||
__builtin_ia32_pause(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define _spinlock(lock) \
|
||||
do { \
|
||||
for (;;) { \
|
||||
|
@ -16,9 +21,8 @@
|
|||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define _spunlock(lock) __sync_lock_release(lock)
|
||||
|
||||
#endif /* GNU 4.1+ */
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_SPINLOCK_H_ */
|
||||
|
|
20
libc/intrin/threaded.c
Normal file
20
libc/intrin/threaded.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
bool __threaded;
|
89
libc/intrin/tls.greg.c
Normal file
89
libc/intrin/tls.greg.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/tls.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
||||
__msabi extern typeof(TlsFree) *const __imp_TlsFree;
|
||||
__msabi extern typeof(TlsAlloc) *const __imp_TlsAlloc;
|
||||
__msabi extern typeof(TlsGetValue) *const __imp_TlsGetValue;
|
||||
__msabi extern typeof(TlsSetValue) *const __imp_TlsSetValue;
|
||||
|
||||
/**
|
||||
* Assigns thread-local storage slot.
|
||||
*
|
||||
* This function may for instance be called at startup and the result
|
||||
* can be assigned to a global static variable; from then on, all the
|
||||
* threads in your application may pass that value to TlsGetValue, to
|
||||
* retrieve their thread-local values.
|
||||
*
|
||||
* @return index on success, or -1u w/ errno
|
||||
* @threadsafe
|
||||
*/
|
||||
uint32_t TlsAlloc(void) {
|
||||
return __imp_TlsAlloc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases thread-local storage slot.
|
||||
* @threadsafe
|
||||
*/
|
||||
bool32 TlsFree(uint32_t dwTlsIndex) {
|
||||
return __imp_TlsFree(dwTlsIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets value to thread-local storage slot.
|
||||
*
|
||||
* @param dwTlsIndex is something returned by TlsAlloc()
|
||||
* @return true if successful, otherwise false
|
||||
* @threadsafe
|
||||
*/
|
||||
bool32 TlsSetValue(uint32_t dwTlsIndex, void *lpTlsValue) {
|
||||
assert(IsWindows());
|
||||
if (dwTlsIndex < 64) {
|
||||
asm("mov\t%1,%%gs:%0"
|
||||
: "=m"(*((long *)0x1480 + dwTlsIndex))
|
||||
: "r"(lpTlsValue));
|
||||
return true;
|
||||
} else {
|
||||
return __imp_TlsSetValue(dwTlsIndex, lpTlsValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves value from thread-local storage slot.
|
||||
*
|
||||
* @param dwTlsIndex is something returned by TlsAlloc()
|
||||
* @return true if successful, otherwise false
|
||||
* @threadsafe
|
||||
*/
|
||||
void *TlsGetValue(uint32_t dwTlsIndex) {
|
||||
void *lpTlsValue;
|
||||
assert(IsWindows());
|
||||
if (dwTlsIndex < 64) {
|
||||
asm("mov\t%%gs:%1,%0"
|
||||
: "=r"(lpTlsValue)
|
||||
: "m"(*((long *)0x1480 + dwTlsIndex)));
|
||||
return lpTlsValue;
|
||||
} else {
|
||||
return __imp_TlsGetValue(dwTlsIndex);
|
||||
}
|
||||
}
|
13
libc/intrin/tls.h
Normal file
13
libc/intrin/tls.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_INTRIN_TLS_H_
|
||||
#define COSMOPOLITAN_LIBC_INTRIN_TLS_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
uint32_t TlsAlloc(void);
|
||||
bool32 TlsFree(uint32_t);
|
||||
bool32 TlsSetValue(uint32_t, void *);
|
||||
void *TlsGetValue(uint32_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_INTRIN_TLS_H_ */
|
|
@ -301,7 +301,7 @@ static __ubsan_die_f *__ubsan_type_mismatch_handler(
|
|||
p = __stpcpy(p, " align ");
|
||||
p = __intcpy(p, info->alignment);
|
||||
} else {
|
||||
p = __stpcpy(p, "insufficient size%n\t");
|
||||
p = __stpcpy(p, "insufficient size ");
|
||||
p = __stpcpy(p, kind);
|
||||
p = __stpcpy(p, " address 0x");
|
||||
p = __fixcpy(p, pointer, sizeof(pointer) * CHAR_BIT);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,32 +16,23 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/zip.h"
|
||||
|
||||
/* TODO(jart): DELETE */
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/tls.h"
|
||||
#include "libc/intrin/winthread.internal.h"
|
||||
|
||||
/**
|
||||
* Locates End Of Central Directory record in ZIP file.
|
||||
*
|
||||
* We search backwards for the End Of Central Directory Record magnum.
|
||||
* The ZIP spec says this can be anywhere in the last 64kb. We go all
|
||||
* the way since .com.dbg binaries will have lots of DWARF stuff after
|
||||
* the embedded .com binary. As such, we sanity check the other fields
|
||||
* too to make sure the record seems legit and it's not just a random
|
||||
* occurrence of the magnum.
|
||||
*
|
||||
* @param p points to file memory
|
||||
* @param n is byte size of file
|
||||
* @fileoverview TLS slot for clone() win32 polyfill.
|
||||
*/
|
||||
uint8_t *zipfindcentraldir(const uint8_t *p, size_t n) {
|
||||
size_t i;
|
||||
if (n >= kZipCdirHdrMinSize) {
|
||||
i = n - kZipCdirHdrMinSize;
|
||||
do {
|
||||
if (ZIP_CDIR_MAGIC(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
|
||||
return (/*unconst*/ uint8_t *)(p + i);
|
||||
}
|
||||
} while (i--);
|
||||
|
||||
int __winthread;
|
||||
|
||||
static textstartup void __winthread_init(void) {
|
||||
if (IsWindows()) {
|
||||
__winthread = TlsAlloc();
|
||||
TlsSetValue(__winthread, 0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void *const __winthread_ctor[] initarray = {
|
||||
__winthread_init,
|
||||
};
|
19
libc/intrin/winthread.internal.h
Normal file
19
libc/intrin/winthread.internal.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_
|
||||
#include "libc/intrin/tls.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct WinThread {
|
||||
int pid;
|
||||
};
|
||||
|
||||
extern int __winthread;
|
||||
|
||||
static inline struct WinThread *GetWinThread(void) {
|
||||
return TlsGetValue(__winthread);
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RUNTIME_WINTHREAD_INTERNAL_H_ */
|
|
@ -64,8 +64,6 @@ relegated static void ShowFunctionCalls(ucontext_t *ctx) {
|
|||
struct StackFrame goodframe;
|
||||
if (!ctx->uc_mcontext.rip) {
|
||||
kprintf("%s is NULL can't show backtrace%n", "RIP");
|
||||
} else if (!ctx->uc_mcontext.rbp) {
|
||||
kprintf("%s is NULL can't show backtrace%n", "RBP");
|
||||
} else {
|
||||
goodframe.next = (struct StackFrame *)ctx->uc_mcontext.rbp;
|
||||
goodframe.addr = ctx->uc_mcontext.rip;
|
||||
|
@ -142,7 +140,7 @@ relegated static void ShowGeneralRegisters(ucontext_t *ctx) {
|
|||
}
|
||||
}
|
||||
DescribeCpuFlags(
|
||||
p, ctx->uc_mcontext.gregs[REG_EFL],
|
||||
p, ctx->uc_mcontext.eflags,
|
||||
ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->swd : 0,
|
||||
ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->mxcsr : 0);
|
||||
kprintf("%s%n", buf);
|
||||
|
|
|
@ -45,11 +45,12 @@ static struct timespec vflogf_ts;
|
|||
*/
|
||||
void vflogf_onfail(FILE *f) {
|
||||
errno_t err;
|
||||
struct stat st;
|
||||
int64_t size;
|
||||
if (IsTiny()) return;
|
||||
err = ferror(f);
|
||||
if (fileno(f) != -1 && (err == ENOSPC || err == EDQUOT || err == EFBIG) &&
|
||||
(fstat(fileno(f), &st) == -1 || st.st_size > kNontrivialSize)) {
|
||||
((size = getfiledescriptorsize(fileno(f))) == -1 ||
|
||||
size > kNontrivialSize)) {
|
||||
ftruncate(fileno(f), 0);
|
||||
fseek(f, SEEK_SET, 0);
|
||||
f->beg = f->end = 0;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#define kNtMovefileReplaceExisting 1
|
||||
#define kNtMovefileCopyAllowed 2
|
||||
#define kNtMovefileDelayUntilReboot 4
|
||||
#define kNtMovefileWriteThrough 8
|
||||
#define kNtMovefileCreateHardlink 16
|
||||
#define kNtMovefileFailIfNotTrackable 32
|
||||
#define kNtMovefileWriteThrough 8
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_MOVEFILEEXFLAGS_H_ */
|
||||
|
|
7
libc/nt/enum/symboliclink.h
Normal file
7
libc/nt/enum/symboliclink.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_
|
||||
#define COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_
|
||||
|
||||
#define kNtSymbolicLinkFlagDirectory 1
|
||||
#define kNtSymbolicLinkFlagAllowUnprivilegedCreate 2
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SYMBOLICLINK_H_ */
|
|
@ -44,8 +44,6 @@
|
|||
#define kNtDuplicateCloseSource 1
|
||||
#define kNtDuplicateSameAccess 2
|
||||
|
||||
#define kNtSymbolicLinkFlagDirectory 1
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
.imp kernel32,__imp_CreateSymbolicLinkW,CreateSymbolicLinkW,0
|
||||
|
||||
.text.windows
|
||||
CreateSymbolicLink:
|
||||
__CreateSymbolicLink:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov __imp_CreateSymbolicLinkW(%rip),%rax
|
||||
jmp __sysv2nt
|
||||
.endfn CreateSymbolicLink,globl
|
||||
.endfn __CreateSymbolicLink,globl
|
||||
.previous
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
.imp kernel32,__imp_MoveFileExW,MoveFileExW,0
|
||||
|
||||
.text.windows
|
||||
MoveFileEx:
|
||||
__MoveFileEx:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov __imp_MoveFileExW(%rip),%rax
|
||||
jmp __sysv2nt
|
||||
.endfn MoveFileEx,globl
|
||||
.endfn __MoveFileEx,globl
|
||||
.previous
|
||||
|
|
|
@ -1,2 +1,14 @@
|
|||
.include "o/libc/nt/codegen.inc"
|
||||
.imp kernel32,__imp_TlsAlloc,TlsAlloc,0
|
||||
|
||||
.text.windows
|
||||
__TlsAlloc:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
sub $32,%rsp
|
||||
call *__imp_TlsAlloc(%rip)
|
||||
leave
|
||||
ret
|
||||
.endfn __TlsAlloc,globl
|
||||
.previous
|
||||
|
|
|
@ -1,2 +1,15 @@
|
|||
.include "o/libc/nt/codegen.inc"
|
||||
.imp kernel32,__imp_TlsFree,TlsFree,0
|
||||
|
||||
.text.windows
|
||||
__TlsFree:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov %rdi,%rcx
|
||||
sub $32,%rsp
|
||||
call *__imp_TlsFree(%rip)
|
||||
leave
|
||||
ret
|
||||
.endfn __TlsFree,globl
|
||||
.previous
|
||||
|
|
|
@ -1,2 +1,15 @@
|
|||
.include "o/libc/nt/codegen.inc"
|
||||
.imp kernel32,__imp_TlsGetValue,TlsGetValue,0
|
||||
|
||||
.text.windows
|
||||
__TlsGetValue:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov %rdi,%rcx
|
||||
sub $32,%rsp
|
||||
call *__imp_TlsGetValue(%rip)
|
||||
leave
|
||||
ret
|
||||
.endfn __TlsGetValue,globl
|
||||
.previous
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
.include "o/libc/nt/codegen.inc"
|
||||
.imp kernel32,__imp_TlsSetValue,TlsSetValue,0
|
||||
|
||||
.text.windows
|
||||
__TlsSetValue:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
.profilable
|
||||
mov __imp_TlsSetValue(%rip),%rax
|
||||
jmp __sysv2nt
|
||||
.endfn __TlsSetValue,globl
|
||||
.previous
|
||||
|
|
|
@ -196,7 +196,6 @@ imp 'CreateSemaphore' CreateSemaphoreW kernel32 0
|
|||
imp 'CreateSemaphoreA' CreateSemaphoreA kernel32 232
|
||||
imp 'CreateSemaphoreEx' CreateSemaphoreExW kernel32 0
|
||||
imp 'CreateSemaphoreExA' CreateSemaphoreExA kernel32 233
|
||||
imp 'CreateSymbolicLink' CreateSymbolicLinkW kernel32 0 3
|
||||
imp 'CreateSymbolicLinkA' CreateSymbolicLinkA kernel32 0 3
|
||||
imp 'CreateSymbolicLinkTransacted' CreateSymbolicLinkTransactedW kernel32 238
|
||||
imp 'CreateSymbolicLinkTransactedA' CreateSymbolicLinkTransactedA kernel32 237
|
||||
|
@ -884,7 +883,6 @@ imp 'Module32First' Module32FirstW kernel32 992
|
|||
imp 'Module32Next' Module32NextW kernel32 994
|
||||
imp 'MoveFile' MoveFileW kernel32 1000 2
|
||||
imp 'MoveFileA' MoveFileA kernel32 995 2
|
||||
imp 'MoveFileEx' MoveFileExW kernel32 0 3
|
||||
imp 'MoveFileExA' MoveFileExA kernel32 996 3
|
||||
imp 'MoveFileTransacted' MoveFileTransactedW kernel32 999
|
||||
imp 'MoveFileTransactedA' MoveFileTransactedA kernel32 998
|
||||
|
@ -1228,10 +1226,6 @@ imp 'TermsrvSetValueKey' TermsrvSetValueKey kernel32 1441
|
|||
imp 'TermsrvSyncUserIniFileExt' TermsrvSyncUserIniFileExt kernel32 1442
|
||||
imp 'Thread32First' Thread32First kernel32 1443
|
||||
imp 'Thread32Next' Thread32Next kernel32 1444
|
||||
imp 'TlsAlloc' TlsAlloc kernel32 0
|
||||
imp 'TlsFree' TlsFree kernel32 0
|
||||
imp 'TlsGetValue' TlsGetValue kernel32 0
|
||||
imp 'TlsSetValue' TlsSetValue kernel32 0
|
||||
imp 'Toolhelp32ReadProcessMemory' Toolhelp32ReadProcessMemory kernel32 1449
|
||||
imp 'TransactNamedPipe' TransactNamedPipe kernel32 0 7
|
||||
imp 'TransmitCommChar' TransmitCommChar kernel32 0
|
||||
|
@ -1353,6 +1347,7 @@ imp '__CreateFileMappingNuma' CreateFileMappingNumaW kernel32 0 7
|
|||
imp '__CreateNamedPipe' CreateNamedPipeW kernel32 0 8
|
||||
imp '__CreatePipe' CreatePipe kernel32 0 4
|
||||
imp '__CreateProcess' CreateProcessW kernel32 0 10
|
||||
imp '__CreateSymbolicLink' CreateSymbolicLinkW kernel32 0 3
|
||||
imp '__CreateThread' CreateThread kernel32 0 6
|
||||
imp '__DeleteFile' DeleteFileW kernel32 0 1
|
||||
imp '__DeviceIoControl' DeviceIoControl kernel32 0 8
|
||||
|
@ -1365,11 +1360,16 @@ imp '__GenerateConsoleCtrlEvent' GenerateConsoleCtrlEvent kernel32 0 2
|
|||
imp '__GetFileAttributes' GetFileAttributesW kernel32 0 1
|
||||
imp '__MapViewOfFileEx' MapViewOfFileEx kernel32 0 6
|
||||
imp '__MapViewOfFileExNuma' MapViewOfFileExNuma kernel32 0 7
|
||||
imp '__MoveFileEx' MoveFileExW kernel32 0 3
|
||||
imp '__OpenProcess' OpenProcess kernel32 0 3
|
||||
imp '__ReOpenFile' ReOpenFile kernel32 0 4 # TODO(jart): 6.2 and higher
|
||||
imp '__RemoveDirectory' RemoveDirectoryW kernel32 0 1
|
||||
imp '__SetCurrentDirectory' SetCurrentDirectoryW kernel32 0 1
|
||||
imp '__TerminateProcess' TerminateProcess kernel32 0 2
|
||||
imp '__TlsAlloc' TlsAlloc kernel32 0 0
|
||||
imp '__TlsFree' TlsFree kernel32 0 1
|
||||
imp '__TlsGetValue' TlsGetValue kernel32 0 1
|
||||
imp '__TlsSetValue' TlsSetValue kernel32 0 2
|
||||
imp '__UnmapViewOfFile' UnmapViewOfFile kernel32 0 1
|
||||
imp '__VirtualProtect' VirtualProtect kernel32 0 4
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define _NtGetFib() gs((void **)(0x20))
|
||||
#define _NtGetEnv() gs((char16_t **)(0x38))
|
||||
#define _NtGetRpc() gs((void **)(0x50))
|
||||
#define _NtGetTls() gs((void **)(0x58))
|
||||
#define _NtGetTls() gs((void **)(0x58)) /* cf. gs((long *)0x1480 + i0..64) */
|
||||
|
||||
#endif /* __GNUC__ && !__STRICT_ANSI__ */
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue