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:
Justine Tunney 2022-04-20 09:56:53 -07:00
parent c3fb624647
commit ae638c0850
181 changed files with 2994 additions and 1367 deletions

View file

@ -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
View 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;
}

View file

@ -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
View 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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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'\\';

View file

@ -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 {

View file

@ -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"
/**

View file

@ -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;

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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 {

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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),

View file

@ -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.

View file

@ -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;

View file

@ -93,5 +93,5 @@ textwindows int ntspawn(
}
if (block) UnmapViewOfFile(block);
if (handle) CloseHandle(handle);
return rc;
return __fix_enotdir(rc, prog16);
}

View file

@ -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) {

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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
*/

View file

@ -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);
}
}

View file

@ -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
View 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);
}

View file

@ -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

View file

@ -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;
}
}
/**

View file

@ -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) {

View file

@ -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) {

View file

@ -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;
}
}

View 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;
}

View file

@ -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;

View file

@ -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 "

View file

@ -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;
}

View file

@ -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_ */

View file

@ -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

View 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_ */

View file

@ -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);
}
}

View file

@ -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) {

View file

@ -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);
}

View file

@ -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];
};

View file

@ -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);
}

View file

@ -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;

View file

@ -25,4 +25,4 @@
*
* By default no limit is imposed.
*/
size_t __virtualmax;
size_t __virtualmax = -1;

View file

@ -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,

View file

@ -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,

View file

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

View file

@ -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;

View file

@ -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);

View file

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

View 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);
}

View file

@ -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 (;;) {

View file

@ -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) {

View file

@ -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.

View file

@ -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();

View file

@ -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 \

View file

@ -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

View file

@ -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;

View 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
View 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
View 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_ */

View file

@ -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);
}

View file

@ -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) {

View file

@ -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
View 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
View 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
View 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_ */

View file

@ -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);

View file

@ -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,
};

View 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_ */

View file

@ -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);

View file

@ -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;

View file

@ -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_ */

View 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_ */

View file

@ -44,8 +44,6 @@
#define kNtDuplicateCloseSource 1
#define kNtDuplicateSameAccess 2
#define kNtSymbolicLinkFlagDirectory 1
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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