mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Fix bugs and make improvements
- Get clone() working on FreeBSD - Increase some Python build quotas - Add more atomic builtins to chibicc - Fix ASAN poisoning of alloca() memory - Make MODE= mandatory link path tinier - Improve the examples folder a little bit - Start working on some more resource limits - Make the linenoise auto-complete UI as good as GNU readline - Update compile.com, avoiding AVX codegen on non-AVX systems - Make sure empty path to syscalls like opendir raises ENOENT - Correctly polyfill ENOENT vs. ENOTDIR on the New Technology - Port bestline's paredit features to //third_party/linenoise - Remove workarounds for RHEL 5.0 bugs that were fixed in 5.1
This commit is contained in:
parent
c3fb624647
commit
ae638c0850
181 changed files with 2994 additions and 1367 deletions
|
@ -87,7 +87,6 @@ int chdir(const char *);
|
|||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t);
|
||||
int chroot(const char *);
|
||||
int clone(int (*)(void *), void *, int, void *, ...);
|
||||
int close(int);
|
||||
int closedir(DIR *);
|
||||
int creat(const char *, uint32_t);
|
||||
|
@ -169,6 +168,7 @@ int sched_yield(void);
|
|||
int setegid(uint32_t);
|
||||
int seteuid(uint32_t);
|
||||
int setgid(int);
|
||||
int setpgrp(void);
|
||||
int setpgid(int, int);
|
||||
int setpriority(int, unsigned, int);
|
||||
int setregid(uint32_t, uint32_t);
|
||||
|
@ -206,7 +206,7 @@ long ptrace(int, ...);
|
|||
long telldir(DIR *);
|
||||
long times(struct tms *);
|
||||
size_t GetFileSize(const char *);
|
||||
size_t getfiledescriptorsize(int);
|
||||
ssize_t getfiledescriptorsize(int);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t lseek(int, int64_t, unsigned);
|
||||
|
@ -233,6 +233,8 @@ void rewinddir(DIR *);
|
|||
void sync(void);
|
||||
int getloadavg(double *, int);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
int clone(int (*)(void *), void *, size_t, int, void *, int *, void *, size_t,
|
||||
int *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » formatting ─╬─│┼
|
||||
|
|
|
@ -110,6 +110,7 @@ o/$(MODE)/libc/calls/execle.o \
|
|||
o/$(MODE)/libc/calls/execlp.o \
|
||||
o/$(MODE)/libc/calls/execve-nt.o \
|
||||
o/$(MODE)/libc/calls/execve-sysv.o \
|
||||
o/$(MODE)/libc/calls/readlinkat-nt.o \
|
||||
o/$(MODE)/libc/calls/mkntenvblock.o: \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
|
|
@ -31,6 +31,7 @@ textwindows int sys_chdir_nt(const char *path) {
|
|||
int e, ms, err, len;
|
||||
char16_t path16[PATH_MAX], var[4];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
if (!len) return enoent();
|
||||
if (len && path16[len - 1] != u'\\') {
|
||||
if (len + 2 > PATH_MAX) return enametoolong();
|
||||
path16[len + 0] = u'\\';
|
||||
|
|
|
@ -42,16 +42,6 @@ textwindows struct DirectMap sys_mmap_nt(void *addr, size_t size, int prot,
|
|||
const struct NtSecurityAttributes *sec;
|
||||
struct NtProcessMemoryCountersEx memcount;
|
||||
|
||||
#if _NT_RLIMIT_PWSS_MB
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(), &memcount, sizeof(memcount))) {
|
||||
if (memcount.PeakWorkingSetSize > _NT_RLIMIT_PWSS_MB * 1048576ull) {
|
||||
kprintf("error: PeakWorkingSetSize %'ldmb exceeded %'ldmb limit%n",
|
||||
memcount.PeakWorkingSetSize / 1048576, (long)_NT_RLIMIT_PWSS_MB);
|
||||
_Exit(201);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fd != -1) {
|
||||
handle = g_fds.p[fd].handle;
|
||||
} else {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,15 +20,13 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
#define __NR_dup3_linux 0x0124 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) {
|
||||
static bool once, demodernize;
|
||||
int olderr, fd;
|
||||
if (!once) {
|
||||
olderr = errno;
|
||||
fd = __sys_dup3(oldfd, newfd, flags);
|
||||
if ((fd == -1 && errno == ENOSYS) || fd == __NR_dup3_linux) {
|
||||
if (fd == -1 && errno == ENOSYS) {
|
||||
STRACE("demodernizing %s() due to %s", "dup3", "RHEL5:CVE-2010-3301");
|
||||
demodernize = true;
|
||||
once = true;
|
||||
|
|
|
@ -42,6 +42,17 @@ static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) {
|
|||
return false;
|
||||
}
|
||||
|
||||
textwindows dontinline int64_t __fix_enotdir3(int64_t rc, char16_t *path1,
|
||||
char16_t *path2) {
|
||||
if (rc == -1 && errno == kNtErrorPathNotFound) {
|
||||
if ((!path1 || !SubpathExistsThatsNotDirectory(path1)) &&
|
||||
(!path2 || !SubpathExistsThatsNotDirectory(path2))) {
|
||||
errno = kNtErrorFileNotFound;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
// WIN32 doesn't distinguish between ENOTDIR and ENOENT. UNIX strictly
|
||||
// requires that a directory component *exists* but is not a directory
|
||||
// whereas WIN32 will return ENOTDIR if a dir label simply isn't found
|
||||
|
@ -54,10 +65,5 @@ static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) {
|
|||
// dangling symbolic link.
|
||||
//
|
||||
textwindows int64_t __fix_enotdir(int64_t rc, char16_t *path) {
|
||||
if (rc == -1 && errno == kNtErrorPathNotFound) {
|
||||
if (!SubpathExistsThatsNotDirectory(path)) {
|
||||
errno = kNtErrorFileNotFound;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return __fix_enotdir3(rc, path, 0);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
/**
|
||||
* Returns information about file, via open()'d descriptor.
|
||||
*
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstat(int fd, struct stat *st) {
|
||||
|
|
|
@ -39,8 +39,8 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
|||
0)) != -1) {
|
||||
rc = st ? sys_fstat_nt(fh, st) : 0;
|
||||
CloseHandle(fh);
|
||||
return rc;
|
||||
} else {
|
||||
return __winerr();
|
||||
rc = __winerr();
|
||||
}
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,10 @@ textwindows int sys_ftruncate_nt(int64_t handle, uint64_t length) {
|
|||
bool32 ok;
|
||||
int64_t tell;
|
||||
tell = -1;
|
||||
if (SetFilePointerEx(handle, 0, &tell, kNtFileCurrent)) {
|
||||
if ((ok = SetFilePointerEx(handle, 0, &tell, kNtFileCurrent))) {
|
||||
ok = SetFilePointerEx(handle, length, NULL, kNtFileBegin) &&
|
||||
SetEndOfFile(handle);
|
||||
SetFilePointerEx(handle, tell, NULL, kNtFileBegin);
|
||||
return ok ? 0 : __winerr();
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
return ok ? 0 : __winerr();
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ 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/bits/pushpop.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
STATIC_YOINK("_init_g_fds");
|
||||
|
||||
struct Fds g_fds;
|
||||
_Alignas(64) char __fds_lock;
|
||||
|
||||
textstartup void InitializeFileDescriptors(void) {
|
||||
struct Fds *fds;
|
||||
fds = VEIL("r", &g_fds);
|
||||
pushmov(&fds->n, ARRAYLEN(fds->__init_p));
|
||||
fds->p = fds->__init_p;
|
||||
if (IsMetal()) {
|
||||
pushmov(&fds->f, 3ull);
|
||||
fds->__init_p[0].kind = pushpop(kFdSerial);
|
||||
fds->__init_p[1].kind = pushpop(kFdSerial);
|
||||
fds->__init_p[2].kind = pushpop(kFdSerial);
|
||||
fds->__init_p[0].handle = VEIL("r", 0x3F8ull);
|
||||
fds->__init_p[1].handle = VEIL("r", 0x3F8ull);
|
||||
fds->__init_p[2].handle = VEIL("r", 0x3F8ull);
|
||||
} else if (IsWindows()) {
|
||||
pushmov(&fds->f, 3ull);
|
||||
fds->__init_p[0].kind = pushpop(kFdFile);
|
||||
fds->__init_p[1].kind = pushpop(kFdFile);
|
||||
fds->__init_p[2].kind = pushpop(kFdFile);
|
||||
fds->__init_p[0].handle = GetStdHandle(pushpop(kNtStdInputHandle));
|
||||
fds->__init_p[1].handle = GetStdHandle(pushpop(kNtStdOutputHandle));
|
||||
fds->__init_p[2].handle = GetStdHandle(pushpop(kNtStdErrorHandle));
|
||||
}
|
||||
fds->__init_p[0].flags = O_RDONLY;
|
||||
fds->__init_p[1].flags = O_WRONLY | O_APPEND;
|
||||
fds->__init_p[2].flags = O_WRONLY | O_APPEND;
|
||||
}
|
|
@ -29,14 +29,15 @@
|
|||
|
||||
char *sys_getcwd_xnu(char *res, size_t size) {
|
||||
int fd;
|
||||
struct stat st[2];
|
||||
union metastat st[2];
|
||||
char buf[XNU_MAXPATHLEN], *ret = NULL;
|
||||
if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) {
|
||||
if (sys_fstat(fd, &st[0]) != -1) {
|
||||
if (st[0].st_dev && st[0].st_ino) {
|
||||
if (__sys_fstat(fd, &st[0]) != -1) {
|
||||
if (METASTAT(st[0], st_dev) && METASTAT(st[0], st_ino)) {
|
||||
if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) {
|
||||
if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
|
||||
if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) {
|
||||
if (__sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
|
||||
if (METASTAT(st[0], st_dev) == METASTAT(st[1], st_dev) &&
|
||||
METASTAT(st[0], st_ino) == METASTAT(st[1], st_ino)) {
|
||||
if (memccpy(res, buf, '\0', size)) {
|
||||
ret = res;
|
||||
} else {
|
||||
|
|
|
@ -16,20 +16,65 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/metastat.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/struct/filestandardinformation.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Determines size of open file.
|
||||
*
|
||||
* @return file byte length, or -1ul w/ errno
|
||||
* This function is equivalent to:
|
||||
*
|
||||
* struct stat st;
|
||||
* !fstat(fd, &st) ? st.st_size : -1
|
||||
*
|
||||
* Except faster on BSD/Windows and a much smaller link size.
|
||||
*
|
||||
* @return file byte length, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
size_t getfiledescriptorsize(int fd) {
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1) return SIZE_MAX;
|
||||
return st.st_size;
|
||||
ssize_t getfiledescriptorsize(int fd) {
|
||||
int e;
|
||||
ssize_t rc;
|
||||
union metastat st;
|
||||
struct NtFileStandardInformation info;
|
||||
e = errno;
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
if (weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &st.cosmo) !=
|
||||
-1) {
|
||||
rc = st.cosmo.st_size;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else if (IsMetal()) {
|
||||
rc = -1;
|
||||
} else if (!IsWindows()) {
|
||||
if (!__sys_fstat(fd, &st)) {
|
||||
rc = METASTAT(st, st_size);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (GetFileInformationByHandleEx(g_fds.p[fd].handle, kNtFileStandardInfo,
|
||||
&info, sizeof(info))) {
|
||||
rc = info.EndOfFile;
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
} else {
|
||||
rc = ebadf();
|
||||
}
|
||||
STRACE("getfiledescriptorsize(%d) → %'zd% m", fd, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* Returns the byte length of file by path.
|
||||
*
|
||||
* @return number of bytes, or -1ul w/ errno
|
||||
* @see getfiledescriptorsize
|
||||
* @see getfiledescriptorsize()
|
||||
*/
|
||||
size_t GetFileSize(const char *pathname) {
|
||||
struct stat st;
|
||||
|
|
|
@ -131,6 +131,7 @@ i32 __sys_getrusage(i32, struct rusage *) hidden;
|
|||
i32 __sys_munmap(void *, u64) hidden;
|
||||
i32 __sys_openat(i32, const char *, i32, u32) hidden;
|
||||
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||
i32 __sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden;
|
||||
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
||||
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
||||
i32 sys_chdir(const char *) hidden;
|
||||
|
@ -197,7 +198,7 @@ i32 sys_setsid(void) hidden;
|
|||
i32 sys_setuid(i32) hidden;
|
||||
i32 sys_sigaction(i32, const void *, void *, i64, i64) hidden;
|
||||
i32 sys_sigaltstack(const void *, void *) hidden;
|
||||
i32 sys_sigprocmask(i32, const sigset *, sigset *, u64) hidden;
|
||||
i32 sys_sigprocmask(i32, const sigset *, sigset *) hidden;
|
||||
i32 sys_sigqueue(i32, i32, const union sigval) hidden;
|
||||
i32 sys_sigqueueinfo(i32, const siginfo_t *) hidden;
|
||||
i32 sys_sigsuspend(const sigset *, u64) hidden;
|
||||
|
@ -326,6 +327,7 @@ int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int64_t __fix_enotdir(int64_t, char16_t *) hidden;
|
||||
int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *) hidden;
|
||||
bool _check_interrupts(bool, struct Fd *) hidden;
|
||||
void _check_sigchld(void) hidden;
|
||||
void _check_sigalrm(void) hidden;
|
||||
|
|
|
@ -30,7 +30,7 @@ textwindows int sys_linkat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
|||
if (CreateHardLink(newpath16, oldpath16, NULL)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
return __fix_enotdir3(__winerr(), newpath16, oldpath16);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
|
|
|
@ -29,6 +29,7 @@ int __mkntpathat(int dirfd, const char *path, int flags,
|
|||
char16_t dir[PATH_MAX];
|
||||
uint32_t dirlen, filelen;
|
||||
if ((filelen = __mkntpath2(path, file, flags)) == -1) return -1;
|
||||
if (!filelen) return enoent();
|
||||
if (file[0] != u'\\' && dirfd != AT_FDCWD) { /* ProTip: \\?\C:\foo */
|
||||
if (!__isfdkind(dirfd, kFdFile)) return ebadf();
|
||||
dirlen = GetFinalPathNameByHandle(g_fds.p[dirfd].handle, dir, ARRAYLEN(dir),
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/runtime/directmap.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
||||
/**
|
||||
* Unmaps memory directly with system.
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
||||
if (!cr) return;
|
||||
ctx->uc_flags = cr->EFlags;
|
||||
ctx->uc_mcontext.gregs[REG_EFL] = cr->EFlags;
|
||||
ctx->uc_mcontext.eflags = cr->EFlags;
|
||||
ctx->uc_mcontext.rax = cr->Rax;
|
||||
ctx->uc_mcontext.rbx = cr->Rbx;
|
||||
ctx->uc_mcontext.rcx = cr->Rcx;
|
||||
|
@ -52,7 +52,7 @@ textwindows void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
|||
textwindows void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
|
||||
if (!cr) return;
|
||||
cr->EFlags = ctx->uc_flags;
|
||||
cr->EFlags = ctx->uc_mcontext.gregs[REG_EFL];
|
||||
cr->EFlags = ctx->uc_mcontext.eflags;
|
||||
cr->Rax = ctx->uc_mcontext.rax;
|
||||
cr->Rbx = ctx->uc_mcontext.rbx;
|
||||
cr->Rcx = ctx->uc_mcontext.rcx;
|
||||
|
|
|
@ -93,5 +93,5 @@ textwindows int ntspawn(
|
|||
}
|
||||
if (block) UnmapViewOfFile(block);
|
||||
if (handle) CloseHandle(handle);
|
||||
return rc;
|
||||
return __fix_enotdir(rc, prog16);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
|
|||
int64_t hin, hout;
|
||||
int reader, writer;
|
||||
char16_t pipename[64];
|
||||
if (!pipefd) return efault();
|
||||
CreatePipeName(pipename);
|
||||
if ((reader = __reservefd(-1)) == -1) return -1;
|
||||
if ((writer = __reservefd(-1)) == -1) {
|
||||
|
|
|
@ -28,12 +28,16 @@
|
|||
*
|
||||
* @param fd is (reader, writer)
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @raise EFAULT if pipefd is NULL or an invalid address
|
||||
* @raise EMFILE if RLIMIT_NOFILE is exceedde
|
||||
* @asyncsignalsafe
|
||||
* @see pipe2()
|
||||
*/
|
||||
int pipe(int pipefd[hasatleast 2]) {
|
||||
int rc;
|
||||
if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) {
|
||||
if (!pipefd || (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) {
|
||||
// needed for windows which is polyfilled
|
||||
// needed for xnu and netbsd which don't take an argument
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_pipe(pipefd);
|
||||
|
|
|
@ -19,16 +19,15 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
||||
#define __NR_pipe2_linux 0x0125 /*RHEL5:CVE-2010-3301*/
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int32_t sys_pipe2(int pipefd[hasatleast 2], unsigned flags) {
|
||||
int rc, olderr;
|
||||
if (!flags) goto OldSkool;
|
||||
olderr = errno;
|
||||
rc = __sys_pipe2(pipefd, flags);
|
||||
if ((rc == -1 && errno == ENOSYS) ||
|
||||
(SupportsLinux() && rc == __NR_pipe2_linux)) {
|
||||
if (rc == -1 && errno == ENOSYS) {
|
||||
errno = olderr;
|
||||
OldSkool:
|
||||
if ((rc = sys_pipe(pipefd)) != -1) {
|
||||
|
|
|
@ -20,20 +20,22 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Creates file-less file descriptors for interprocess communication.
|
||||
*
|
||||
* @param pipefd is used to return (reader, writer) file descriptors
|
||||
* @param flags can have O_CLOEXEC, O_NONBLOCK, O_DIRECT
|
||||
* @param flags can have O_CLOEXEC or O_DIRECT or O_NONBLOCK
|
||||
* @return 0 on success, or -1 w/ errno and pipefd isn't modified
|
||||
*/
|
||||
int pipe2(int pipefd[hasatleast 2], int flags) {
|
||||
int rc;
|
||||
if (!pipefd) {
|
||||
rc = efault();
|
||||
} else if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) {
|
||||
if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) {
|
||||
return einval();
|
||||
} else if (!pipefd ||
|
||||
(IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_pipe2(pipefd, flags);
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_preadv_linux 0x0127
|
||||
|
||||
/**
|
||||
* Reads with maximum generality.
|
||||
*
|
||||
|
@ -76,14 +74,6 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
|
|||
once = true;
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "preadv", "ENOSYS");
|
||||
} else if (IsLinux() && rc == __NR_preadv_linux) {
|
||||
if (__iovec_size(iov, iovlen) < __NR_preadv_linux) {
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "preadv", "RHEL5:CVE-2010-3301");
|
||||
once = true;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
once = true;
|
||||
return rc;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
|
@ -46,7 +47,7 @@
|
|||
|
||||
char program_executable_name[SIZE];
|
||||
|
||||
static textwindows bool GetNtExePath(char executable[SIZE]) {
|
||||
static textwindows bool GetNtExePath(char exe[SIZE]) {
|
||||
bool32 rc;
|
||||
uint64_t w;
|
||||
wint_t x, y;
|
||||
|
@ -54,7 +55,7 @@ static textwindows bool GetNtExePath(char executable[SIZE]) {
|
|||
char16_t path16[PATH_MAX + 1];
|
||||
path16[0] = 0;
|
||||
rc = GetModuleFileName(0, path16, ARRAYLEN(path16));
|
||||
STRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||
NTTRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||
if (!rc) return false;
|
||||
for (i = j = 0; (x = path16[i++] & 0xffff);) {
|
||||
if (!IsUcs2(x)) {
|
||||
|
@ -64,47 +65,49 @@ static textwindows bool GetNtExePath(char executable[SIZE]) {
|
|||
if (x == '\\') x = '/';
|
||||
w = tpenc(x);
|
||||
do {
|
||||
executable[j] = w;
|
||||
exe[j] = w;
|
||||
if (++j == SIZE) {
|
||||
return false;
|
||||
}
|
||||
} while ((w >>= 8));
|
||||
}
|
||||
executable[j] = 0;
|
||||
exe[j] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ReadProgramExecutableName(char executable[SIZE], char *argv0,
|
||||
static void ReadProgramExecutableName(char exe[SIZE], char *argv0,
|
||||
uintptr_t *auxv) {
|
||||
int e;
|
||||
size_t m;
|
||||
ssize_t n;
|
||||
int cmd[4];
|
||||
char *p, *t;
|
||||
if (IsWindows() && GetNtExePath(executable)) {
|
||||
return;
|
||||
}
|
||||
for (p = 0; *auxv; auxv += 2) {
|
||||
if (*auxv == AT_EXECFN) {
|
||||
p = (char *)auxv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
if (!p) p = argv0;
|
||||
if (p) {
|
||||
if (!_isabspath(p)) {
|
||||
if (getcwd(executable, SIZE - 1)) {
|
||||
n = strlen(executable);
|
||||
executable[n++] = '/';
|
||||
e = errno;
|
||||
if (!IsWindows() || !GetNtExePath(exe)) {
|
||||
for (p = 0; *auxv; auxv += 2) {
|
||||
if (*auxv == AT_EXECFN) {
|
||||
p = (char *)auxv[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (; *p; ++p) {
|
||||
if (n + 1 < SIZE) {
|
||||
executable[n++] = *p;
|
||||
n = 0;
|
||||
if (!p) p = argv0;
|
||||
if (p) {
|
||||
if (!_isabspath(p)) {
|
||||
if (getcwd(exe, SIZE - 1)) {
|
||||
n = strlen(exe);
|
||||
exe[n++] = '/';
|
||||
}
|
||||
}
|
||||
for (; *p; ++p) {
|
||||
if (n + 1 < SIZE) {
|
||||
exe[n++] = *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
exe[n] = 0;
|
||||
}
|
||||
executable[n] = 0;
|
||||
errno = e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,14 +127,9 @@ static void ReadProgramExecutableName(char executable[SIZE], char *argv0,
|
|||
* @see program_invocation_name
|
||||
*/
|
||||
char *GetProgramExecutableName(void) {
|
||||
int e;
|
||||
static bool once;
|
||||
char executable[SIZE];
|
||||
if (!once) {
|
||||
e = errno;
|
||||
ReadProgramExecutableName(executable, __argv[0], __auxv);
|
||||
errno = e;
|
||||
__stpcpy(program_executable_name, executable);
|
||||
ReadProgramExecutableName(program_executable_name, __argv[0], __auxv);
|
||||
once = true;
|
||||
}
|
||||
return program_executable_name;
|
||||
|
|
|
@ -29,8 +29,6 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_pwritev_linux 0x0128
|
||||
|
||||
/**
|
||||
* Writes data from multiple buffers to offset.
|
||||
*
|
||||
|
@ -80,15 +78,6 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
|||
once = true;
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "pwritev", "ENOSYS");
|
||||
} else if (IsLinux() && rc == __NR_pwritev_linux) {
|
||||
if (__iovec_size(iov, iovlen) < __NR_pwritev_linux) {
|
||||
demodernize = true;
|
||||
STRACE("demodernizing %s() due to %s", "pwritev",
|
||||
"RHEL5:CVE-2010-3301");
|
||||
once = true;
|
||||
} else {
|
||||
return rc;
|
||||
}
|
||||
} else {
|
||||
once = true;
|
||||
return rc;
|
||||
|
|
|
@ -16,30 +16,21 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
||||
size_t size, ssize_t offset) {
|
||||
uint32_t err, got, avail;
|
||||
uint32_t got, avail;
|
||||
struct NtOverlapped overlap;
|
||||
if (GetFileType(fd->handle) == kNtFileTypePipe) {
|
||||
for (;;) {
|
||||
|
@ -60,14 +51,16 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
|||
_offset2overlap(fd->handle, offset, &overlap))) {
|
||||
return got;
|
||||
}
|
||||
err = GetLastError();
|
||||
// make sure read() returns 0 on broken pipe
|
||||
if (err == kNtErrorBrokenPipe) return 0;
|
||||
// make sure read() returns 0 on closing named pipe
|
||||
if (err == kNtErrorNoData) return 0;
|
||||
// make sure pread() returns 0 if we start reading after EOF
|
||||
if (err == kNtErrorHandleEof) return 0;
|
||||
return __winerr();
|
||||
switch (GetLastError()) {
|
||||
case kNtErrorBrokenPipe: // broken pipe
|
||||
case kNtErrorNoData: // closing named pipe
|
||||
case kNtErrorHandleEof: // pread read past EOF
|
||||
return 0; //
|
||||
case kNtErrorAccessDenied: // read doesn't return EACCESS
|
||||
return ebadf(); //
|
||||
default:
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
|
||||
textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov,
|
||||
|
|
|
@ -22,16 +22,10 @@
|
|||
/**
|
||||
* Reads symbolic link.
|
||||
*
|
||||
* This does *not* nul-terminate the buffer.
|
||||
*
|
||||
* It is recommended that malloc() be linked into your program when
|
||||
* using this function. Otherwise the buffer should be larger. It should
|
||||
* also be noted that, without malloc, long names with many astral plane
|
||||
* characters might not decode properly.
|
||||
*
|
||||
* @param path must be a symbolic link pathname
|
||||
* @param buf will receive symbolic link contents, and won't be modified
|
||||
* unless the function succeeds (with the exception of no-malloc nt)
|
||||
* and this buffer will *not* be nul-terminated
|
||||
* @return number of bytes written to buf, or -1 w/ errno; if the
|
||||
* return is equal to bufsiz then truncation may have occurred
|
||||
* @see readlinkat(AT_FDCWD, ...) for modern version of this
|
||||
|
|
|
@ -16,22 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fsctl.h"
|
||||
#include "libc/nt/enum/io.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/reparsedatabuffer.h"
|
||||
|
@ -45,25 +37,15 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
ssize_t rc;
|
||||
uint64_t w;
|
||||
wint_t x, y;
|
||||
void *freeme;
|
||||
volatile char *memory;
|
||||
uint32_t i, j, n, mem;
|
||||
char16_t path16[PATH_MAX], *p;
|
||||
struct NtReparseDataBuffer *rdb;
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (weaken(malloc)) {
|
||||
mem = 16384;
|
||||
rdb = weaken(malloc)(mem);
|
||||
freeme = rdb;
|
||||
} else if (bufsiz >= sizeof(struct NtReparseDataBuffer) + 16) {
|
||||
mem = bufsiz;
|
||||
rdb = (struct NtReparseDataBuffer *)buf;
|
||||
freeme = 0;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() needs bigger buffer malloc() to be yoinked");
|
||||
return enomem();
|
||||
}
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
mem = 16384;
|
||||
memory = alloca(mem);
|
||||
for (i = 0; i < mem; i += PAGESIZE) memory[i] = 0;
|
||||
rdb = (struct NtReparseDataBuffer *)memory;
|
||||
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
|
||||
kNtFileFlagOpenReparsePoint | kNtFileFlagBackupSemantics,
|
||||
0)) != -1) {
|
||||
|
@ -99,26 +81,17 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
w >>= 8;
|
||||
} while (w);
|
||||
}
|
||||
if (freeme || (intptr_t)(buf + j) <= (intptr_t)(p + i)) {
|
||||
rc = j;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() too many astral codepoints");
|
||||
rc = enametoolong();
|
||||
}
|
||||
rc = j;
|
||||
} else {
|
||||
NTTRACE("sys_readlinkat_nt() should have kNtIoReparseTagSymlink");
|
||||
rc = einval();
|
||||
}
|
||||
} else {
|
||||
assert(errno == EINVAL);
|
||||
rc = -1;
|
||||
}
|
||||
CloseHandle(h);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
if (freeme && weaken(free)) {
|
||||
weaken(free)(freeme);
|
||||
rc = __fix_enotdir(-1, path16);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -17,14 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
|
@ -33,16 +29,12 @@
|
|||
*
|
||||
* This does *not* nul-terminate the buffer.
|
||||
*
|
||||
* It is recommended that malloc() be linked into your program when
|
||||
* using this function. Otherwise the buffer should be larger. It should
|
||||
* also be noted that, without malloc, long names with many astral plane
|
||||
* characters might not decode properly.
|
||||
*
|
||||
* @param dirfd is normally AT_FDCWD but if it's an open directory and
|
||||
* file is a relative path, then file is opened relative to dirfd
|
||||
* @param path must be a symbolic link pathname
|
||||
* @param buf will receive symbolic link contents, and won't be modified
|
||||
* unless the function succeeds (with the exception of no-malloc nt)
|
||||
* and this buffer will *not* be nul-terminated
|
||||
* @return number of bytes written to buf, or -1 w/ errno; if the
|
||||
* return is equal to bufsiz then truncation may have occurred
|
||||
* @error EINVAL if path isn't a symbolic link
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
/**
|
||||
* Moves file the Unix way.
|
||||
*
|
||||
* This is generally an atomic operation with the file system, since all
|
||||
* it's doing is changing a name associated with an inode. However, that
|
||||
* means rename() doesn't permit your `oldpathname` and `newpathname` to
|
||||
* be on separate file systems, in which case this returns EXDEV. That's
|
||||
* also the case on Windows.
|
||||
*
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
|
|
|
@ -19,12 +19,9 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/enum/movefileexflags.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
const char *newpath) {
|
||||
char16_t oldpath16[PATH_MAX];
|
||||
char16_t newpath16[PATH_MAX];
|
||||
if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) == -1 ||
|
||||
|
@ -34,6 +31,6 @@ textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
|||
if (MoveFileEx(oldpath16, newpath16, kNtMovefileReplaceExisting)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
return __fix_enotdir3(-1, oldpath16, newpath16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
/**
|
||||
* Renames files relative to directories.
|
||||
*
|
||||
* This is generally an atomic operation with the file system, since all
|
||||
* it's doing is changing a name associated with an inode. However, that
|
||||
* means rename() doesn't permit your `oldpathname` and `newpathname` to
|
||||
* be on separate file systems, in which case this returns EXDEV. That's
|
||||
* also the case on Windows.
|
||||
*
|
||||
* @param olddirfd is normally AT_FDCWD but if it's an open directory
|
||||
* and oldpath is relative, then oldpath become relative to dirfd
|
||||
* @param newdirfd is normally AT_FDCWD but if it's an open directory
|
||||
|
|
|
@ -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 2021 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,15 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
|
||||
void __releasefd(int fd) {
|
||||
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);
|
||||
}
|
||||
/**
|
||||
* Sets the process group ID.
|
||||
*/
|
||||
int setpgrp(void) {
|
||||
return setpgid(0, 0);
|
||||
}
|
|
@ -44,11 +44,20 @@
|
|||
* when the hard limit is exceeded. It works everywhere but Windows
|
||||
*
|
||||
* - `RLIMIT_NPROC` limits the number of simultaneous processes and it
|
||||
* should work on all platforms except Windows.
|
||||
* should work on all platforms except Windows. Please be advised it
|
||||
* limits the process, with respect to the activities of the user id
|
||||
* as a whole.
|
||||
*
|
||||
* - `RLIMIT_NOFILE` limits the number of open file descriptors and it
|
||||
* should work on all platforms except Windows (TODO)
|
||||
*
|
||||
* The rlimit magnums differ for each platform but occupy the interval
|
||||
* zero through `RLIM_NLIMITS`. Usually they're set to `RLIM_INFINITY`
|
||||
* which is `-1` on Linux/Windows, and `LONG_MAX` on BSDs. In any case
|
||||
* they're both very large numbers under the Cosmopolitan unsigned ABI
|
||||
* because struct rlimit uses uint64_t. The special magnum 127 is used
|
||||
* for constant values that aren't supported by the host platform.
|
||||
*
|
||||
* @param rlim specifies new resource limit
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @see libc/sysv/consts.sh
|
||||
|
|
|
@ -149,7 +149,11 @@ static textwindows bool __sig_deliver(bool restartable, int sig, int si_code,
|
|||
* Returns true if signal default action is to end process.
|
||||
*/
|
||||
static textwindows bool __sig_isfatal(int sig) {
|
||||
return sig != SIGCHLD;
|
||||
if (sig == SIGCHLD || sig == SIGURG || sig == SIGWINCH) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#undef sigaction
|
||||
|
||||
#ifdef SYSDEBUG
|
||||
STATIC_YOINK("strsignal"); // for kprintf()
|
||||
#endif
|
||||
|
@ -75,9 +77,9 @@ union metasigaction {
|
|||
struct sigaction_xnu_out xnu_out;
|
||||
};
|
||||
|
||||
void __sigenter_netbsd(int, void *, void *);
|
||||
void __sigenter_freebsd(int, void *, void *);
|
||||
void __sigenter_openbsd(int, void *, void *);
|
||||
void __sigenter_netbsd(int, void *, void *) hidden;
|
||||
void __sigenter_freebsd(int, void *, void *) hidden;
|
||||
void __sigenter_openbsd(int, void *, void *) hidden;
|
||||
|
||||
static void sigaction_cosmo2native(union metasigaction *sa) {
|
||||
if (!sa) return;
|
||||
|
@ -279,7 +281,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
* `SA_NOMASK` for this flag, which means the same thing.
|
||||
*
|
||||
* - `SA_NOCLDWAIT`: Changes `SIGCHLD` so the zombie is gone and you
|
||||
* can't call `wait()` anymore; similar to SIGCHLD + SIG_IGN but may
|
||||
* can't call `wait()` anymore; similar but may
|
||||
* still deliver the SIGCHLD.
|
||||
*
|
||||
* - `SA_NOCLDSTOP`: Lets you set `SIGCHLD` handler that's only notified
|
||||
|
@ -435,7 +437,7 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||
int rc;
|
||||
char buf[2][128];
|
||||
if (sig == SIGKILL || sig == SIGSTOP) {
|
||||
|
|
|
@ -45,10 +45,9 @@ void _check_sigchld(void) {
|
|||
STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
|
||||
return;
|
||||
}
|
||||
if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN) {
|
||||
STRACE("killing zombie fd=%d handle=%ld", pids[i], handles[i]);
|
||||
CloseHandle(handles[i]);
|
||||
__releasefd(pids[i]);
|
||||
if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN ||
|
||||
__sighandrvas[SIGCHLD] == (intptr_t)SIG_DFL) {
|
||||
STRACE("new zombie fd=%d handle=%ld", pids[i], handles[i]);
|
||||
return;
|
||||
}
|
||||
if (__sighandflags[SIGCHLD] & SA_NOCLDWAIT) {
|
||||
|
|
|
@ -21,68 +21,13 @@
|
|||
#include "libc/calls/struct/sigaction-freebsd.internal.h"
|
||||
#include "libc/calls/struct/siginfo-netbsd.internal.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/ucontext-netbsd.internal.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
#define RDI 0
|
||||
#define RSI 1
|
||||
#define RDX 2
|
||||
#define R10 6
|
||||
#define R8 4
|
||||
#define R9 5
|
||||
#define RCX 3
|
||||
#define R11 7
|
||||
#define R12 8
|
||||
#define R13 9
|
||||
#define R14 10
|
||||
#define R15 11
|
||||
#define RBP 12
|
||||
#define RBX 13
|
||||
#define RAX 14
|
||||
#define GS 15
|
||||
#define FS 16
|
||||
#define ES 17
|
||||
#define DS 18
|
||||
#define TRAP 19
|
||||
#define ERR 20
|
||||
#define RIP 21
|
||||
#define CS 22
|
||||
#define RFLAGS 23
|
||||
#define RSP 24
|
||||
#define SS 25
|
||||
|
||||
union sigval_netbsd {
|
||||
int32_t sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
struct sigset_netbsd {
|
||||
uint32_t __bits[4];
|
||||
};
|
||||
|
||||
struct stack_netbsd {
|
||||
void *ss_sp;
|
||||
size_t ss_size;
|
||||
int32_t ss_flags;
|
||||
};
|
||||
|
||||
struct mcontext_netbsd {
|
||||
int64_t __gregs[26];
|
||||
int64_t _mc_tlsbase;
|
||||
struct FpuState __fpregs;
|
||||
};
|
||||
|
||||
struct ucontext_netbsd {
|
||||
uint32_t uc_flags;
|
||||
struct ucontext_netbsd *uc_link;
|
||||
struct sigset_netbsd uc_sigmask;
|
||||
struct stack_netbsd uc_stack;
|
||||
struct mcontext_netbsd uc_mcontext;
|
||||
};
|
||||
|
||||
void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
||||
struct ucontext_netbsd *ctx) {
|
||||
int rva, flags;
|
||||
|
@ -109,50 +54,50 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
|
||||
memcpy(&uc.uc_sigmask, &ctx->uc_sigmask,
|
||||
MIN(sizeof(uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
|
||||
uc.uc_mcontext.rdi = ctx->uc_mcontext.__gregs[RDI];
|
||||
uc.uc_mcontext.rsi = ctx->uc_mcontext.__gregs[RSI];
|
||||
uc.uc_mcontext.rdx = ctx->uc_mcontext.__gregs[RDX];
|
||||
uc.uc_mcontext.rcx = ctx->uc_mcontext.__gregs[RCX];
|
||||
uc.uc_mcontext.r8 = ctx->uc_mcontext.__gregs[R8];
|
||||
uc.uc_mcontext.r9 = ctx->uc_mcontext.__gregs[R9];
|
||||
uc.uc_mcontext.rax = ctx->uc_mcontext.__gregs[RAX];
|
||||
uc.uc_mcontext.rbx = ctx->uc_mcontext.__gregs[RBX];
|
||||
uc.uc_mcontext.rbp = ctx->uc_mcontext.__gregs[RBP];
|
||||
uc.uc_mcontext.r10 = ctx->uc_mcontext.__gregs[R10];
|
||||
uc.uc_mcontext.r11 = ctx->uc_mcontext.__gregs[R11];
|
||||
uc.uc_mcontext.r12 = ctx->uc_mcontext.__gregs[R12];
|
||||
uc.uc_mcontext.r13 = ctx->uc_mcontext.__gregs[R13];
|
||||
uc.uc_mcontext.r14 = ctx->uc_mcontext.__gregs[R14];
|
||||
uc.uc_mcontext.r15 = ctx->uc_mcontext.__gregs[R15];
|
||||
uc.uc_mcontext.trapno = ctx->uc_mcontext.__gregs[TRAP];
|
||||
uc.uc_mcontext.fs = ctx->uc_mcontext.__gregs[FS];
|
||||
uc.uc_mcontext.gs = ctx->uc_mcontext.__gregs[GS];
|
||||
uc.uc_mcontext.err = ctx->uc_mcontext.__gregs[ERR];
|
||||
uc.uc_mcontext.rip = ctx->uc_mcontext.__gregs[RIP];
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.__gregs[RSP];
|
||||
uc.uc_mcontext.rdi = ctx->uc_mcontext.rdi;
|
||||
uc.uc_mcontext.rsi = ctx->uc_mcontext.rsi;
|
||||
uc.uc_mcontext.rdx = ctx->uc_mcontext.rdx;
|
||||
uc.uc_mcontext.rcx = ctx->uc_mcontext.rcx;
|
||||
uc.uc_mcontext.r8 = ctx->uc_mcontext.r8;
|
||||
uc.uc_mcontext.r9 = ctx->uc_mcontext.r9;
|
||||
uc.uc_mcontext.rax = ctx->uc_mcontext.rax;
|
||||
uc.uc_mcontext.rbx = ctx->uc_mcontext.rbx;
|
||||
uc.uc_mcontext.rbp = ctx->uc_mcontext.rbp;
|
||||
uc.uc_mcontext.r10 = ctx->uc_mcontext.r10;
|
||||
uc.uc_mcontext.r11 = ctx->uc_mcontext.r11;
|
||||
uc.uc_mcontext.r12 = ctx->uc_mcontext.r12;
|
||||
uc.uc_mcontext.r13 = ctx->uc_mcontext.r13;
|
||||
uc.uc_mcontext.r14 = ctx->uc_mcontext.r14;
|
||||
uc.uc_mcontext.r15 = ctx->uc_mcontext.r15;
|
||||
uc.uc_mcontext.trapno = ctx->uc_mcontext.trapno;
|
||||
uc.uc_mcontext.fs = ctx->uc_mcontext.fs;
|
||||
uc.uc_mcontext.gs = ctx->uc_mcontext.gs;
|
||||
uc.uc_mcontext.err = ctx->uc_mcontext.err;
|
||||
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
|
||||
*uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs;
|
||||
((sigaction_f)(_base + rva))(sig, &si2, &uc);
|
||||
ctx->uc_mcontext.__gregs[RDI] = uc.uc_mcontext.rdi;
|
||||
ctx->uc_mcontext.__gregs[RSI] = uc.uc_mcontext.rsi;
|
||||
ctx->uc_mcontext.__gregs[RDX] = uc.uc_mcontext.rdx;
|
||||
ctx->uc_mcontext.__gregs[RCX] = uc.uc_mcontext.rcx;
|
||||
ctx->uc_mcontext.__gregs[R8] = uc.uc_mcontext.r8;
|
||||
ctx->uc_mcontext.__gregs[R9] = uc.uc_mcontext.r9;
|
||||
ctx->uc_mcontext.__gregs[RAX] = uc.uc_mcontext.rax;
|
||||
ctx->uc_mcontext.__gregs[RBX] = uc.uc_mcontext.rbx;
|
||||
ctx->uc_mcontext.__gregs[RBP] = uc.uc_mcontext.rbp;
|
||||
ctx->uc_mcontext.__gregs[R10] = uc.uc_mcontext.r10;
|
||||
ctx->uc_mcontext.__gregs[R11] = uc.uc_mcontext.r11;
|
||||
ctx->uc_mcontext.__gregs[R12] = uc.uc_mcontext.r12;
|
||||
ctx->uc_mcontext.__gregs[R13] = uc.uc_mcontext.r13;
|
||||
ctx->uc_mcontext.__gregs[R14] = uc.uc_mcontext.r14;
|
||||
ctx->uc_mcontext.__gregs[R15] = uc.uc_mcontext.r15;
|
||||
ctx->uc_mcontext.__gregs[TRAP] = uc.uc_mcontext.trapno;
|
||||
ctx->uc_mcontext.__gregs[FS] = uc.uc_mcontext.fs;
|
||||
ctx->uc_mcontext.__gregs[GS] = uc.uc_mcontext.gs;
|
||||
ctx->uc_mcontext.__gregs[ERR] = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.__gregs[RIP] = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.__gregs[RSP] = uc.uc_mcontext.rsp;
|
||||
ctx->uc_mcontext.rdi = uc.uc_mcontext.rdi;
|
||||
ctx->uc_mcontext.rsi = uc.uc_mcontext.rsi;
|
||||
ctx->uc_mcontext.rdx = uc.uc_mcontext.rdx;
|
||||
ctx->uc_mcontext.rcx = uc.uc_mcontext.rcx;
|
||||
ctx->uc_mcontext.r8 = uc.uc_mcontext.r8;
|
||||
ctx->uc_mcontext.r9 = uc.uc_mcontext.r9;
|
||||
ctx->uc_mcontext.rax = uc.uc_mcontext.rax;
|
||||
ctx->uc_mcontext.rbx = uc.uc_mcontext.rbx;
|
||||
ctx->uc_mcontext.rbp = uc.uc_mcontext.rbp;
|
||||
ctx->uc_mcontext.r10 = uc.uc_mcontext.r10;
|
||||
ctx->uc_mcontext.r11 = uc.uc_mcontext.r11;
|
||||
ctx->uc_mcontext.r12 = uc.uc_mcontext.r12;
|
||||
ctx->uc_mcontext.r13 = uc.uc_mcontext.r13;
|
||||
ctx->uc_mcontext.r14 = uc.uc_mcontext.r14;
|
||||
ctx->uc_mcontext.r15 = uc.uc_mcontext.r15;
|
||||
ctx->uc_mcontext.trapno = uc.uc_mcontext.trapno;
|
||||
ctx->uc_mcontext.fs = uc.uc_mcontext.fs;
|
||||
ctx->uc_mcontext.gs = uc.uc_mcontext.gs;
|
||||
ctx->uc_mcontext.err = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.rip = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.rsp = uc.uc_mcontext.rsp;
|
||||
ctx->uc_mcontext.__fpregs = *uc.uc_mcontext.fpregs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
/*-*- 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,12 +16,33 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
||||
.init.start 305,_init_g_fds
|
||||
push %rdi
|
||||
push %rsi
|
||||
call InitializeFileDescriptors
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
.init.end 305,_init_g_fds
|
||||
int sys_sigprocmask(int how, const sigset_t *opt_set,
|
||||
sigset_t *opt_out_oldset) {
|
||||
int res, rc, arg1;
|
||||
sigset_t old = {0};
|
||||
const sigset_t *arg2;
|
||||
if (!IsOpenbsd()) {
|
||||
rc = __sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0, 8);
|
||||
} else {
|
||||
if (opt_set) {
|
||||
// openbsd only supports 32 signals so it passses them in a reg
|
||||
arg1 = how;
|
||||
arg2 = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||
} else {
|
||||
arg1 = how; // SIG_BLOCK
|
||||
arg2 = 0; // changes nothing
|
||||
}
|
||||
if ((res = __sys_sigprocmask(arg1, arg2, 0, 0)) != -1) {
|
||||
memcpy(&old, &res, sizeof(res));
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
if (rc != -1 && opt_out_oldset) {
|
||||
*opt_out_oldset = old;
|
||||
}
|
||||
return rc;
|
||||
}
|
|
@ -68,26 +68,11 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
|||
(opt_out_oldset &&
|
||||
!__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset))))) {
|
||||
rc = efault();
|
||||
} else if (IsLinux() || IsXnu() || IsFreebsd() || IsNetbsd()) {
|
||||
rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0, 8);
|
||||
} else if (IsOpenbsd()) {
|
||||
if (opt_set) {
|
||||
// openbsd only supports 32 signals so it passses them in a reg
|
||||
arg1 = how;
|
||||
arg2 = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||
} else {
|
||||
arg1 = how; // SIG_BLOCK
|
||||
arg2 = 0; // changes nothing
|
||||
}
|
||||
if ((res = sys_sigprocmask(arg1, arg2, 0, 0)) != -1) {
|
||||
memcpy(&old, &res, sizeof(res));
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
} else { // windows or metal
|
||||
} else if (IsMetal() || IsWindows()) {
|
||||
rc = __sig_mask(how, opt_set, &old);
|
||||
_check_interrupts(false, 0);
|
||||
} else {
|
||||
rc = sys_sigprocmask(how, opt_set, opt_out_oldset ? &old : 0);
|
||||
}
|
||||
if (rc != -1 && opt_out_oldset) {
|
||||
*opt_out_oldset = old;
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
|
||||
#define _NT_RLIMIT_PWSS_MB 1000 /* nocommit */
|
||||
#define _KERNTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||
#define _NTTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _KERNTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||
#define _NTTRACE 0 /* not configurable w/ flag yet */
|
||||
|
||||
#define STRACE_PROLOGUE "%rSYS %5P %'18T "
|
||||
|
||||
|
|
|
@ -24,9 +24,27 @@
|
|||
|
||||
const char *__strace_rlimit_name(int resource) {
|
||||
static char buf[12];
|
||||
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||
if (resource != 127) {
|
||||
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||
if (resource == RLIMIT_NPROC) return "RLIMIT_NPROC";
|
||||
if (resource == RLIMIT_NOFILE) return "RLIMIT_NOFILE";
|
||||
if (resource == RLIMIT_RSS) return "RLIMIT_RSS";
|
||||
if (resource == RLIMIT_DATA) return "RLIMIT_DATA";
|
||||
if (resource == RLIMIT_CORE) return "RLIMIT_CORE";
|
||||
if (resource == RLIMIT_STACK) return "RLIMIT_STACK";
|
||||
if (resource == RLIMIT_SIGPENDING) return "RLIMIT_SIGPENDING";
|
||||
if (resource == RLIMIT_MEMLOCK) return "RLIMIT_MEMLOCK";
|
||||
if (resource == RLIMIT_LOCKS) return "RLIMIT_LOCKS";
|
||||
if (resource == RLIMIT_MSGQUEUE) return "RLIMIT_MSGQUEUE";
|
||||
if (resource == RLIMIT_NICE) return "RLIMIT_NICE";
|
||||
if (resource == RLIMIT_RTPRIO) return "RLIMIT_RTPRIO";
|
||||
if (resource == RLIMIT_RTTIME) return "RLIMIT_RTTIME";
|
||||
if (resource == RLIMIT_SWAP) return "RLIMIT_SWAP";
|
||||
if (resource == RLIMIT_SBSIZE) return "RLIMIT_SBSIZE";
|
||||
if (resource == RLIMIT_NPTS) return "RLIMIT_NPTS";
|
||||
}
|
||||
FormatInt32(buf, resource);
|
||||
return buf;
|
||||
}
|
||||
|
@ -35,6 +53,6 @@ privileged const char *__strace_rlimit(char buf[64], size_t bufsize, int rc,
|
|||
const struct rlimit *rlim) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!rlim) return "NULL";
|
||||
ksnprintf(buf, bufsize, "{%'lu, %'lu}", rlim->rlim_cur, rlim->rlim_max);
|
||||
ksnprintf(buf, bufsize, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max);
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -325,6 +325,9 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff
|
||||
#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56
|
||||
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \
|
||||
(((uint64_t)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
|
||||
|
||||
#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0)
|
||||
#define BPF_LOCAL_STORAGE_GET_F_CREATE (1ULL << 0)
|
||||
#define BPF_SK_STORAGE_GET_F_CREATE BPF_LOCAL_STORAGE_GET_F_CREATE
|
||||
|
@ -352,7 +355,8 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_F_BROADCAST (1ULL << 3)
|
||||
#define BPF_F_EXCLUDE_INGRESS (1ULL << 4)
|
||||
|
||||
#define BPF_TAG_SIZE 8
|
||||
#define XDP_PACKET_HEADROOM 256
|
||||
#define BPF_TAG_SIZE 8
|
||||
|
||||
#define BPF_SOCK_OPS_RTO_CB_FLAG (1 << 0)
|
||||
#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1 << 1)
|
||||
|
@ -451,10 +455,176 @@ COSMOPOLITAN_C_START_
|
|||
#define BPF_REDIRECT 7
|
||||
#define BPF_LWT_REROUTE 128
|
||||
|
||||
#define XDP_PACKET_HEADROOM 256
|
||||
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) \
|
||||
(((uint64_t)len & BPF_ADJ_ROOM_ENCAP_L2_MASK) << BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
|
||||
#define BPF_FUNC_unspec 0
|
||||
#define BPF_FUNC_map_lookup_elem 1
|
||||
#define BPF_FUNC_map_update_elem 2
|
||||
#define BPF_FUNC_map_delete_elem 3
|
||||
#define BPF_FUNC_probe_read 4
|
||||
#define BPF_FUNC_ktime_get_ns 5
|
||||
#define BPF_FUNC_trace_printk 6
|
||||
#define BPF_FUNC_get_prandom_u32 7
|
||||
#define BPF_FUNC_get_smp_processor_id 8
|
||||
#define BPF_FUNC_skb_store_bytes 9
|
||||
#define BPF_FUNC_l3_csum_replace 10
|
||||
#define BPF_FUNC_l4_csum_replace 11
|
||||
#define BPF_FUNC_tail_call 12
|
||||
#define BPF_FUNC_clone_redirect 13
|
||||
#define BPF_FUNC_get_current_pid_tgid 14
|
||||
#define BPF_FUNC_get_current_uid_gid 15
|
||||
#define BPF_FUNC_get_current_comm 16
|
||||
#define BPF_FUNC_get_cgroup_classid 17
|
||||
#define BPF_FUNC_skb_vlan_push 18
|
||||
#define BPF_FUNC_skb_vlan_pop 19
|
||||
#define BPF_FUNC_skb_get_tunnel_key 20
|
||||
#define BPF_FUNC_skb_set_tunnel_key 21
|
||||
#define BPF_FUNC_perf_event_read 22
|
||||
#define BPF_FUNC_redirect 23
|
||||
#define BPF_FUNC_get_route_realm 24
|
||||
#define BPF_FUNC_perf_event_output 25
|
||||
#define BPF_FUNC_skb_load_bytes 26
|
||||
#define BPF_FUNC_get_stackid 27
|
||||
#define BPF_FUNC_csum_diff 28
|
||||
#define BPF_FUNC_skb_get_tunnel_opt 29
|
||||
#define BPF_FUNC_skb_set_tunnel_opt 30
|
||||
#define BPF_FUNC_skb_change_proto 31
|
||||
#define BPF_FUNC_skb_change_type 32
|
||||
#define BPF_FUNC_skb_under_cgroup 33
|
||||
#define BPF_FUNC_get_hash_recalc 34
|
||||
#define BPF_FUNC_get_current_task 35
|
||||
#define BPF_FUNC_probe_write_user 36
|
||||
#define BPF_FUNC_current_task_under_cgroup 37
|
||||
#define BPF_FUNC_skb_change_tail 38
|
||||
#define BPF_FUNC_skb_pull_data 39
|
||||
#define BPF_FUNC_csum_update 40
|
||||
#define BPF_FUNC_set_hash_invalid 41
|
||||
#define BPF_FUNC_get_numa_node_id 42
|
||||
#define BPF_FUNC_skb_change_head 43
|
||||
#define BPF_FUNC_xdp_adjust_head 44
|
||||
#define BPF_FUNC_probe_read_str 45
|
||||
#define BPF_FUNC_get_socket_cookie 46
|
||||
#define BPF_FUNC_get_socket_uid 47
|
||||
#define BPF_FUNC_set_hash 48
|
||||
#define BPF_FUNC_setsockopt 49
|
||||
#define BPF_FUNC_skb_adjust_room 50
|
||||
#define BPF_FUNC_redirect_map 51
|
||||
#define BPF_FUNC_sk_redirect_map 52
|
||||
#define BPF_FUNC_sock_map_update 53
|
||||
#define BPF_FUNC_xdp_adjust_meta 54
|
||||
#define BPF_FUNC_perf_event_read_value 55
|
||||
#define BPF_FUNC_perf_prog_read_value 56
|
||||
#define BPF_FUNC_getsockopt 57
|
||||
#define BPF_FUNC_override_return 58
|
||||
#define BPF_FUNC_sock_ops_cb_flags_set 59
|
||||
#define BPF_FUNC_msg_redirect_map 60
|
||||
#define BPF_FUNC_msg_apply_bytes 61
|
||||
#define BPF_FUNC_msg_cork_bytes 62
|
||||
#define BPF_FUNC_msg_pull_data 63
|
||||
#define BPF_FUNC_bind 64
|
||||
#define BPF_FUNC_xdp_adjust_tail 65
|
||||
#define BPF_FUNC_skb_get_xfrm_state 66
|
||||
#define BPF_FUNC_get_stack 67
|
||||
#define BPF_FUNC_skb_load_bytes_relative 68
|
||||
#define BPF_FUNC_fib_lookup 69
|
||||
#define BPF_FUNC_sock_hash_update 70
|
||||
#define BPF_FUNC_msg_redirect_hash 71
|
||||
#define BPF_FUNC_sk_redirect_hash 72
|
||||
#define BPF_FUNC_lwt_push_encap 73
|
||||
#define BPF_FUNC_lwt_seg6_store_bytes 74
|
||||
#define BPF_FUNC_lwt_seg6_adjust_srh 75
|
||||
#define BPF_FUNC_lwt_seg6_action 76
|
||||
#define BPF_FUNC_rc_repeat 77
|
||||
#define BPF_FUNC_rc_keydown 78
|
||||
#define BPF_FUNC_skb_cgroup_id 79
|
||||
#define BPF_FUNC_get_current_cgroup_id 80
|
||||
#define BPF_FUNC_get_local_storage 81
|
||||
#define BPF_FUNC_sk_select_reuseport 82
|
||||
#define BPF_FUNC_skb_ancestor_cgroup_id 83
|
||||
#define BPF_FUNC_sk_lookup_tcp 84
|
||||
#define BPF_FUNC_sk_lookup_udp 85
|
||||
#define BPF_FUNC_sk_release 86
|
||||
#define BPF_FUNC_map_push_elem 87
|
||||
#define BPF_FUNC_map_pop_elem 88
|
||||
#define BPF_FUNC_map_peek_elem 89
|
||||
#define BPF_FUNC_msg_push_data 90
|
||||
#define BPF_FUNC_msg_pop_data 91
|
||||
#define BPF_FUNC_rc_pointer_rel 92
|
||||
#define BPF_FUNC_spin_lock 93
|
||||
#define BPF_FUNC_spin_unlock 94
|
||||
#define BPF_FUNC_sk_fullsock 95
|
||||
#define BPF_FUNC_tcp_sock 96
|
||||
#define BPF_FUNC_skb_ecn_set_ce 97
|
||||
#define BPF_FUNC_get_listener_sock 98
|
||||
#define BPF_FUNC_skc_lookup_tcp 99
|
||||
#define BPF_FUNC_tcp_check_syncookie 100
|
||||
#define BPF_FUNC_sysctl_get_name 101
|
||||
#define BPF_FUNC_sysctl_get_current_value 102
|
||||
#define BPF_FUNC_sysctl_get_new_value 103
|
||||
#define BPF_FUNC_sysctl_set_new_value 104
|
||||
#define BPF_FUNC_strtol 105
|
||||
#define BPF_FUNC_strtoul 106
|
||||
#define BPF_FUNC_sk_storage_get 107
|
||||
#define BPF_FUNC_sk_storage_delete 108
|
||||
#define BPF_FUNC_send_signal 109
|
||||
#define BPF_FUNC_tcp_gen_syncookie 110
|
||||
#define BPF_FUNC_skb_output 111
|
||||
#define BPF_FUNC_probe_read_user 112
|
||||
#define BPF_FUNC_probe_read_kernel 113
|
||||
#define BPF_FUNC_probe_read_user_str 114
|
||||
#define BPF_FUNC_probe_read_kernel_str 115
|
||||
#define BPF_FUNC_tcp_send_ack 116
|
||||
#define BPF_FUNC_send_signal_thread 117
|
||||
#define BPF_FUNC_jiffies64 118
|
||||
#define BPF_FUNC_read_branch_records 119
|
||||
#define BPF_FUNC_get_ns_current_pid_tgid 120
|
||||
#define BPF_FUNC_xdp_output 121
|
||||
#define BPF_FUNC_get_netns_cookie 122
|
||||
#define BPF_FUNC_get_current_ancestor_cgroup_id 123
|
||||
#define BPF_FUNC_sk_assign 124
|
||||
#define BPF_FUNC_ktime_get_boot_ns 125
|
||||
#define BPF_FUNC_seq_printf 126
|
||||
#define BPF_FUNC_seq_write 127
|
||||
#define BPF_FUNC_sk_cgroup_id 128
|
||||
#define BPF_FUNC_sk_ancestor_cgroup_id 129
|
||||
#define BPF_FUNC_ringbuf_output 130
|
||||
#define BPF_FUNC_ringbuf_reserve 131
|
||||
#define BPF_FUNC_ringbuf_submit 132
|
||||
#define BPF_FUNC_ringbuf_discard 133
|
||||
#define BPF_FUNC_ringbuf_query 134
|
||||
#define BPF_FUNC_csum_level 135
|
||||
#define BPF_FUNC_skc_to_tcp6_sock 136
|
||||
#define BPF_FUNC_skc_to_tcp_sock 137
|
||||
#define BPF_FUNC_skc_to_tcp_timewait_sock 138
|
||||
#define BPF_FUNC_skc_to_tcp_request_sock 139
|
||||
#define BPF_FUNC_skc_to_udp6_sock 140
|
||||
#define BPF_FUNC_get_task_stack 141
|
||||
#define BPF_FUNC_load_hdr_opt 142
|
||||
#define BPF_FUNC_store_hdr_opt 143
|
||||
#define BPF_FUNC_reserve_hdr_opt 144
|
||||
#define BPF_FUNC_inode_storage_get 145
|
||||
#define BPF_FUNC_inode_storage_delete 146
|
||||
#define BPF_FUNC_d_path 147
|
||||
#define BPF_FUNC_copy_from_user 148
|
||||
#define BPF_FUNC_snprintf_btf 149
|
||||
#define BPF_FUNC_seq_printf_btf 150
|
||||
#define BPF_FUNC_skb_cgroup_classid 151
|
||||
#define BPF_FUNC_redirect_neigh 152
|
||||
#define BPF_FUNC_per_cpu_ptr 153
|
||||
#define BPF_FUNC_this_cpu_ptr 154
|
||||
#define BPF_FUNC_redirect_peer 155
|
||||
#define BPF_FUNC_task_storage_get 156
|
||||
#define BPF_FUNC_task_storage_delete 157
|
||||
#define BPF_FUNC_get_current_task_btf 158
|
||||
#define BPF_FUNC_bprm_opts_set 159
|
||||
#define BPF_FUNC_ktime_get_coarse_ns 160
|
||||
#define BPF_FUNC_ima_inode_hash 161
|
||||
#define BPF_FUNC_sock_from_file 162
|
||||
#define BPF_FUNC_check_mtu 163
|
||||
#define BPF_FUNC_for_each_map_elem 164
|
||||
#define BPF_FUNC_snprintf 165
|
||||
#define BPF_FUNC_sys_bpf 166
|
||||
#define BPF_FUNC_btf_find_by_name_kind 167
|
||||
#define BPF_FUNC_sys_close 168
|
||||
#define __BPF_FUNC_MAX_ID 169
|
||||
|
||||
#define __bpf_md_ptr(type, name) \
|
||||
union { \
|
||||
|
@ -1157,185 +1327,6 @@ struct btf_ptr {
|
|||
uint32_t flags;
|
||||
};
|
||||
|
||||
/* clang-format off */
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
FN(map_lookup_elem), \
|
||||
FN(map_update_elem), \
|
||||
FN(map_delete_elem), \
|
||||
FN(probe_read), \
|
||||
FN(ktime_get_ns), \
|
||||
FN(trace_printk), \
|
||||
FN(get_prandom_u32), \
|
||||
FN(get_smp_processor_id), \
|
||||
FN(skb_store_bytes), \
|
||||
FN(l3_csum_replace), \
|
||||
FN(l4_csum_replace), \
|
||||
FN(tail_call), \
|
||||
FN(clone_redirect), \
|
||||
FN(get_current_pid_tgid), \
|
||||
FN(get_current_uid_gid), \
|
||||
FN(get_current_comm), \
|
||||
FN(get_cgroup_classid), \
|
||||
FN(skb_vlan_push), \
|
||||
FN(skb_vlan_pop), \
|
||||
FN(skb_get_tunnel_key), \
|
||||
FN(skb_set_tunnel_key), \
|
||||
FN(perf_event_read), \
|
||||
FN(redirect), \
|
||||
FN(get_route_realm), \
|
||||
FN(perf_event_output), \
|
||||
FN(skb_load_bytes), \
|
||||
FN(get_stackid), \
|
||||
FN(csum_diff), \
|
||||
FN(skb_get_tunnel_opt), \
|
||||
FN(skb_set_tunnel_opt), \
|
||||
FN(skb_change_proto), \
|
||||
FN(skb_change_type), \
|
||||
FN(skb_under_cgroup), \
|
||||
FN(get_hash_recalc), \
|
||||
FN(get_current_task), \
|
||||
FN(probe_write_user), \
|
||||
FN(current_task_under_cgroup), \
|
||||
FN(skb_change_tail), \
|
||||
FN(skb_pull_data), \
|
||||
FN(csum_update), \
|
||||
FN(set_hash_invalid), \
|
||||
FN(get_numa_node_id), \
|
||||
FN(skb_change_head), \
|
||||
FN(xdp_adjust_head), \
|
||||
FN(probe_read_str), \
|
||||
FN(get_socket_cookie), \
|
||||
FN(get_socket_uid), \
|
||||
FN(set_hash), \
|
||||
FN(setsockopt), \
|
||||
FN(skb_adjust_room), \
|
||||
FN(redirect_map), \
|
||||
FN(sk_redirect_map), \
|
||||
FN(sock_map_update), \
|
||||
FN(xdp_adjust_meta), \
|
||||
FN(perf_event_read_value), \
|
||||
FN(perf_prog_read_value), \
|
||||
FN(getsockopt), \
|
||||
FN(override_return), \
|
||||
FN(sock_ops_cb_flags_set), \
|
||||
FN(msg_redirect_map), \
|
||||
FN(msg_apply_bytes), \
|
||||
FN(msg_cork_bytes), \
|
||||
FN(msg_pull_data), \
|
||||
FN(bind), \
|
||||
FN(xdp_adjust_tail), \
|
||||
FN(skb_get_xfrm_state), \
|
||||
FN(get_stack), \
|
||||
FN(skb_load_bytes_relative), \
|
||||
FN(fib_lookup), \
|
||||
FN(sock_hash_update), \
|
||||
FN(msg_redirect_hash), \
|
||||
FN(sk_redirect_hash), \
|
||||
FN(lwt_push_encap), \
|
||||
FN(lwt_seg6_store_bytes), \
|
||||
FN(lwt_seg6_adjust_srh), \
|
||||
FN(lwt_seg6_action), \
|
||||
FN(rc_repeat), \
|
||||
FN(rc_keydown), \
|
||||
FN(skb_cgroup_id), \
|
||||
FN(get_current_cgroup_id), \
|
||||
FN(get_local_storage), \
|
||||
FN(sk_select_reuseport), \
|
||||
FN(skb_ancestor_cgroup_id), \
|
||||
FN(sk_lookup_tcp), \
|
||||
FN(sk_lookup_udp), \
|
||||
FN(sk_release), \
|
||||
FN(map_push_elem), \
|
||||
FN(map_pop_elem), \
|
||||
FN(map_peek_elem), \
|
||||
FN(msg_push_data), \
|
||||
FN(msg_pop_data), \
|
||||
FN(rc_pointer_rel), \
|
||||
FN(spin_lock), \
|
||||
FN(spin_unlock), \
|
||||
FN(sk_fullsock), \
|
||||
FN(tcp_sock), \
|
||||
FN(skb_ecn_set_ce), \
|
||||
FN(get_listener_sock), \
|
||||
FN(skc_lookup_tcp), \
|
||||
FN(tcp_check_syncookie), \
|
||||
FN(sysctl_get_name), \
|
||||
FN(sysctl_get_current_value), \
|
||||
FN(sysctl_get_new_value), \
|
||||
FN(sysctl_set_new_value), \
|
||||
FN(strtol), \
|
||||
FN(strtoul), \
|
||||
FN(sk_storage_get), \
|
||||
FN(sk_storage_delete), \
|
||||
FN(send_signal), \
|
||||
FN(tcp_gen_syncookie), \
|
||||
FN(skb_output), \
|
||||
FN(probe_read_user), \
|
||||
FN(probe_read_kernel), \
|
||||
FN(probe_read_user_str), \
|
||||
FN(probe_read_kernel_str), \
|
||||
FN(tcp_send_ack), \
|
||||
FN(send_signal_thread), \
|
||||
FN(jiffies64), \
|
||||
FN(read_branch_records), \
|
||||
FN(get_ns_current_pid_tgid), \
|
||||
FN(xdp_output), \
|
||||
FN(get_netns_cookie), \
|
||||
FN(get_current_ancestor_cgroup_id), \
|
||||
FN(sk_assign), \
|
||||
FN(ktime_get_boot_ns), \
|
||||
FN(seq_printf), \
|
||||
FN(seq_write), \
|
||||
FN(sk_cgroup_id), \
|
||||
FN(sk_ancestor_cgroup_id), \
|
||||
FN(ringbuf_output), \
|
||||
FN(ringbuf_reserve), \
|
||||
FN(ringbuf_submit), \
|
||||
FN(ringbuf_discard), \
|
||||
FN(ringbuf_query), \
|
||||
FN(csum_level), \
|
||||
FN(skc_to_tcp6_sock), \
|
||||
FN(skc_to_tcp_sock), \
|
||||
FN(skc_to_tcp_timewait_sock), \
|
||||
FN(skc_to_tcp_request_sock), \
|
||||
FN(skc_to_udp6_sock), \
|
||||
FN(get_task_stack), \
|
||||
FN(load_hdr_opt), \
|
||||
FN(store_hdr_opt), \
|
||||
FN(reserve_hdr_opt), \
|
||||
FN(inode_storage_get), \
|
||||
FN(inode_storage_delete), \
|
||||
FN(d_path), \
|
||||
FN(copy_from_user), \
|
||||
FN(snprintf_btf), \
|
||||
FN(seq_printf_btf), \
|
||||
FN(skb_cgroup_classid), \
|
||||
FN(redirect_neigh), \
|
||||
FN(per_cpu_ptr), \
|
||||
FN(this_cpu_ptr), \
|
||||
FN(redirect_peer), \
|
||||
FN(task_storage_get), \
|
||||
FN(task_storage_delete), \
|
||||
FN(get_current_task_btf), \
|
||||
FN(bprm_opts_set), \
|
||||
FN(ktime_get_coarse_ns), \
|
||||
FN(ima_inode_hash), \
|
||||
FN(sock_from_file), \
|
||||
FN(check_mtu), \
|
||||
FN(for_each_map_elem), \
|
||||
FN(snprintf), \
|
||||
FN(sys_bpf), \
|
||||
FN(btf_find_by_name_kind), \
|
||||
FN(sys_close), \
|
||||
/* clang-format on */
|
||||
|
||||
#define __BPF_ENUM_FN(x) BPF_FUNC_##x
|
||||
enum bpf_func_id {
|
||||
__BPF_FUNC_MAPPER(__BPF_ENUM_FN) __BPF_FUNC_MAX_ID,
|
||||
};
|
||||
#undef __BPF_ENUM_FN
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_BPF_H_ */
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
s="""
|
||||
BPF_SOCK_OPS_VOID,
|
||||
BPF_SOCK_OPS_TIMEOUT_INIT,
|
||||
BPF_SOCK_OPS_RWND_INIT,
|
||||
BPF_SOCK_OPS_TCP_CONNECT_CB,
|
||||
BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB,
|
||||
BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB,
|
||||
BPF_SOCK_OPS_NEEDS_ECN,
|
||||
BPF_SOCK_OPS_BASE_RTT,
|
||||
BPF_SOCK_OPS_RTO_CB,
|
||||
BPF_SOCK_OPS_RETRANS_CB,
|
||||
BPF_SOCK_OPS_STATE_CB,
|
||||
BPF_SOCK_OPS_TCP_LISTEN_CB,
|
||||
BPF_SOCK_OPS_RTT_CB,
|
||||
BPF_SOCK_OPS_PARSE_HDR_OPT_CB,
|
||||
BPF_SOCK_OPS_HDR_OPT_LEN_CB,
|
||||
BPF_SOCK_OPS_WRITE_HDR_OPT_CB,
|
||||
"""
|
||||
|
||||
i = 0
|
||||
for x in s.replace(',','').split():
|
||||
print("#define %s %d" % (x, i))
|
||||
i += 1
|
84
libc/calls/struct/ucontext-netbsd.internal.h
Normal file
84
libc/calls/struct/ucontext-netbsd.internal.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
// clang-format off
|
||||
#include "libc/calls/ucontext.h"
|
||||
|
||||
#define __UCONTEXT_SIZE 784
|
||||
#define _UC_SIGMASK 0x01
|
||||
#define _UC_STACK 0x02
|
||||
#define _UC_CPU 0x04
|
||||
#define _UC_FPU 0x08
|
||||
#define _UC_TLSBASE 0x00080000
|
||||
#define _UC_SETSTACK 0x00010000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
#define _UC_CLRSTACK 0x00020000
|
||||
|
||||
union sigval_netbsd {
|
||||
int32_t sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
struct sigset_netbsd {
|
||||
uint32_t __bits[4];
|
||||
};
|
||||
|
||||
struct stack_netbsd {
|
||||
void *ss_sp;
|
||||
size_t ss_size;
|
||||
int32_t ss_flags;
|
||||
};
|
||||
|
||||
struct mcontext_netbsd {
|
||||
union {
|
||||
struct {
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r12;
|
||||
uint64_t r13;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
uint64_t rbp;
|
||||
uint64_t rbx;
|
||||
uint64_t rax;
|
||||
uint64_t gs;
|
||||
uint64_t fs;
|
||||
uint64_t es;
|
||||
uint64_t ds;
|
||||
uint64_t trapno;
|
||||
uint64_t err;
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
};
|
||||
int64_t __gregs[26];
|
||||
};
|
||||
int64_t _mc_tlsbase;
|
||||
struct FpuState __fpregs;
|
||||
};
|
||||
|
||||
struct ucontext_netbsd {
|
||||
union {
|
||||
struct {
|
||||
uint32_t uc_flags; /* see _UC_* above */
|
||||
struct ucontext_netbsd *uc_link;
|
||||
struct sigset_netbsd uc_sigmask;
|
||||
struct stack_netbsd uc_stack;
|
||||
struct mcontext_netbsd uc_mcontext;
|
||||
};
|
||||
char __pad[__UCONTEXT_SIZE];
|
||||
};
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_UCONTEXT_NETBSD_INTERNAL_H_ */
|
|
@ -19,7 +19,11 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/once.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/symboliclink.h"
|
||||
#include "libc/nt/enum/tokeninformationclass.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
@ -27,27 +31,12 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/luid.h"
|
||||
#include "libc/nt/struct/tokenprivileges.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool g_can_symlink;
|
||||
__msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW;
|
||||
|
||||
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
const char *linkpath) {
|
||||
uint32_t flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
if (!g_can_symlink) return eacces();
|
||||
flags = isdirectory(target) ? kNtSymbolicLinkFlagDirectory : 0;
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
if (__mkntpath(target, target16) == -1) return -1;
|
||||
if (CreateSymbolicLink(linkpath16, target16, flags)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
|
||||
static textstartup bool EnableSymlink(void) {
|
||||
static bool AllowedToCreateSymlinks(void) {
|
||||
int64_t tok;
|
||||
struct NtLuid id;
|
||||
struct NtTokenPrivileges tp;
|
||||
|
@ -60,10 +49,45 @@ static textstartup bool EnableSymlink(void) {
|
|||
return GetLastError() != kNtErrorNotAllAssigned;
|
||||
}
|
||||
|
||||
static textstartup void g_can_symlink_init() {
|
||||
g_can_symlink = EnableSymlink();
|
||||
}
|
||||
textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
||||
const char *linkpath) {
|
||||
int targetlen;
|
||||
uint32_t attrs, flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
|
||||
const void *const g_can_symlink_ctor[] initarray = {
|
||||
g_can_symlink_init,
|
||||
};
|
||||
// convert the paths
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
if ((targetlen = __mkntpath(target, target16)) == -1) return -1;
|
||||
|
||||
// determine if we need directory flag
|
||||
if ((attrs = __imp_GetFileAttributesW(target16)) != -1u) {
|
||||
if (attrs & kNtFileAttributeDirectory) {
|
||||
flags = kNtSymbolicLinkFlagDirectory;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
} else {
|
||||
// win32 needs to know if it's a directory of a file symlink, but
|
||||
// that's hard to determine if we're creating a broken symlink so
|
||||
// we'll fall back to checking for trailing slash
|
||||
if (targetlen && target16[targetlen - 1] == '\\') {
|
||||
flags = kNtSymbolicLinkFlagDirectory;
|
||||
} else {
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// windows only lets administrators do this
|
||||
// even then we're required to ask for permission
|
||||
if (!_once(AllowedToCreateSymlinks())) {
|
||||
return eperm();
|
||||
}
|
||||
|
||||
// we can now proceed
|
||||
if (CreateSymbolicLink(linkpath16, target16, flags)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __fix_enotdir(-1, linkpath16);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* @param target can be relative and needn't exist
|
||||
* @param linkpath is what gets created
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @note Windows NT only lets admins do this
|
||||
* @raise EPERM if a non-admin on Windows NT tries to use this
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int symlinkat(const char *target, int newdirfd, const char *linkpath) {
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
#include "libc/nt/runtime.h"
|
||||
|
||||
textwindows int sys_truncate_nt(const char *path, uint64_t length) {
|
||||
int rc;
|
||||
bool32 ok;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL,
|
||||
kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1) {
|
||||
ok = sys_ftruncate_nt(fh, length);
|
||||
rc = sys_ftruncate_nt(fh, length);
|
||||
CloseHandle(fh);
|
||||
if (ok) return 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
return __winerr();
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -5,56 +5,6 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define REG_R8 REG_R8
|
||||
#define REG_R9 REG_R9
|
||||
#define REG_R10 REG_R10
|
||||
#define REG_R11 REG_R11
|
||||
#define REG_R12 REG_R12
|
||||
#define REG_R13 REG_R13
|
||||
#define REG_R14 REG_R14
|
||||
#define REG_R15 REG_R15
|
||||
#define REG_RDI REG_RDI
|
||||
#define REG_RSI REG_RSI
|
||||
#define REG_RBP REG_RBP
|
||||
#define REG_RBX REG_RBX
|
||||
#define REG_RDX REG_RDX
|
||||
#define REG_RAX REG_RAX
|
||||
#define REG_RCX REG_RCX
|
||||
#define REG_RSP REG_RSP
|
||||
#define REG_RIP REG_RIP
|
||||
#define REG_EFL REG_EFL
|
||||
#define REG_CSGSFS REG_CSGSFS
|
||||
#define REG_ERR REG_ERR
|
||||
#define REG_TRAPNO REG_TRAPNO
|
||||
#define REG_OLDMASK REG_OLDMASK
|
||||
#define REG_CR2 REG_CR2
|
||||
|
||||
enum GeneralRegister {
|
||||
REG_R8,
|
||||
REG_R9,
|
||||
REG_R10,
|
||||
REG_R11,
|
||||
REG_R12,
|
||||
REG_R13,
|
||||
REG_R14,
|
||||
REG_R15,
|
||||
REG_RDI,
|
||||
REG_RSI,
|
||||
REG_RBP,
|
||||
REG_RBX,
|
||||
REG_RDX,
|
||||
REG_RAX,
|
||||
REG_RCX,
|
||||
REG_RSP,
|
||||
REG_RIP,
|
||||
REG_EFL,
|
||||
REG_CSGSFS,
|
||||
REG_ERR,
|
||||
REG_TRAPNO,
|
||||
REG_OLDMASK,
|
||||
REG_CR2
|
||||
};
|
||||
|
||||
struct XmmRegister {
|
||||
uint64_t u64[2];
|
||||
};
|
||||
|
|
|
@ -140,5 +140,5 @@ textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
|
|||
// rc = SyncDirectory(dirfd, path16, n);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return __fix_enotdir(rc, path16);
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include "libc/time/time.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_utimensat_linux 0x118 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
||||
int flags) {
|
||||
int rc, olderr;
|
||||
|
@ -35,8 +33,7 @@ int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
|||
if (!IsXnu()) {
|
||||
olderr = errno;
|
||||
rc = __sys_utimensat(dirfd, path, ts, flags);
|
||||
if (((rc == -1 && errno == ENOSYS) || rc == __NR_utimensat_linux) &&
|
||||
dirfd == AT_FDCWD && !flags) {
|
||||
if ((rc == -1 && errno == ENOSYS) && dirfd == AT_FDCWD && !flags) {
|
||||
errno = olderr;
|
||||
if (ts) {
|
||||
tv[0].tv_sec = ts[0].tv_sec;
|
||||
|
|
|
@ -25,4 +25,4 @@
|
|||
*
|
||||
* By default no limit is imposed.
|
||||
*/
|
||||
size_t __virtualmax;
|
||||
size_t __virtualmax = -1;
|
||||
|
|
|
@ -16,22 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -44,16 +32,20 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
|
|||
_offset2overlap(g_fds.p[fd].handle, offset, &overlap))) {
|
||||
return sent;
|
||||
}
|
||||
err = GetLastError();
|
||||
// make sure write() raises SIGPIPE on broken pipe
|
||||
// make sure write() raises SIGPIPE on closing named pipe
|
||||
if (err == kNtErrorBrokenPipe || err == kNtErrorNoData) {
|
||||
__sig_raise(SIGPIPE, SI_KERNEL);
|
||||
return epipe();
|
||||
switch (GetLastError()) {
|
||||
// case kNtErrorInvalidHandle:
|
||||
// return ebadf(); /* handled by consts.sh */
|
||||
// case kNtErrorNotEnoughQuota:
|
||||
// return edquot(); /* handled by consts.sh */
|
||||
case kNtErrorBrokenPipe: // broken pipe
|
||||
case kNtErrorNoData: // closing named pipe
|
||||
__sig_raise(SIGPIPE, SI_KERNEL); //
|
||||
return epipe(); //
|
||||
case kNtErrorAccessDenied: // write doesn't return EACCESS
|
||||
return ebadf(); //
|
||||
default:
|
||||
return __winerr();
|
||||
}
|
||||
// kNtErrorInvalidHandle → EBADF (consts.sh)
|
||||
// kNtErrorNotEnoughQuota → EDQUOT (consts.sh; SetProcessWorkingSetSize)
|
||||
return __winerr();
|
||||
}
|
||||
|
||||
textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue