diff --git a/libc/calls/calls.h b/libc/calls/calls.h index eb8f2f63b..7eac94776 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -155,7 +155,7 @@ int pipe(int[hasatleast 2]); int pipe2(int[hasatleast 2], int); int posix_fadvise(int, uint64_t, uint64_t, int); int posix_madvise(void *, uint64_t, int); -int prctl(); +int prctl(int, ...); int raise(int); int reboot(int); int remove(const char *); @@ -232,6 +232,7 @@ uint32_t umask(uint32_t); void rewinddir(DIR *); void sync(void); int getloadavg(double *, int); +int seccomp(unsigned, unsigned, void *); /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § system calls » formatting ─╬─│┼ diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 2708adc6a..f4d2157e4 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -83,6 +83,9 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: \ -O3 # TODO(jart): make va_arg optimize well in default mode +o//libc/calls/open.o \ +o//libc/calls/openat.o \ +o//libc/calls/prctl.o \ o//libc/calls/ioctl.o \ o//libc/calls/ioctl_default.o \ o//libc/calls/ioctl_fioclex-nt.o \ diff --git a/libc/calls/chdir-nt.c b/libc/calls/chdir-nt.c index 9cbc40b6d..be94dd304 100644 --- a/libc/calls/chdir-nt.c +++ b/libc/calls/chdir-nt.c @@ -76,5 +76,5 @@ textwindows int sys_chdir_nt(const char *path) { } } } - return -1; + return __fix_enotdir(-1, path16); } diff --git a/libc/calls/chdir.c b/libc/calls/chdir.c index 9498f2f97..0b42d5a95 100644 --- a/libc/calls/chdir.c +++ b/libc/calls/chdir.c @@ -32,7 +32,7 @@ */ int chdir(const char *path) { int rc; - if (IsAsan() && !__asan_is_valid(path, 1)) { + if (!path || (IsAsan() && !__asan_is_valid(path, 1))) { rc = efault(); } else if (!IsWindows()) { rc = sys_chdir(path); diff --git a/libc/calls/chroot.c b/libc/calls/chroot.c new file mode 100644 index 000000000..2f654f7a4 --- /dev/null +++ b/libc/calls/chroot.c @@ -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/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" + +/** + * Changes root directory. + * + * @raise ENOSYS on Windows + */ +int chroot(const char *path) { + int rc; + rc = sys_chroot(path); + STRACE("chroot(%s) → %d% m", path, rc); + return rc; +} diff --git a/libc/calls/directmap.c b/libc/calls/directmap.c index a8ecd85d3..6dcf9f03c 100644 --- a/libc/calls/directmap.c +++ b/libc/calls/directmap.c @@ -22,7 +22,6 @@ #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" /** @@ -32,6 +31,9 @@ * support Windows NT and Address Sanitizer. That memory tracking can be * bypassed by calling this function. However the caller is responsible * for passing the magic memory handle on Windows NT to CloseHandle(). + * + * @asyncsignalsafe + * @threadsafe */ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { diff --git a/libc/calls/faccessat-nt.c b/libc/calls/faccessat-nt.c index 1c8446184..c1c66d4da 100644 --- a/libc/calls/faccessat-nt.c +++ b/libc/calls/faccessat-nt.c @@ -24,5 +24,5 @@ int sys_faccessat_nt(int dirfd, const char *path, int mode, uint32_t flags) { char16_t path16[PATH_MAX]; if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; - return ntaccesscheck(path16, mode); + return __fix_enotdir(ntaccesscheck(path16, mode), path16); } diff --git a/libc/calls/fixenotdir.c b/libc/calls/fixenotdir.c new file mode 100644 index 000000000..37d6ecb9b --- /dev/null +++ b/libc/calls/fixenotdir.c @@ -0,0 +1,63 @@ +/*-*- 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/errno.h" +#include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/errors.h" +#include "libc/nt/files.h" + +static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) { + int e; + char16_t *p; + uint32_t attrs; + e = errno; + while ((p = strrchr16(path, '\\'))) { + *p = u'\0'; + if ((attrs = GetFileAttributes(path)) != -1u) { + if (attrs & kNtFileAttributeDirectory) { + return false; + } else { + return true; + } + } else { + errno = e; + } + } + return false; +} + +// 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 +// +// - ENOTDIR: A component used as a directory in pathname is not, in +// fact, a directory. -or- pathname is relative and dirfd is a file +// descriptor referring to a file other than a directory. +// +// - ENOENT: A directory component in pathname does not exist or is a +// 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; +} diff --git a/libc/calls/getrlimit.c b/libc/calls/getrlimit.c index 17f117bde..25bacf842 100644 --- a/libc/calls/getrlimit.c +++ b/libc/calls/getrlimit.c @@ -21,6 +21,7 @@ #include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/errfuns.h" /** @@ -36,10 +37,16 @@ int getrlimit(int resource, struct rlimit *rlim) { char buf[64]; if (resource == 127) { rc = einval(); - } else if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) { + } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { rc = efault(); - } else { + } else if (!IsWindows()) { rc = sys_getrlimit(resource, rlim); + } else if (resource == RLIMIT_AS) { + rlim->rlim_cur = __virtualmax; + rlim->rlim_max = __virtualmax; + rc = 0; + } else { + rc = einval(); } STRACE("getrlimit(%s, [%s]) → %d% m", __strace_rlimit_name(resource), __strace_rlimit(buf, sizeof(buf), rc, rlim), rc); diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 68ab4682b..16d3f64c9 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -5,6 +5,7 @@ #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/itimerval.h" #include "libc/calls/struct/metastat.internal.h" +#include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction-xnu.internal.h" #include "libc/calls/struct/siginfo-xnu.internal.h" @@ -133,6 +134,7 @@ i32 __sys_pipe2(i32[hasatleast 2], u32) 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; +i32 sys_chroot(const char *) hidden; i32 sys_clock_gettime(i32, struct timespec *) hidden; i32 sys_close(i32) hidden; i32 sys_dup(i32) hidden; @@ -310,6 +312,7 @@ int sys_sync_nt(void) hidden; int sys_sysinfo_nt(struct sysinfo *) hidden; int sys_truncate_nt(const char *, u64) hidden; int sys_unlinkat_nt(int, const char *, int) hidden; +int sys_setrlimit_nt(int, const struct rlimit *) hidden; int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden; int sys_utimes_nt(const char *, const struct timeval[2]) hidden; ssize_t sys_open_nt(int, const char *, u32, i32) dontdiscard hidden; @@ -322,6 +325,7 @@ int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden; │ cosmopolitan § syscalls » windows nt » support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +int64_t __fix_enotdir(int64_t, char16_t *) hidden; bool _check_interrupts(bool, struct Fd *) hidden; void _check_sigchld(void) hidden; void _check_sigalrm(void) hidden; diff --git a/libc/calls/issandboxed.h b/libc/calls/issandboxed.h new file mode 100644 index 000000000..c97f9ce59 --- /dev/null +++ b/libc/calls/issandboxed.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +extern bool __issandboxed; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_ISSANDBOXED_INTERNAL_H_ */ diff --git a/libc/calls/mkdirat-nt.c b/libc/calls/mkdirat-nt.c index ba3276624..b167b9b5b 100644 --- a/libc/calls/mkdirat-nt.c +++ b/libc/calls/mkdirat-nt.c @@ -17,50 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" -#include "libc/errno.h" -#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" -#include "libc/nt/runtime.h" -#include "libc/str/str.h" - -static textwindows bool SubpathExistsThatsNotDirectory(char16_t *path) { - int e; - char16_t *p; - uint32_t attrs; - e = errno; - while ((p = strrchr16(path, '\\'))) { - *p = u'\0'; - if ((attrs = GetFileAttributes(path)) != -1u) { - if (attrs & kNtFileAttributeDirectory) { - return false; - } else { - return true; - } - } else { - errno = e; - } - } - return false; -} textwindows int sys_mkdirat_nt(int dirfd, const char *path, uint32_t mode) { int e; char16_t *p, path16[PATH_MAX]; if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1; if (CreateDirectory(path16, 0)) return 0; - - // WIN32 doesn't distinguish between ENOTDIR and ENOENT - // - // - ENOTDIR: A component used as a directory in pathname is not, in - // fact, a directory. -or- pathname is relative and dirfd is a file - // descriptor referring to a file other than a directory. - // - // - ENOENT: A directory component in pathname does not exist or is a - // dangling symbolic link. - if (errno == ENOTDIR) { - if (!SubpathExistsThatsNotDirectory(path16)) { - errno = ENOENT; - } - } - return -1; + return __fix_enotdir(-1, path16); } diff --git a/libc/calls/munmap-sysv.c b/libc/calls/munmap-sysv.c index cbb9a186d..db622bd1b 100644 --- a/libc/calls/munmap-sysv.c +++ b/libc/calls/munmap-sysv.c @@ -19,8 +19,16 @@ #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. + * + * This function bypasses memtrack. Therefore it won't work on Windows, + * but it works on everything else including bare metal. + * + * @asyncsignalsafe + * @threadsafe + */ int sys_munmap(void *p, size_t n) { int rc; if (!IsMetal()) { diff --git a/libc/calls/open-nt.c b/libc/calls/open-nt.c index 6fcc16a41..1955a5d18 100644 --- a/libc/calls/open-nt.c +++ b/libc/calls/open-nt.c @@ -42,7 +42,9 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path, uint32_t perm, share, disp, attr; if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1; if (GetNtOpenFlags(flags, mode, &perm, &share, &disp, &attr) == -1) return -1; - return CreateFile(path16, perm, share, &kNtIsInheritable, disp, attr, 0); + return __fix_enotdir( + CreateFile(path16, perm, share, &kNtIsInheritable, disp, attr, 0), + path16); } static textwindows ssize_t sys_open_nt_console(int dirfd, diff --git a/libc/calls/poll.c b/libc/calls/poll.c index 360ca5901..acada2c86 100644 --- a/libc/calls/poll.c +++ b/libc/calls/poll.c @@ -87,11 +87,13 @@ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) { if (rc == -1 && errno == EFAULT) { STRACE("poll(%p, %'lu, %'d) → %d% lm", fds, nfds, timeout_ms, rc); } else { + char flagbuf[2][64]; kprintf(STRACE_PROLOGUE "poll({"); for (i = 0; i < MIN(5, nfds); ++i) { - kprintf("%s{%d,%s,%s}", i ? ", " : "", fds[i].fd, - DescribePollFlags(fds[i].events), - DescribePollFlags(fds[i].revents)); + kprintf( + "%s{%d, %s, %s}", i ? ", " : "", fds[i].fd, + DescribePollFlags(flagbuf[0], sizeof(flagbuf[0]), fds[i].events), + DescribePollFlags(flagbuf[1], sizeof(flagbuf[1]), fds[i].revents)); } kprintf("%s}, %'zu, %'d) → %d% lm%n", i == 5 ? "..." : "", nfds, timeout_ms, rc); diff --git a/libc/calls/prctl.c b/libc/calls/prctl.c new file mode 100644 index 000000000..ed82bcf45 --- /dev/null +++ b/libc/calls/prctl.c @@ -0,0 +1,52 @@ +/*-*- 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" +#include "libc/calls/strace.internal.h" +#include "libc/errno.h" +#include "libc/sysv/errfuns.h" + +/** + * Tunes process on Linux. + * + * @raise ENOSYS on non-Linux. + */ +int prctl(int operation, ...) { + int rc; + va_list va; + intptr_t a, b; + register intptr_t c asm("r10"); + register intptr_t d asm("r8"); + va_start(va, operation); + a = va_arg(va, intptr_t); + b = va_arg(va, intptr_t); + c = va_arg(va, intptr_t); + d = va_arg(va, intptr_t); + va_end(va); + if (IsLinux()) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(operation), "S"(a), "d"(b), "r"(c), "r"(d) + : "rcx", "r11", "memory"); + if (rc > -4096u) errno = -rc, rc = -1; + } else { + rc = enosys(); + } + STRACE("seccomp(%d, %p, %p, %p, %p) → %d% m", operation, a, b, c, d, rc); + return rc; +} diff --git a/libc/calls/pread.c b/libc/calls/pread.c index a65ff0fe2..3fe6d679f 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -56,7 +56,7 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { rc = ebadf(); } assert(rc == -1 || (size_t)rc <= size); - STRACE("pread(%d, [%#.*hhs%s], %'zu, %'zd) → %'zd% m", fd, - MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc); + DATATRACE("pread(%d, [%#.*hhs%s], %'zu, %'zd) → %'zd% m", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc); return rc; } diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index dba5fdfa1..45bc53219 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -58,7 +58,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { assert(wrote <= size); } } - STRACE("pwrite(%d, %#.*hhs%s, %'zu, %'zd) → %'zd% m", fd, MAX(0, MIN(40, rc)), - buf, rc > 40 ? "..." : "", size, offset, rc); + DATATRACE("pwrite(%d, %#.*hhs%s, %'zu, %'zd) → %'zd% m", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, offset, rc); return rc; } diff --git a/libc/calls/read.c b/libc/calls/read.c index f8ff698d4..31ffff570 100644 --- a/libc/calls/read.c +++ b/libc/calls/read.c @@ -62,7 +62,7 @@ ssize_t read(int fd, void *buf, size_t size) { } else { rc = einval(); } - STRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), buf, - rc > 40 ? "..." : "", size, rc); + DATATRACE("read(%d, [%#.*hhs%s], %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), + buf, rc > 40 ? "..." : "", size, rc); return rc; } diff --git a/libc/calls/readv.c b/libc/calls/readv.c index de6d3df0f..47492ffcf 100644 --- a/libc/calls/readv.c +++ b/libc/calls/readv.c @@ -22,6 +22,7 @@ #include "libc/calls/strace.internal.h" #include "libc/calls/struct/iovec.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -40,7 +41,9 @@ * @restartable */ ssize_t readv(int fd, const struct iovec *iov, int iovlen) { - ssize_t rc; + int i; + ssize_t rc, rem; + if (fd >= 0 && iovlen >= 0) { if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) { rc = efault(); @@ -63,6 +66,27 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) { } else { rc = einval(); } - STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + } else { + rem = rc != -1 ? rc : 0; + kprintf(STRACE_PROLOGUE "readv(%d, [{", fd); + for (i = 0; i < MIN(5, iovlen); ++i) { + kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "", + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base, + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len + ? "..." + : "", + iov[i].iov_len); + rem -= iov[i].iov_len; + } + kprintf("%s}], %d) → %'ld% m%n", iovlen > 5 ? "..." : "", iovlen, rc); + } + } +#endif + return rc; } diff --git a/libc/calls/seccomp.c b/libc/calls/seccomp.c new file mode 100644 index 000000000..5f3a7d4a6 --- /dev/null +++ b/libc/calls/seccomp.c @@ -0,0 +1,69 @@ +/*-*- 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" +#include "libc/calls/issandboxed.h" +#include "libc/calls/strace.internal.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/describeflags.internal.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/consts/seccomp.h" +#include "libc/sysv/errfuns.h" + +/** + * Tunes Linux security policy. + * + * This system call was first introduced in Linux 3.17. We polyfill + * automatically features like SECCOMP_SET_MODE_STRICT, for kernels + * dating back to 2.6.23, whenever possible. + * + * @raise ENOSYS on non-Linux. + */ +int seccomp(unsigned operation, unsigned flags, void *args) { + int rc; + if (IsLinux()) { + asm volatile("syscall" + : "=a"(rc) + : "0"(317), "D"(operation), "S"(flags), "d"(args) + : "rcx", "r11", "memory"); + if (rc == -ENOSYS) { + if (operation == SECCOMP_SET_MODE_STRICT) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(PR_SET_SECCOMP), "S"(SECCOMP_MODE_STRICT) + : "rcx", "r11", "memory"); + } else if (operation == SECCOMP_SET_MODE_FILTER && !flags) { + asm volatile("syscall" + : "=a"(rc) + : "0"(157), "D"(PR_SET_SECCOMP), "S"(SECCOMP_MODE_FILTER), + "d"(args) + : "rcx", "r11", "memory"); + } + } + if (rc > -4096u) { + errno = -rc; + rc = -1; + } + } else { + rc = enosys(); + } + STRACE("seccomp(%s, %#x, %p) → %d% m", + DescribeSeccompOperationFlags(operation), flags, args, rc); + return rc; +} diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index ae9e2b121..77127136f 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -16,17 +16,39 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/strace.internal.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/errfuns.h" /** * Sets resource limit for current process. * - * @param resource can be RLIMIT_{CPU,FSIZE,DATA,STACK,CORE,RSS,etc.} + * The following resources are recommended: + * + * - `RLIMIT_AS` limits the size of the virtual address space. This will + * work on all platforms. It's emulated on XNU and Windows which means + * it won't propagate across execve() currently. + * + * - `RLIMIT_CPU` causes `SIGXCPU` to be sent to the process when the + * soft limit on CPU time is exceeded, and the process is destroyed + * when the hard limit is exceeded. It works everywhere but Windows + * where it should be possible to poll getrusage() with setitimer() + * + * - `RLIMIT_FSIZE` causes `SIGXFSZ` to sent to the process when the + * soft limit on file size is exceeded and the process is destroyed + * 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. + * + * - `RLIMIT_NOFILE` limits the number of open file descriptors and it + * should work on all platforms except Windows (TODO) + * * @param rlim specifies new resource limit * @return 0 on success or -1 w/ errno * @see libc/sysv/consts.sh @@ -37,10 +59,19 @@ int setrlimit(int resource, const struct rlimit *rlim) { char buf[64]; if (resource == 127) { rc = einval(); - } else if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) { + } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { rc = efault(); - } else { + } else if (!IsWindows()) { rc = sys_setrlimit(resource, rlim); + if (IsXnu() && !rc && resource == RLIMIT_AS) { + // TODO(jart): What's up with XNU and NetBSD? + __virtualmax = rlim->rlim_cur; + } + } else if (resource == RLIMIT_AS) { + __virtualmax = rlim->rlim_cur; + rc = 0; + } else { + rc = einval(); } STRACE("setrlimit(%s, %s) → %d% m", __strace_rlimit_name(resource), __strace_rlimit(buf, sizeof(buf), 0, rlim), rc); diff --git a/libc/calls/stat2cosmo.c b/libc/calls/stat2cosmo.c index b6c76763b..c4e28281e 100644 --- a/libc/calls/stat2cosmo.c +++ b/libc/calls/stat2cosmo.c @@ -24,6 +24,10 @@ void __stat2cosmo(struct stat *restrict st, const union metastat *ms) { if (st) { if (IsLinux()) { st->st_birthtim = st->st_ctim; + if (st->st_atim.tv_sec < st->st_ctim.tv_sec) + st->st_birthtim = st->st_atim; + if (st->st_mtim.tv_sec < st->st_ctim.tv_sec) + st->st_birthtim = st->st_mtim; } else if (IsXnu()) { st->st_dev = ms->xnu.st_dev; st->st_ino = ms->xnu.st_ino; diff --git a/libc/calls/strace.internal.h b/libc/calls/strace.internal.h index e68041907..f3c86ab48 100644 --- a/libc/calls/strace.internal.h +++ b/libc/calls/strace.internal.h @@ -7,6 +7,7 @@ #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 STRACE_PROLOGUE "%rSYS %5P %'18T " @@ -25,6 +26,12 @@ COSMOPOLITAN_C_START_ #define STRACE(FMT, ...) (void)0 #endif +#if defined(SYSDEBUG) && _DATATRACE +#define DATATRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define DATATRACE(FMT, ...) (void)0 +#endif + #if defined(SYSDEBUG) && _POLLTRACE #define POLLTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) #else diff --git a/libc/calls/struct/seccomp.h b/libc/calls/struct/seccomp.h new file mode 100644 index 000000000..b5e57e9ef --- /dev/null +++ b/libc/calls/struct/seccomp.h @@ -0,0 +1,54 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct seccomp_data { + int32_t nr; + uint32_t arch; + uint64_t instruction_pointer; + uint64_t args[6]; +}; + +struct seccomp_notif_sizes { + uint16_t seccomp_notif; + uint16_t seccomp_notif_resp; + uint16_t seccomp_data; +}; + +struct seccomp_notif { + uint64_t id; + uint32_t pid; + uint32_t flags; + struct seccomp_data data; +}; + +struct seccomp_notif_resp { + uint64_t id; + int64_t val; + int32_t error; + uint32_t flags; +}; + +struct seccomp_notif_addfd { + uint64_t id; + uint32_t flags; + uint32_t srcfd; + uint32_t newfd; + uint32_t newfd_flags; +}; + +#define SECCOMP_IOC_MAGIC '!' +#define SECCOMP_IO(nr) _IO(SECCOMP_IOC_MAGIC, nr) +#define SECCOMP_IOR(nr, type) _IOR(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOW(nr, type) _IOW(SECCOMP_IOC_MAGIC, nr, type) +#define SECCOMP_IOWR(nr, type) _IOWR(SECCOMP_IOC_MAGIC, nr, type) + +#define SECCOMP_IOCTL_NOTIF_RECV SECCOMP_IOWR(0, struct seccomp_notif) +#define SECCOMP_IOCTL_NOTIF_SEND SECCOMP_IOWR(1, struct seccomp_notif_resp) +#define SECCOMP_IOCTL_NOTIF_ID_VALID SECCOMP_IOW(2, __u64) +#define SECCOMP_IOCTL_NOTIF_ADDFD SECCOMP_IOW(3, struct seccomp_notif_addfd) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SECCOMP_H_ */ diff --git a/libc/calls/virtualmax.c b/libc/calls/virtualmax.c new file mode 100644 index 000000000..7c8f8359e --- /dev/null +++ b/libc/calls/virtualmax.c @@ -0,0 +1,28 @@ +/*-*- 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" + +/** + * Maximum amount of virtual memory in bytes. + * + * mmap() will return ENOMEM once this is reached. + * + * By default no limit is imposed. + */ +size_t __virtualmax; diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index 839d4d956..737be07b9 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -51,6 +51,8 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size, __sig_raise(SIGPIPE, SI_KERNEL); return epipe(); } + // kNtErrorInvalidHandle → EBADF (consts.sh) + // kNtErrorNotEnoughQuota → EDQUOT (consts.sh; SetProcessWorkingSetSize) return __winerr(); } diff --git a/libc/calls/write.c b/libc/calls/write.c index 5942a338b..7bcc3a7d5 100644 --- a/libc/calls/write.c +++ b/libc/calls/write.c @@ -59,7 +59,7 @@ ssize_t write(int fd, const void *buf, size_t size) { } else { rc = einval(); } - STRACE("write(%d, %#.*hhs%s, %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), buf, - rc > 40 ? "..." : "", size, rc); + DATATRACE("write(%d, %#.*hhs%s, %'zu) → %'zd% m", fd, MAX(0, MIN(40, rc)), + buf, rc > 40 ? "..." : "", size, rc); return rc; } diff --git a/libc/calls/writev.c b/libc/calls/writev.c index ed6d465a1..fe17ab97a 100644 --- a/libc/calls/writev.c +++ b/libc/calls/writev.c @@ -20,7 +20,9 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/strace.internal.h" +#include "libc/errno.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/sock/internal.h" #include "libc/sysv/errfuns.h" #include "libc/zipos/zipos.internal.h" @@ -44,7 +46,9 @@ * @restartable */ ssize_t writev(int fd, const struct iovec *iov, int iovlen) { - ssize_t rc; + int i; + ssize_t rc, rem; + if (fd >= 0 && iovlen >= 0) { if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) { rc = efault(); @@ -67,6 +71,27 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) { } else { rc = einval(); } - STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + +#if defined(SYSDEBUG) && _DATATRACE + if (__strace > 0) { + if (rc == -1 && errno == EFAULT) { + STRACE("writev(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc); + } else { + rem = rc != -1 ? rc : 0; + kprintf(STRACE_PROLOGUE "writev(%d, {", fd); + for (i = 0; i < MIN(5, iovlen); ++i) { + kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "", + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))), iov[i].iov_base, + MAX(0, MIN(40, MIN(rem, iov[i].iov_len))) < iov[i].iov_len + ? "..." + : "", + iov[i].iov_len); + rem -= iov[i].iov_len; + } + kprintf("%s}, %d) → %'ld% m%n", iovlen > 5 ? "..." : "", iovlen, rc); + } + } +#endif + return rc; } diff --git a/libc/fmt/kerrornames.S b/libc/fmt/kerrornames.S index 6903d755c..6755891c0 100644 --- a/libc/fmt/kerrornames.S +++ b/libc/fmt/kerrornames.S @@ -115,6 +115,7 @@ kErrorNames: .e ENOTRECOVERABLE .e ENONET .e ERESTART + .e ENODATA .long 0 .endobj kErrorNames,globl,hidden .overrun diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.internal.h index ca790046a..ed6259b70 100644 --- a/libc/intrin/describeflags.internal.h +++ b/libc/intrin/describeflags.internal.h @@ -14,8 +14,9 @@ const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t, const char *DescribeMapFlags(int); const char *DescribeProtFlags(int); -const char *DescribePollFlags(int); const char *DescribeRemapFlags(int); +const char *DescribeSeccompOperationFlags(int); +const char *DescribePollFlags(char *, size_t, int); const char *DescribeNtPageFlags(uint32_t); const char *DescribeNtStartFlags(uint32_t); diff --git a/libc/intrin/describepollflags.greg.c b/libc/intrin/describepollflags.greg.c index 2e2a4d8a0..c1c868e51 100644 --- a/libc/intrin/describepollflags.greg.c +++ b/libc/intrin/describepollflags.greg.c @@ -21,7 +21,7 @@ #include "libc/nt/enum/filemapflags.h" #include "libc/sysv/consts/poll.h" -const char *DescribePollFlags(int x) { +const char *DescribePollFlags(char *buf, size_t size, int x) { const struct DescribeFlags kPollFlags[] = { {POLLIN, "IN"}, // order matters {POLLOUT, "OUT"}, // order matters @@ -35,7 +35,5 @@ const char *DescribePollFlags(int x) { {POLLWRBAND, "WRBAND"}, // {POLLWRNORM, "WRNORM"}, // }; - static char pollflags[64]; - return DescribeFlags(pollflags, sizeof(pollflags), kPollFlags, - ARRAYLEN(kPollFlags), "POLL", x); + return DescribeFlags(buf, size, kPollFlags, ARRAYLEN(kPollFlags), "POLL", x); } diff --git a/libc/intrin/describeseccompoperationflags.greg.c b/libc/intrin/describeseccompoperationflags.greg.c new file mode 100644 index 000000000..841fdad2e --- /dev/null +++ b/libc/intrin/describeseccompoperationflags.greg.c @@ -0,0 +1,35 @@ +/*-*- 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/sysv/consts/seccomp.h" + +const struct DescribeFlags kSeccompOperationFlags[] = { + {SECCOMP_GET_NOTIF_SIZES, "GET_NOTIF_SIZES"}, // order matters + {SECCOMP_GET_ACTION_AVAIL, "GET_ACTION_AVAIL"}, // + {SECCOMP_SET_MODE_FILTER, "SET_MODE_FILTER"}, // + {SECCOMP_SET_MODE_STRICT, "SET_MODE_STRICT"}, // +}; + +const char *DescribeSeccompOperationFlags(int x) { + static char seccompflags[128]; + return DescribeFlags(seccompflags, sizeof(seccompflags), + kSeccompOperationFlags, ARRAYLEN(kSeccompOperationFlags), + "SECCOMP_", x); +} diff --git a/libc/intrin/exit.greg.c b/libc/intrin/exit.greg.c index 1e3d47615..72d7a637d 100644 --- a/libc/intrin/exit.greg.c +++ b/libc/intrin/exit.greg.c @@ -21,6 +21,7 @@ #include "libc/dce.h" #include "libc/nexgen32e/vendor.internal.h" #include "libc/nt/runtime.h" +#include "libc/runtime/runtime.h" #include "libc/sysv/consts/nr.h" /** @@ -31,17 +32,18 @@ * * @param exitcode is masked with 255 * @asyncsignalsafe + * @threadsafe * @vforksafe * @noreturn */ -privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) { +privileged wontreturn void _Exit(int exitcode) { int i; STRACE("_Exit(%d)", exitcode); if (!IsWindows() && !IsMetal()) { asm volatile("syscall" : /* no outputs */ : "a"(__NR_exit_group), "D"(exitcode) - : "memory"); + : "rcx", "r11", "memory"); } else if (IsWindows()) { __imp_ExitProcess(exitcode & 0xff); } diff --git a/libc/intrin/exit1.greg.c b/libc/intrin/exit1.greg.c new file mode 100644 index 000000000..cbe1ed625 --- /dev/null +++ b/libc/intrin/exit1.greg.c @@ -0,0 +1,47 @@ +/*-*- 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 │ +│ │ +│ 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/strace.internal.h" +#include "libc/dce.h" +#include "libc/nt/runtime.h" +#include "libc/nt/thread.h" +#include "libc/sysv/consts/nr.h" + +/** + * Terminates thread with raw system call. + * + * @param rc only works on Linux and Windows + * @see cthread_exit() + * @threadsafe + * @noreturn + */ +privileged wontreturn void _Exit1(int rc) { + STRACE("_Exit1(%d)", rc); + if (!IsWindows() && !IsMetal()) { + asm volatile("syscall" + : /* no outputs */ + : "a"(__NR_exit), "D"(IsLinux() ? rc : 0) + : "rcx", "r11", "memory"); + __builtin_unreachable(); + } else if (IsWindows()) { + ExitThread(rc); + } + for (;;) { + asm("ud2"); + } +} diff --git a/libc/intrin/intrin.mk b/libc/intrin/intrin.mk index 502d6a9ff..9a6235214 100644 --- a/libc/intrin/intrin.mk +++ b/libc/intrin/intrin.mk @@ -64,6 +64,8 @@ o/$(MODE)/libc/intrin/kprintf.greg.o: \ -ffreestanding \ $(NO_MAGIC) +o/$(MODE)/libc/intrin/exit.greg.o \ +o/$(MODE)/libc/intrin/exit1.greg.o \ o/$(MODE)/libc/intrin/createfile.greg.o \ o/$(MODE)/libc/intrin/reopenfile.greg.o \ o/$(MODE)/libc/intrin/deletefile.greg.o \ diff --git a/libc/intrin/isdebuggerpresent.greg.c b/libc/intrin/isdebuggerpresent.greg.c index a786d8b62..b248d88ec 100644 --- a/libc/intrin/isdebuggerpresent.greg.c +++ b/libc/intrin/isdebuggerpresent.greg.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/issandboxed.h" #include "libc/dce.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" @@ -35,24 +36,20 @@ noasan noubsan int IsDebuggerPresent(bool force) { int fd, res; ssize_t got; char *p, buf[1024]; - if (!force) { - if (IsGenuineCosmo()) return 0; - if (getenv("HEISENDEBUG")) return 0; - } - if (IsWindows()) { - return NtGetPeb()->BeingDebugged; /* needs noasan */ - } else { - res = 0; - if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) { - if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) { - buf[got] = '\0'; - if ((p = __strstr(buf, kPid))) { - p += sizeof(kPid) - 1; - res = __atoul(p); - } + if (!force && IsGenuineCosmo()) return 0; + if (!force && getenv("HEISENDEBUG")) return 0; + if (IsWindows()) return NtGetPeb()->BeingDebugged; /* needs noasan */ + if (__issandboxed) return false; + res = 0; + if ((fd = __sysv_open("/proc/self/status", O_RDONLY, 0)) >= 0) { + if ((got = __sysv_read(fd, buf, sizeof(buf) - 1)) > 0) { + buf[got] = '\0'; + if ((p = __strstr(buf, kPid))) { + p += sizeof(kPid) - 1; + res = __atoul(p); } - __sysv_close(fd); } - return res; + __sysv_close(fd); } + return res; } diff --git a/libc/intrin/issandboxed.c b/libc/intrin/issandboxed.c new file mode 100644 index 000000000..85fb44282 --- /dev/null +++ b/libc/intrin/issandboxed.c @@ -0,0 +1,22 @@ +/*-*- 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" + +// SECCOMP_SET_MODE_STRICT +bool __issandboxed; diff --git a/libc/intrin/kdos2errno.S b/libc/intrin/kdos2errno.S index 4fb064a93..f15e02f7f 100644 --- a/libc/intrin/kdos2errno.S +++ b/libc/intrin/kdos2errno.S @@ -33,9 +33,12 @@ kDos2Errno: // .e kNtErrorFileNotFound,ENOENT # in consts.sh // .e kNtErrorPathNotFound,ENOTDIR # in consts.sh // .e kNtErrorTooManyOpenFiles,EMFILE # in consts.sh +// .e kNtErrorTooManyDescriptors,ENFILE # in consts.sh +// .e kNtErrorTooManyLinks,EMLINK # in consts.sh // .e kNtErrorAccessDenied,EACCES # in consts.sh // .e kNtErrorInvalidHandle,EBADF # in consts.sh // .e kNtErrorInvalidAccess,EPERM # in consts.sh +// .e kNtErrorNotEnoughQuota,EDQUOT # in consts.sh // .e kNtErrorSeek,ESPIPE # in consts.sh // .e kNtErrorNotDosDisk,ENOTBLK # in consts.sh // .e kNtErrorFileExists,EEXIST # in consts.sh @@ -48,7 +51,6 @@ kDos2Errno: // .e kNtErrorAlreadyExists,EEXIST # in consts.sh // .e kNtErrorBadExeFormat,ENOEXEC # in consts.sh // .e kNtErrorFileTooLarge,EFBIG # in consts.sh -// .e kNtErrorTooManyDescriptors,ENFILE # in consts.sh // .e kNtErrorDirectoryNotSupported,EISDIR # in consts.sh // .e kNtErrorInvalidAddress,EFAULT # in consts.sh // .e kNtErrorThreadNotInProcess,ESRCH # in consts.sh @@ -160,6 +162,7 @@ kDos2Errno: .e WSAEDISCON,EPIPE .e WSAEFAULT,EFAULT .e WSAEINVAL,EINVAL + .e WSAEDQUOT,EDQUOT .e WSAEPROCLIM,ENOMEM .e WSANOTINITIALISED,ENETDOWN .e WSASYSNOTREADY,ENETDOWN diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index 0fea1c979..97f73a2c6 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -21,6 +21,7 @@ #include "libc/bits/safemacros.internal.h" #include "libc/bits/weaken.h" #include "libc/calls/calls.h" +#include "libc/calls/issandboxed.h" #include "libc/calls/sigbits.h" #include "libc/calls/strace.internal.h" #include "libc/dce.h" @@ -159,7 +160,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { } static int PrintBacktrace(int fd, const struct StackFrame *bp) { - if (!IsTiny()) { + if (!IsTiny() && !__issandboxed) { if (PrintBacktraceUsingAddr2line(fd, bp) != -1) { return 0; } diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index 8a8d1e8f6..b55773594 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -17,7 +17,9 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" +#include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/issandboxed.h" #include "libc/calls/sigbits.h" #include "libc/calls/strace.internal.h" #include "libc/calls/struct/sigaction.h" @@ -198,8 +200,10 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, names.version[0] = 0; names.nodename[0] = 0; __stpcpy(host, "unknown"); - gethostname(host, sizeof(host)); - uname(&names); + if (!__issandboxed) { + gethostname(host, sizeof(host)); + uname(&names); + } p = buf; errno = err; kprintf("%n%serror%s: Uncaught %G (%s) on %s pid %d%n" @@ -211,8 +215,8 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) ? "Stack Overflow" : GetSiCodeName(sig, si->si_code), - host, __getpid(), program_invocation_name, names.sysname, - names.version, names.nodename, names.release); + host, getpid(), program_invocation_name, names.sysname, names.version, + names.nodename, names.release); if (ctx) { kprintf("%n"); ShowFunctionCalls(ctx); @@ -288,7 +292,8 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si, DebugBreak(); } else if (__nocolor || g_isrunningundermake) { gdbpid = -1; - } else if (!IsTiny() && IsLinux() && FindDebugBinary()) { + } else if (!IsTiny() && IsLinux() && FindDebugBinary() && + !__issandboxed) { RestoreDefaultCrashSignalHandlers(); gdbpid = AttachDebugger( ((sig == SIGTRAP || sig == SIGQUIT) && diff --git a/libc/log/restoretty.c b/libc/log/restoretty.c index 85ff62cfa..22134c463 100644 --- a/libc/log/restoretty.c +++ b/libc/log/restoretty.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/issandboxed.h" #include "libc/calls/struct/termios.h" #include "libc/calls/termios.h" #include "libc/errno.h" @@ -51,10 +52,12 @@ const void *const g_oldtermios_ctor[] initarray = { void __restore_tty(int fd) { int e; - e = errno; - if (g_oldtermios.c_lflag && !__nocolor && isatty(fd)) { - write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE)); - tcsetattr(fd, TCSAFLUSH, &g_oldtermios); + if (!__issandboxed) { + e = errno; + if (g_oldtermios.c_lflag && !__nocolor && isatty(fd)) { + write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE)); + tcsetattr(fd, TCSAFLUSH, &g_oldtermios); + } + errno = e; } - errno = e; } diff --git a/libc/nt/errors.h b/libc/nt/errors.h index d4edd0882..6a0301d39 100644 --- a/libc/nt/errors.h +++ b/libc/nt/errors.h @@ -194,7 +194,7 @@ #define kNtErrorEaListInconsistent 255 #define kNtErrorNoMoreItems 259 #define kNtErrorCannotCopy 266 -#define kNtErrorDirectory 267 +#define kNtErrorDirectory 267 /* EISDIR */ #define kNtErrorEasDidntFit 275 #define kNtErrorEaFileCorrupt 276 #define kNtErrorEaTableFull 277 @@ -238,7 +238,7 @@ #define kNtErrorNotRedundantStorage 333 #define kNtErrorResidentFileNotSupported 334 #define kNtErrorCompressedFileNotSupported 335 -#define kNtErrorDirectoryNotSupported 336 /* EISDIR */ +#define kNtErrorDirectoryNotSupported 336 #define kNtErrorNotReadFromCopy 337 #define kNtErrorFtWriteFailure 338 #define kNtErrorFtDiScanRequired 339 @@ -1102,7 +1102,7 @@ #define kNtErrorResourceTypeNotFound 1813 #define kNtErrorResourceNameNotFound 1814 #define kNtErrorResourceLangNotFound 1815 -#define kNtErrorNotEnoughQuota 1816 +#define kNtErrorNotEnoughQuota 1816 /* EDQUOT */ #define kNtErrorInvalidTime 1901 #define kNtErrorInvalidFormName 1902 #define kNtErrorInvalidFormSize 1903 diff --git a/libc/nt/kernel32/ExitThread.s b/libc/nt/kernel32/ExitThread.s new file mode 100644 index 000000000..575958455 --- /dev/null +++ b/libc/nt/kernel32/ExitThread.s @@ -0,0 +1,15 @@ +.include "o/libc/nt/codegen.inc" +.imp kernel32,__imp_ExitThread,ExitThread,0 + + .text.windows +ExitThread: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ExitThread(%rip) + leave + ret + .endfn ExitThread,globl + .previous diff --git a/libc/nt/master.sh b/libc/nt/master.sh index c70c1754b..0eaac8ade 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -303,6 +303,7 @@ imp 'EnumerateLocalComputerNamesA' EnumerateLocalComputerNamesA kernel32 3 imp 'EraseTape' EraseTape kernel32 352 imp 'EscapeCommFunction' EscapeCommFunction kernel32 0 imp 'ExecuteUmsThread' ExecuteUmsThread kernel32 354 +imp 'ExitThread' ExitThread kernel32 0 1 imp 'ExitProcess' ExitProcess kernel32 0 1 # a.k.a. RtlExitUserProcess imp 'ExitVDM' ExitVDM kernel32 357 imp 'ExpandEnvironmentStrings' ExpandEnvironmentStringsW kernel32 0 diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index b121faf67..821a0257f 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -87,13 +87,11 @@ privileged int clone(int (*f)(void *), void *stack, int flags, void *arg, ...) { if (ax) return ax; asm volatile("xor\t%%ebp,%%ebp\n\t" "pop\t%%rdi\n\t" - "call\t%1" - : "=a"(ax) - : "r"(func) - : "memory"); - asm volatile("syscall" + "call\t%0\n\t" + "xchg\t%%eax,%%edi\n\t" + "call\t_Exit1" : /* no outputs */ - : "a"(__NR_exit), "D"(ax) + : "r"(func) : "memory"); unreachable; } else if (IsWindows()) { diff --git a/libc/runtime/getsymboltable.c b/libc/runtime/getsymboltable.c index 354d42e01..9bd119970 100644 --- a/libc/runtime/getsymboltable.c +++ b/libc/runtime/getsymboltable.c @@ -19,6 +19,7 @@ #include "libc/assert.h" #include "libc/bits/bits.h" #include "libc/bits/weaken.h" +#include "libc/calls/issandboxed.h" #include "libc/calls/strace.internal.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" @@ -117,7 +118,7 @@ static struct SymbolTable *GetSymbolTableFromElf(void) { struct SymbolTable *GetSymbolTable(void) { int ft, st; struct Zipos *z; - if (!g_symtab) { + if (!g_symtab && !__issandboxed) { ft = g_ftrace, g_ftrace = 0; st = __strace, __strace = 0; if (weaken(__zipos_get) && (z = weaken(__zipos_get)())) { diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index bc7e69259..b22492e42 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -112,6 +112,14 @@ noasan static bool Automap(int n, int *res) { } } +noasan static size_t GetMemtrackSize(struct MemoryIntervals *mm) { + size_t i, n; + for (n = i = 0; i < mm->i; ++i) { + n += ((size_t)(mm->p[i].y - mm->p[i].x) + 1) << 16; + } + return n; +} + static noasan void *MapMemory(void *addr, size_t size, int prot, int flags, int fd, int64_t off, int f, int x, int n) { struct DirectMap dm; @@ -225,6 +233,7 @@ noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd, void *res; char *p = addr; struct DirectMap dm; + size_t virtualused, virtualneed; int a, b, i, f, m, n, x; if (UNLIKELY(!size)) { STRACE("size=0"); @@ -268,6 +277,13 @@ noasan void *mmap(void *addr, size_t size, int prot, int flags, int fd, } else if (__isfdkind(fd, kFdZip)) { STRACE("fd is zipos handle"); res = VIP(einval()); + } else if (__virtualmax && + (__builtin_add_overflow((virtualused = GetMemtrackSize(&_mmi)), + size, &virtualneed) || + virtualneed > __virtualmax)) { + STRACE("%'zu size + %'zu inuse exceeds virtual memory limit %'zu", size, + virtualused, __virtualmax); + res = VIP(enomem()); } else { if (fd == -1) { size = ROUNDUP(size, FRAMESIZE); diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 02ba9f5fd..d3e6baa78 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -38,6 +38,7 @@ extern unsigned char *__relo_end[]; /* αpε */ extern uint8_t __zip_start[]; /* αpε */ extern uint8_t __zip_end[]; /* αpε */ extern bool ftrace_enabled; +extern size_t __virtualmax; void mcount(void); unsigned long getauxval(unsigned long); @@ -49,6 +50,7 @@ void _longjmp(jmp_buf, int) libcesque wontreturn paramsnonnull(); void exit(int) wontreturn; void _exit(int) libcesque wontreturn; void _Exit(int) libcesque wontreturn; +void _Exit1(int) libcesque wontreturn; void quick_exit(int) wontreturn; void abort(void) wontreturn noinstrument; int __cxa_atexit(void *, void *, void *) libcesque; diff --git a/libc/sock/recv.c b/libc/sock/recv.c index 5136f3f2b..c818bcd83 100644 --- a/libc/sock/recv.c +++ b/libc/sock/recv.c @@ -58,7 +58,7 @@ ssize_t recv(int fd, void *buf, size_t size, int flags) { } else { rc = ebadf(); } - STRACE("recv(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, MAX(0, MIN(40, rc)), - buf, rc > 40 ? "..." : "", size, flags); + DATATRACE("recv(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags); return rc; } diff --git a/libc/sock/recvfrom.c b/libc/sock/recvfrom.c index f93c649cf..7dde89a4a 100644 --- a/libc/sock/recvfrom.c +++ b/libc/sock/recvfrom.c @@ -74,7 +74,7 @@ ssize_t recvfrom(int fd, void *buf, size_t size, uint32_t flags, } else { rc = ebadf(); } - STRACE("recvfrom(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, - MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, rc); + DATATRACE("recvfrom(%d, [%#.*hhs%s], %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, rc); return rc; } diff --git a/libc/sock/send.c b/libc/sock/send.c index 0fbb19cad..2fe9ae644 100644 --- a/libc/sock/send.c +++ b/libc/sock/send.c @@ -60,7 +60,7 @@ ssize_t send(int fd, const void *buf, size_t size, int flags) { } else { rc = ebadf(); } - STRACE("send(%d, %#.*hhs%s, %'zu, %#x) → %'ld% lm", fd, MAX(0, MIN(40, rc)), - buf, rc > 40 ? "..." : "", size, flags, rc); + DATATRACE("send(%d, %#.*hhs%s, %'zu, %#x) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, rc); return rc; } diff --git a/libc/sock/sendto.c b/libc/sock/sendto.c index 2bb77564f..3fcfb0023 100644 --- a/libc/sock/sendto.c +++ b/libc/sock/sendto.c @@ -87,8 +87,8 @@ ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags, rc = ebadf(); } } - STRACE("sendto(%d, %#.*hhs%s, %'zu, %#x, %p, %u) → %'ld% lm", fd, - MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, opt_addr, - addrsize, rc); + DATATRACE("sendto(%d, %#.*hhs%s, %'zu, %#x, %p, %u) → %'ld% lm", fd, + MAX(0, MIN(40, rc)), buf, rc > 40 ? "..." : "", size, flags, + opt_addr, addrsize, rc); return rc; } diff --git a/libc/sysv/calls/chroot.s b/libc/sysv/calls/chroot.s deleted file mode 100644 index 702d03be0..000000000 --- a/libc/sysv/calls/chroot.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall chroot,0x03d03d03d203d0a1,globl diff --git a/libc/sysv/calls/prctl.s b/libc/sysv/calls/prctl.s deleted file mode 100644 index 3fdf8080d..000000000 --- a/libc/sysv/calls/prctl.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall prctl,0xfffffffffffff09d,globl diff --git a/libc/sysv/calls/seccomp.s b/libc/sysv/calls/seccomp.s deleted file mode 100644 index bb6be8156..000000000 --- a/libc/sysv/calls/seccomp.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall seccomp,0xfffffffffffff13d,globl diff --git a/libc/sysv/calls/sys_chroot.s b/libc/sysv/calls/sys_chroot.s new file mode 100644 index 000000000..5e22b1782 --- /dev/null +++ b/libc/sysv/calls/sys_chroot.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_chroot,0x03d03d03d203d0a1,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 2cdaa1fc3..1a3c4037b 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -47,15 +47,15 @@ syscon errno ENOTDIR 20 20 20 20 20 3 # not a directory; unix co syscon errno EISDIR 21 21 21 21 21 267 # is a a directory; unix consensus; kNtErrorDirectory; raised by acct(2), copy_file_range(2), execve(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), open(2), read(2), rename(2), truncate(2), unlink(2) syscon errno EINVAL 22 22 22 22 22 87 # invalid argument; unix consensus; kNtErrorInvalidParameter; raised by accept(2), access(2), add_key(2), adjtimex(2), arch_prctl(2), bdflush(2), bind(2), bpf(2), cacheflush(2), capget(2), chmod(2), chown(2), clock_getres(2), clock_nanosleep(2), clone(2), copy_file_range(2), create_module(2), dup(2), epoll_create(2), epoll_ctl(2), epoll_wait(2), eventfd(2), execve(2), execveat(2), fallocate(2), fanotify_init(2), fanotify_mark(2), fcntl(2), flock(2), futex(2), get_mempolicy(2), get_robust_list(2), getdents(2), getdomainname(2), getgroups(2), gethostname(2), getitimer(2), getpeername(2), getpriority(2), getrandom(2), getrlimit(2), getrusage(2), getsockname(2), getsockopt(2), gettimeofday(2), init_module(2), inotify_add_watch(2), inotify_init(2), inotify_rm_watch(2), io_cancel(2), io_destroy(2), io_getevents(2), io_setup(2), io_submit(2), ioctl(2), ioctl_console(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), ioctl_getfsmap(2), ioctl_ns(2), ioctl_tty(2), ioctl_userfaultfd(2), ioperm(2), iopl(2), ioprio_set(2), kcmp(2), kexec_load(2), keyctl(2), kill(2), link(2), llseek(2), lookup_dcookie(2), lseek(2), madvise(2), mbind(2), membarrier(2), memfd_create(2), migrate_pages(2), mincore(2), mkdir(2), mknod(2), mlock(2), mmap(2), mmap2(2), modify_ldt(2), mount(2), move_pages(2), mprotect(2), mremap(2), msgctl(2), msgop(2), msync(2), nanosleep(2), open(2), open_by_handle_at(2), openat2(2), pciconfig_read(2), perf_event_open(2), personality(2), pidfd_getfd(2), pidfd_open(2), pidfd_send_signal(2), pipe(2), pivot_root(2), pkey_alloc(2), poll(2), posix_fadvise(2), prctl(2), process_vm_readv(2), ptrace(2), query_module(2), quotactl(2), read(2), readahead(2), readdir(2), readlink(2), readv(2), reboot(2), recv(2), recvmmsg(2), remap_file_pages(2), rename(2), request_key(2), rmdir(2), rt_sigqueueinfo(2), s390_guarded_storage(2), s390_pci_mmio_write(2), s390_runtime_instr(2), s390_sthyi(2), sched_get_priority_max(2), sched_rr_get_interval(2), sched_setaffinity(2), sched_setattr(2), sched_setparam(2), sched_setscheduler(2), seccomp(2), select(2), semctl(2), semget(2), semop(2), send(2), sendfile(2), set_mempolicy(2), set_thread_area(2), seteuid(2), setfsgid(2), setfsuid(2), setgid(2), setns(2), setpgid(2), setresuid(2), setreuid(2), setuid(2), shmctl(2), shmget(2), shmop(2), shutdown(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2), sigprocmask(2), sigsuspend(2), sigwaitinfo(2), socket(2), splice(2), spu_create(2), spu_run(2), stat(2), statx(2), subpage_prot(2), swapon(2), sync_file_range(2), sysfs(2), syslog(2), tee(2), timer_create(2), timer_delete(2), timer_getoverrun(2), timer_settime(2), timerfd_create(2), tkill(2), truncate(2), umount(2), unlink(2), unshare(2), userfaultfd(2), ustat(2), utimensat(2), vmsplice(2), wait(2), write(2), unix(7), ip(7) syscon errno ENFILE 23 23 23 23 23 331 # too many open files in system; unix consensus; kNtErrorTooManyDescriptors; raised by accept(2), acct(2), epoll_create(2), eventfd(2), execve(2), futex(2), inotify_init(2), memfd_create(2), mmap(2), open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), shmget(2), signalfd(2), socket(2), socketpair(2), spu_create(2), swapon(2), timerfd_create(2), uselib(2), userfaultfd(2) -syscon errno EMFILE 24 24 24 24 24 336 # too many open files; unix consensus; kNtErrorTooManyOpenFiles; raised by accept(2), dup(2), epoll_create(2), eventfd(2), execve(2), fanotify_init(2), fcntl(2), inotify_init(2), memfd_create(2), mount(2), open(2), perf_event_open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), signalfd(2), socket(2), socketpair(2), spu_create(2), timerfd_create(2) +syscon errno EMFILE 24 24 24 24 24 4 # too many open files; unix consensus; kNtErrorTooManyOpenFiles; raised by accept(2), dup(2), epoll_create(2), eventfd(2), execve(2), fanotify_init(2), fcntl(2), inotify_init(2), memfd_create(2), mount(2), open(2), perf_event_open(2), pidfd_getfd(2), pidfd_open(2), pipe(2), signalfd(2), socket(2), socketpair(2), spu_create(2), timerfd_create(2) syscon errno ENOTTY 25 25 25 25 25 1118 # inappropriate i/o control operation; unix consensus; kNtErrorSerialNoDevice; raised by ioctl(2), ioctl_console(2), ioctl_fat(2), ioctl_ns(2), ioctl_tty(2) syscon errno ETXTBSY 26 26 26 26 26 148 # won't open executable that's executing in write mode; try UnlockExecutable(); unix consensus; kNtErrorPathBusy; raised by access(2), copy_file_range(2), execve(2), fallocate(2), ioctl_ficlonerange(2), ioctl_fideduperange(2), mmap(2), open(2), truncate(2) syscon errno EFBIG 27 27 27 27 27 223 # file too large; unix consensus; kNtErrorFileTooLarge; raised by copy_file_range(2), fallocate(2), init_module(2), open(2), semop(2), truncate(2), write(2) syscon errno ENOSPC 28 28 28 28 28 39 # no space left on device; unix consensus; kNtErrorDiskFull; raised by copy_file_range(2), epoll_ctl(2), fallocate(2), fanotify_mark(2), fsync(2), inotify_add_watch(2), link(2), mkdir(2), mknod(2), msgget(2), open(2), perf_event_open(2), pkey_alloc(2), query_module(2), rename(2), semget(2), setxattr(2), shmget(2), spu_create(2), symlink(2), sync_file_range(2), write(2) -syscon errno EDQUOT 122 69 69 69 69 10069 # disk quota exceeded; bsd consensus; raised by add_key(2), keyctl(2), link(2), mkdir(2), mknod(2), open(2), rename(2), request_key(2), setxattr(2), symlink(2), write(2) +syscon errno EDQUOT 122 69 69 69 69 1816 # disk quota exceeded; bsd consensus; kNtErrorNotEnoughQuota; raised by add_key(2), keyctl(2), link(2), mkdir(2), mknod(2), open(2), rename(2), request_key(2), setxattr(2), symlink(2), write(2) syscon errno ESPIPE 29 29 29 29 29 25 # invalid seek; unix consensus; kNtErrorSeek; raised by fallocate(2), lseek(2), posix_fadvise(2), sendfile(2), splice(2), sync_file_range(2) syscon errno EROFS 30 30 30 30 30 6009 # read-only filesystem; unix consensus; kNtErrorFileReadOnly; raised by access(2), acct(2), bind(2), chmod(2), chown(2), link(2), mkdir(2), mknod(2), mount(2), open(2), rename(2), rmdir(2), symlink(2), truncate(2), unlink(2), utime(2), utimensat(2) -syscon errno EMLINK 31 31 31 31 31 4 # too many links; unix consensus; kNtErrorTooManyLinks; raised by link(2), mkdir(2), rename(2) +syscon errno EMLINK 31 31 31 31 31 1142 # too many links; unix consensus; kNtErrorTooManyLinks; raised by link(2), mkdir(2), rename(2) syscon errno EPIPE 32 32 32 32 32 109 # broken pipe; unix consensus; kNtErrorBrokenPipe; raised by send(2), write(2), tcp(7), unix(7), ip(7) syscon errno EDOM 33 33 33 33 33 33 # mathematics argument out of domain of function; bsd consensus; fudged on NT; returned by cos(3), fmod(3), log1p(3), sin(3), tan(3), tgamma(3) syscon errno ERANGE 34 34 34 34 34 34 # result too large; bsd consensus; fudged on NT; raised by getxattr(2), listxattr(2), lookup_dcookie(2), prctl(2), quotactl(2), semctl(2), semop(2), setxattr(2) @@ -125,9 +125,9 @@ syscon errno EOWNERDEAD 130 105 96 94 97 0 # raised by pthread_co syscon errno ENOTRECOVERABLE 131 104 95 93 98 0 # raised by pthread_cond_timedwait(3), pthread_mutex_consistent(3), pthread_mutex_getprioceiling(3), pthread_mutex_lock(3), pthread_mutex_timedlock(3), pthread_mutexattr_getrobust(3), pthread_mutexattr_setrobust(3) syscon errno ENONET 64 0 0 0 0 0 # unilateral; raised by accept(2) syscon errno ERESTART 85 -1 -1 -1 -3 0 # should only be seen in ptrace() +syscon errno ENODATA 61 96 0 0 89 232 # no message is available in xsi stream or named pipe is being closed; no data available; barely in posix; returned by ioctl; very close in spirit to EPIPE? syscon errno ENOSR 63 98 0 90 90 0 # out of streams resources; something like EAGAIN; it's in POSIX; maybe some commercial UNIX returns it with openat, putmsg, putpmsg, posix_openpt, ioctl, open syscon errno ENOSTR 60 99 0 0 91 0 # not a stream; returned by getmsg, putmsg, putpmsg, getpmsg -syscon errno ENODATA 61 96 0 0 89 232 # no message is available in xsi stream or named pipe is being closed; no data available; barely in posix; returned by ioctl; very close in spirit to EPIPE? syscon errno EMULTIHOP 72 95 90 0 94 0 # barely in posix syscon errno ENOLINK 67 97 91 0 95 0 # barely in posix syscon errno ENOMEDIUM 123 0 0 85 0 0 # not posix; not documented @@ -187,6 +187,7 @@ syscon open O_CREAT 0x00000040 0x00000200 0x00000200 0x00000200 0x000002 syscon open O_EXCL 0x00000080 0x00000800 0x00000800 0x00000800 0x00000800 0x00000080 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] syscon open O_TRUNC 0x00000200 0x00000400 0x00000400 0x00000400 0x00000400 0x00000200 # bsd consensus & NT faked as Linux [SYNC libc/calls/open-nt.c] syscon open O_DIRECTORY 0x00010000 0x00100000 0x00020000 0x00020000 0x00200000 0x00010000 # useful hint on UNIX, but required on NT (see kNtFileFlagBackupSemantics) [SYNC libc/calls/open-nt.c] +syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0x00020000 # bsd consensus; kNtFileFlagOpenReparsePoint syscon open O_DIRECT 0x00004000 0 0x00010000 0 0x00080000 0x00004000 # kNtFileFlagNoBuffering [SYNC libc/calls/open-nt.c] syscon open O_NDELAY 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # kNtFileFlagWriteThrough [SYNC libc/calls/open-nt.c] syscon open O_RANDOM 0 0 0 0 0 0x80000000 # kNtFileFlagRandomAccess [SYNC libc/calls/open-nt.c] @@ -198,7 +199,6 @@ syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00410000 # Linux 3.11+ ( syscon open O_SPARSE 0 0 0 0 0 0 # wut syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus -syscon open O_NOFOLLOW 0x00020000 0x00000100 0x00000100 0x00000100 0x00000100 0 # bsd consensus syscon open O_NOFOLLOW_ANY 0 0x20000000 0 0 0 0 # syscon open O_SYNC 0x00101000 0x00000080 0x00000080 0x00000080 0x00000080 0 # bsd consensus syscon open O_NOCTTY 0x00000100 0x00020000 0x00008000 0x00008000 0x00008000 0 # used for remote viewing (default behavior on freebsd) @@ -512,7 +512,7 @@ syscon rlimit RLIMIT_RSS 5 5 5 5 5 127 # max physical memory size syscon rlimit RLIMIT_NPROC 6 7 7 7 7 127 # max number of processes; see fork()→EAGAIN; bsd consensus syscon rlimit RLIMIT_NOFILE 7 8 8 8 8 127 # max number of open files; see accept()→EMFILE/ENFILE; bsd consensus syscon rlimit RLIMIT_MEMLOCK 8 6 6 6 6 127 # max locked-in-memory address space; bsd consensus -syscon rlimit RLIMIT_AS 9 5 10 127 10 127 # max virtual memory size in bytes; this one actually works; we set this to RLIMIT_DATA on OpenBSD +syscon rlimit RLIMIT_AS 9 5 10 2 10 9 # max virtual memory size in bytes; this one actually works; fudged as RLIMIT_DATA on OpenBSD syscon rlimit RLIMIT_LOCKS 10 127 127 127 127 127 # max flock() / fcntl() locks; bsd consensus syscon rlimit RLIMIT_SIGPENDING 11 127 127 127 127 127 # max sigqueue() can enqueue; bsd consensus syscon rlimit RLIMIT_MSGQUEUE 12 127 127 127 127 127 # meh posix message queues; bsd consensus @@ -953,109 +953,6 @@ syscon iproto IPPROTO_BEETPH 94 0 0 0 0 0 syscon iproto IPPROTO_COMP 108 0 0 0 0 0 syscon iproto IPPROTO_DCCP 33 0 0 0 0 0 -syscon pr PR_SET_PTRACER_ANY -1 0 0 0 0 0 -syscon pr PR_ENDIAN_BIG 0 0 0 0 0 0 # consensus -syscon pr PR_FP_EXC_DISABLED 0 0 0 0 0 0 # consensus -syscon pr PR_MCE_KILL_CLEAR 0 0 0 0 0 0 # consensus -syscon pr PR_MCE_KILL_LATE 0 0 0 0 0 0 # consensus -syscon pr PR_SPEC_NOT_AFFECTED 0 0 0 0 0 0 # consensus -syscon pr PR_SPEC_STORE_BYPASS 0 0 0 0 0 0 # consensus -syscon pr PR_TIMING_STATISTICAL 0 0 0 0 0 0 # consensus -syscon pr PR_CAP_AMBIENT_IS_SET 1 0 0 0 0 0 -syscon pr PR_ENDIAN_LITTLE 1 0 0 0 0 0 -syscon pr PR_FPEMU_NOPRINT 1 0 0 0 0 0 -syscon pr PR_FP_EXC_NONRECOV 1 0 0 0 0 0 -syscon pr PR_FP_MODE_FR 1 0 0 0 0 0 -syscon pr PR_MCE_KILL_EARLY 1 0 0 0 0 0 -syscon pr PR_MCE_KILL_SET 1 0 0 0 0 0 -syscon pr PR_SET_MM_START_CODE 1 0 0 0 0 0 -syscon pr PR_SET_PDEATHSIG 1 0 0 0 0 0 -syscon pr PR_SPEC_PRCTL 1 0 0 0 0 0 -syscon pr PR_TIMING_TIMESTAMP 1 0 0 0 0 0 -syscon pr PR_TSC_ENABLE 1 0 0 0 0 0 -syscon pr PR_UNALIGN_NOPRINT 1 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_RAISE 2 0 0 0 0 0 -syscon pr PR_ENDIAN_PPC_LITTLE 2 0 0 0 0 0 -syscon pr PR_FPEMU_SIGFPE 2 0 0 0 0 0 -syscon pr PR_FP_EXC_ASYNC 2 0 0 0 0 0 -syscon pr PR_FP_MODE_FRE 2 0 0 0 0 0 -syscon pr PR_GET_PDEATHSIG 2 0 0 0 0 0 -syscon pr PR_MCE_KILL_DEFAULT 2 0 0 0 0 0 -syscon pr PR_SET_MM_END_CODE 2 0 0 0 0 0 -syscon pr PR_SPEC_ENABLE 2 0 0 0 0 0 -syscon pr PR_TSC_SIGSEGV 2 0 0 0 0 0 -syscon pr PR_UNALIGN_SIGBUS 2 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_LOWER 3 0 0 0 0 0 -syscon pr PR_FP_EXC_PRECISE 3 0 0 0 0 0 -syscon pr PR_GET_DUMPABLE 3 0 0 0 0 0 -syscon pr PR_SET_MM_START_DATA 3 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT_CLEAR_ALL 4 0 0 0 0 0 -syscon pr PR_SET_DUMPABLE 4 0 0 0 0 0 -syscon pr PR_SET_MM_END_DATA 4 0 0 0 0 0 -syscon pr PR_SPEC_DISABLE 4 0 0 0 0 0 -syscon pr PR_GET_UNALIGN 5 0 0 0 0 0 -syscon pr PR_SET_MM_START_STACK 5 0 0 0 0 0 -syscon pr PR_SET_MM_START_BRK 6 0 0 0 0 0 -syscon pr PR_SET_UNALIGN 6 0 0 0 0 0 -syscon pr PR_GET_KEEPCAPS 7 0 0 0 0 0 -syscon pr PR_SET_MM_BRK 7 0 0 0 0 0 -syscon pr PR_SET_KEEPCAPS 8 0 0 0 0 0 -syscon pr PR_SET_MM_ARG_START 8 0 0 0 0 0 -syscon pr PR_SPEC_FORCE_DISABLE 8 0 0 0 0 0 -syscon pr PR_GET_FPEMU 9 0 0 0 0 0 -syscon pr PR_SET_MM_ARG_END 9 0 0 0 0 0 -syscon pr PR_SET_FPEMU 10 0 0 0 0 0 -syscon pr PR_SET_MM_ENV_START 10 0 0 0 0 0 -syscon pr PR_GET_FPEXC 11 0 0 0 0 0 -syscon pr PR_SET_MM_ENV_END 11 0 0 0 0 0 -syscon pr PR_SET_FPEXC 12 0 0 0 0 0 -syscon pr PR_SET_MM_AUXV 12 0 0 0 0 0 -syscon pr PR_GET_TIMING 13 0 0 0 0 0 -syscon pr PR_SET_MM_EXE_FILE 13 0 0 0 0 0 -syscon pr PR_SET_MM_MAP 14 0 0 0 0 0 -syscon pr PR_SET_TIMING 14 0 0 0 0 0 -syscon pr PR_SET_MM_MAP_SIZE 15 0 0 0 0 0 -syscon pr PR_SET_NAME 15 0 0 0 0 0 -syscon pr PR_GET_NAME 0x10 0 0 0 0 0 -syscon pr PR_GET_ENDIAN 19 0 0 0 0 0 -syscon pr PR_SET_ENDIAN 20 0 0 0 0 0 -syscon pr PR_GET_SECCOMP 21 0 0 0 0 0 -syscon pr PR_SET_SECCOMP 22 0 0 0 0 0 -syscon pr PR_CAPBSET_READ 23 0 0 0 0 0 -syscon pr PR_CAPBSET_DROP 24 0 0 0 0 0 -syscon pr PR_GET_TSC 25 0 0 0 0 0 -syscon pr PR_SET_TSC 26 0 0 0 0 0 -syscon pr PR_GET_SECUREBITS 27 0 0 0 0 0 -syscon pr PR_SET_SECUREBITS 28 0 0 0 0 0 -syscon pr PR_SET_TIMERSLACK 29 0 0 0 0 0 -syscon pr PR_GET_TIMERSLACK 30 0 0 0 0 0 -syscon pr PR_TASK_PERF_EVENTS_DISABLE 31 0 0 0 0 0 -syscon pr PR_TASK_PERF_EVENTS_ENABLE 0x20 0 0 0 0 0 -syscon pr PR_MCE_KILL 33 0 0 0 0 0 -syscon pr PR_MCE_KILL_GET 34 0 0 0 0 0 -syscon pr PR_SET_MM 35 0 0 0 0 0 -syscon pr PR_SET_CHILD_SUBREAPER 36 0 0 0 0 0 -syscon pr PR_GET_CHILD_SUBREAPER 37 0 0 0 0 0 -syscon pr PR_SET_NO_NEW_PRIVS 38 0 0 0 0 0 -syscon pr PR_GET_NO_NEW_PRIVS 39 0 0 0 0 0 -syscon pr PR_GET_TID_ADDRESS 40 0 0 0 0 0 -syscon pr PR_SET_THP_DISABLE 41 0 0 0 0 0 -syscon pr PR_GET_THP_DISABLE 42 0 0 0 0 0 -syscon pr PR_MPX_ENABLE_MANAGEMENT 43 0 0 0 0 0 -syscon pr PR_MPX_DISABLE_MANAGEMENT 44 0 0 0 0 0 -syscon pr PR_SET_FP_MODE 45 0 0 0 0 0 -syscon pr PR_GET_FP_MODE 46 0 0 0 0 0 -syscon pr PR_CAP_AMBIENT 47 0 0 0 0 0 -syscon pr PR_GET_SPECULATION_CTRL 52 0 0 0 0 0 -syscon pr PR_SET_SPECULATION_CTRL 53 0 0 0 0 0 -syscon pr PR_FP_EXC_SW_ENABLE 0x80 0 0 0 0 0 -syscon pr PR_FP_EXC_DIV 0x010000 0 0 0 0 0 -syscon pr PR_FP_EXC_OVF 0x020000 0 0 0 0 0 -syscon pr PR_FP_EXC_UND 0x040000 0 0 0 0 0 -syscon pr PR_FP_EXC_RES 0x080000 0 0 0 0 0 -syscon pr PR_FP_EXC_INV 0x100000 0 0 0 0 0 -syscon pr PR_SET_PTRACER 0x59616d61 0 0 0 0 0 - syscon sio SIOCADDMULTI 0x8931 0x80206931 0x80206931 0x80206931 0x80206931 0 # bsd consensus syscon sio SIOCATMARK 0x8905 0x40047307 0x40047307 0x40047307 0x40047307 0 # bsd consensus syscon sio SIOCDELMULTI 0x8932 0x80206932 0x80206932 0x80206932 0x80206932 0 # bsd consensus @@ -1987,8 +1884,8 @@ syscon misc FALLOC_FL_UNSHARE_RANGE 0x40 -1 -1 -1 -1 -1 # bsd cons # System Call Numbers. # # group name GNU/Systemd XNU's Not UNIX! FreeBSD OpenBSD NetBSD The New Technology -syscon nr __NR_exit 0x003c 0x2000001 0x0001 0x0001 0x001 0xfff -syscon nr __NR_exit_group 0x00e7 0x2000001 0x0001 0x0001 0x001 0xfff +syscon nr __NR_exit 0x003c 0x2000169 0x01af 0x012e 0x136 0xfff # __bsdthread_terminate() on XNU, thr_exit() on FreeBSD, sys___threxit() on OpenBSD, __lwp_exit() on NetBSD +syscon nr __NR_exit_group 0x00e7 0x2000001 0x0001 0x0001 0x001 0xfff syscon nr __NR_read 0x0000 0x2000003 0x0003 0x0003 0x003 0xfff syscon nr __NR_write 0x0001 0x2000004 0x0004 0x0004 0x004 0xfff syscon nr __NR_open 0x0002 0x2000005 0x0005 0x0005 0x005 0xfff diff --git a/libc/sysv/consts/EDQUOT.S b/libc/sysv/consts/EDQUOT.S index 2d4bae78a..98e5a7360 100644 --- a/libc/sysv/consts/EDQUOT.S +++ b/libc/sysv/consts/EDQUOT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EDQUOT,122,69,69,69,69,10069 +.syscon errno,EDQUOT,122,69,69,69,69,1816 diff --git a/libc/sysv/consts/EMFILE.S b/libc/sysv/consts/EMFILE.S index 7877ea505..cf15a0d89 100644 --- a/libc/sysv/consts/EMFILE.S +++ b/libc/sysv/consts/EMFILE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EMFILE,24,24,24,24,24,336 +.syscon errno,EMFILE,24,24,24,24,24,4 diff --git a/libc/sysv/consts/EMLINK.S b/libc/sysv/consts/EMLINK.S index e9569d2c2..7279d4329 100644 --- a/libc/sysv/consts/EMLINK.S +++ b/libc/sysv/consts/EMLINK.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon errno,EMLINK,31,31,31,31,31,4 +.syscon errno,EMLINK,31,31,31,31,31,1142 diff --git a/libc/sysv/consts/O_NOFOLLOW.S b/libc/sysv/consts/O_NOFOLLOW.S index b0b255d23..823dfcb1a 100644 --- a/libc/sysv/consts/O_NOFOLLOW.S +++ b/libc/sysv/consts/O_NOFOLLOW.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon open,O_NOFOLLOW,0x00020000,0x00000100,0x00000100,0x00000100,0x00000100,0 +.syscon open,O_NOFOLLOW,0x00020000,0x00000100,0x00000100,0x00000100,0x00000100,0x00020000 diff --git a/libc/sysv/consts/PR_CAPBSET_DROP.S b/libc/sysv/consts/PR_CAPBSET_DROP.S deleted file mode 100644 index 4b686464e..000000000 --- a/libc/sysv/consts/PR_CAPBSET_DROP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAPBSET_DROP,24,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAPBSET_READ.S b/libc/sysv/consts/PR_CAPBSET_READ.S deleted file mode 100644 index fa534ace9..000000000 --- a/libc/sysv/consts/PR_CAPBSET_READ.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAPBSET_READ,23,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT.S b/libc/sysv/consts/PR_CAP_AMBIENT.S deleted file mode 100644 index efd1a03af..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT,47,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S b/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S deleted file mode 100644 index 294bf1d8a..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_CLEAR_ALL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_CLEAR_ALL,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S b/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S deleted file mode 100644 index 2e13f3454..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_IS_SET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_IS_SET,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S b/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S deleted file mode 100644 index cd3cbb4e3..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_LOWER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_LOWER,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S b/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S deleted file mode 100644 index da3d27819..000000000 --- a/libc/sysv/consts/PR_CAP_AMBIENT_RAISE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_CAP_AMBIENT_RAISE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_BIG.S b/libc/sysv/consts/PR_ENDIAN_BIG.S deleted file mode 100644 index 83b211d77..000000000 --- a/libc/sysv/consts/PR_ENDIAN_BIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_BIG,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_LITTLE.S b/libc/sysv/consts/PR_ENDIAN_LITTLE.S deleted file mode 100644 index b9b4dbd13..000000000 --- a/libc/sysv/consts/PR_ENDIAN_LITTLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_LITTLE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S b/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S deleted file mode 100644 index 7fd4aa188..000000000 --- a/libc/sysv/consts/PR_ENDIAN_PPC_LITTLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_ENDIAN_PPC_LITTLE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FPEMU_NOPRINT.S b/libc/sysv/consts/PR_FPEMU_NOPRINT.S deleted file mode 100644 index 10925eb6d..000000000 --- a/libc/sysv/consts/PR_FPEMU_NOPRINT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FPEMU_NOPRINT,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FPEMU_SIGFPE.S b/libc/sysv/consts/PR_FPEMU_SIGFPE.S deleted file mode 100644 index 4cbb46164..000000000 --- a/libc/sysv/consts/PR_FPEMU_SIGFPE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FPEMU_SIGFPE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_ASYNC.S b/libc/sysv/consts/PR_FP_EXC_ASYNC.S deleted file mode 100644 index f36d72396..000000000 --- a/libc/sysv/consts/PR_FP_EXC_ASYNC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_ASYNC,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_DISABLED.S b/libc/sysv/consts/PR_FP_EXC_DISABLED.S deleted file mode 100644 index 8cc774685..000000000 --- a/libc/sysv/consts/PR_FP_EXC_DISABLED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_DISABLED,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_DIV.S b/libc/sysv/consts/PR_FP_EXC_DIV.S deleted file mode 100644 index fc8ad75b1..000000000 --- a/libc/sysv/consts/PR_FP_EXC_DIV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_DIV,0x010000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_INV.S b/libc/sysv/consts/PR_FP_EXC_INV.S deleted file mode 100644 index 85475ca11..000000000 --- a/libc/sysv/consts/PR_FP_EXC_INV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_INV,0x100000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_NONRECOV.S b/libc/sysv/consts/PR_FP_EXC_NONRECOV.S deleted file mode 100644 index f57d78bdf..000000000 --- a/libc/sysv/consts/PR_FP_EXC_NONRECOV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_NONRECOV,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_OVF.S b/libc/sysv/consts/PR_FP_EXC_OVF.S deleted file mode 100644 index 07ff9ac8d..000000000 --- a/libc/sysv/consts/PR_FP_EXC_OVF.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_OVF,0x020000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_PRECISE.S b/libc/sysv/consts/PR_FP_EXC_PRECISE.S deleted file mode 100644 index f55e2600b..000000000 --- a/libc/sysv/consts/PR_FP_EXC_PRECISE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_PRECISE,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_RES.S b/libc/sysv/consts/PR_FP_EXC_RES.S deleted file mode 100644 index 234428b05..000000000 --- a/libc/sysv/consts/PR_FP_EXC_RES.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_RES,0x080000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S b/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S deleted file mode 100644 index 7ac6c8101..000000000 --- a/libc/sysv/consts/PR_FP_EXC_SW_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_SW_ENABLE,0x80,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_EXC_UND.S b/libc/sysv/consts/PR_FP_EXC_UND.S deleted file mode 100644 index ba05501ca..000000000 --- a/libc/sysv/consts/PR_FP_EXC_UND.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_EXC_UND,0x040000,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_MODE_FR.S b/libc/sysv/consts/PR_FP_MODE_FR.S deleted file mode 100644 index 8948def13..000000000 --- a/libc/sysv/consts/PR_FP_MODE_FR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_MODE_FR,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_FP_MODE_FRE.S b/libc/sysv/consts/PR_FP_MODE_FRE.S deleted file mode 100644 index 03f89460c..000000000 --- a/libc/sysv/consts/PR_FP_MODE_FRE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_FP_MODE_FRE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S b/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S deleted file mode 100644 index ad1aeec26..000000000 --- a/libc/sysv/consts/PR_GET_CHILD_SUBREAPER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_CHILD_SUBREAPER,37,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_DUMPABLE.S b/libc/sysv/consts/PR_GET_DUMPABLE.S deleted file mode 100644 index e1dd69fdb..000000000 --- a/libc/sysv/consts/PR_GET_DUMPABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_DUMPABLE,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_ENDIAN.S b/libc/sysv/consts/PR_GET_ENDIAN.S deleted file mode 100644 index 8d2f95582..000000000 --- a/libc/sysv/consts/PR_GET_ENDIAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_ENDIAN,19,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FPEMU.S b/libc/sysv/consts/PR_GET_FPEMU.S deleted file mode 100644 index df847914a..000000000 --- a/libc/sysv/consts/PR_GET_FPEMU.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FPEMU,9,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FPEXC.S b/libc/sysv/consts/PR_GET_FPEXC.S deleted file mode 100644 index 1e2caa8f9..000000000 --- a/libc/sysv/consts/PR_GET_FPEXC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FPEXC,11,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_FP_MODE.S b/libc/sysv/consts/PR_GET_FP_MODE.S deleted file mode 100644 index 07252f7df..000000000 --- a/libc/sysv/consts/PR_GET_FP_MODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_FP_MODE,46,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_KEEPCAPS.S b/libc/sysv/consts/PR_GET_KEEPCAPS.S deleted file mode 100644 index cf71ee7fb..000000000 --- a/libc/sysv/consts/PR_GET_KEEPCAPS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_KEEPCAPS,7,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_NAME.S b/libc/sysv/consts/PR_GET_NAME.S deleted file mode 100644 index ef5987835..000000000 --- a/libc/sysv/consts/PR_GET_NAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_NAME,0x10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S b/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S deleted file mode 100644 index 17ace0567..000000000 --- a/libc/sysv/consts/PR_GET_NO_NEW_PRIVS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_NO_NEW_PRIVS,39,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_PDEATHSIG.S b/libc/sysv/consts/PR_GET_PDEATHSIG.S deleted file mode 100644 index 6b0883ef3..000000000 --- a/libc/sysv/consts/PR_GET_PDEATHSIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_PDEATHSIG,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SECCOMP.S b/libc/sysv/consts/PR_GET_SECCOMP.S deleted file mode 100644 index 5a49f97de..000000000 --- a/libc/sysv/consts/PR_GET_SECCOMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SECCOMP,21,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SECUREBITS.S b/libc/sysv/consts/PR_GET_SECUREBITS.S deleted file mode 100644 index 061ece0ae..000000000 --- a/libc/sysv/consts/PR_GET_SECUREBITS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SECUREBITS,27,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S b/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S deleted file mode 100644 index fbc620150..000000000 --- a/libc/sysv/consts/PR_GET_SPECULATION_CTRL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_SPECULATION_CTRL,52,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_THP_DISABLE.S b/libc/sysv/consts/PR_GET_THP_DISABLE.S deleted file mode 100644 index 14fbf6d23..000000000 --- a/libc/sysv/consts/PR_GET_THP_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_THP_DISABLE,42,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TID_ADDRESS.S b/libc/sysv/consts/PR_GET_TID_ADDRESS.S deleted file mode 100644 index 31f35d285..000000000 --- a/libc/sysv/consts/PR_GET_TID_ADDRESS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TID_ADDRESS,40,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TIMERSLACK.S b/libc/sysv/consts/PR_GET_TIMERSLACK.S deleted file mode 100644 index b713ba6ca..000000000 --- a/libc/sysv/consts/PR_GET_TIMERSLACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TIMERSLACK,30,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TIMING.S b/libc/sysv/consts/PR_GET_TIMING.S deleted file mode 100644 index 6de7b07b4..000000000 --- a/libc/sysv/consts/PR_GET_TIMING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TIMING,13,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_TSC.S b/libc/sysv/consts/PR_GET_TSC.S deleted file mode 100644 index 93ec93d88..000000000 --- a/libc/sysv/consts/PR_GET_TSC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_TSC,25,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_GET_UNALIGN.S b/libc/sysv/consts/PR_GET_UNALIGN.S deleted file mode 100644 index cfd961d09..000000000 --- a/libc/sysv/consts/PR_GET_UNALIGN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_GET_UNALIGN,5,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL.S b/libc/sysv/consts/PR_MCE_KILL.S deleted file mode 100644 index 15c958ea3..000000000 --- a/libc/sysv/consts/PR_MCE_KILL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL,33,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_CLEAR.S b/libc/sysv/consts/PR_MCE_KILL_CLEAR.S deleted file mode 100644 index bb9f4c94a..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_CLEAR.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_CLEAR,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S b/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S deleted file mode 100644 index 739713661..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_DEFAULT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_DEFAULT,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_EARLY.S b/libc/sysv/consts/PR_MCE_KILL_EARLY.S deleted file mode 100644 index 155ddb9a9..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_EARLY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_EARLY,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_GET.S b/libc/sysv/consts/PR_MCE_KILL_GET.S deleted file mode 100644 index e5a7a3234..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_GET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_GET,34,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_LATE.S b/libc/sysv/consts/PR_MCE_KILL_LATE.S deleted file mode 100644 index 36b6c0ff7..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_LATE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_LATE,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MCE_KILL_SET.S b/libc/sysv/consts/PR_MCE_KILL_SET.S deleted file mode 100644 index 3956109cc..000000000 --- a/libc/sysv/consts/PR_MCE_KILL_SET.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MCE_KILL_SET,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S b/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S deleted file mode 100644 index aa70185a8..000000000 --- a/libc/sysv/consts/PR_MPX_DISABLE_MANAGEMENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MPX_DISABLE_MANAGEMENT,44,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S b/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S deleted file mode 100644 index 40a829d6b..000000000 --- a/libc/sysv/consts/PR_MPX_ENABLE_MANAGEMENT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_MPX_ENABLE_MANAGEMENT,43,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S b/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S deleted file mode 100644 index 1db02010c..000000000 --- a/libc/sysv/consts/PR_SET_CHILD_SUBREAPER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_CHILD_SUBREAPER,36,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_DUMPABLE.S b/libc/sysv/consts/PR_SET_DUMPABLE.S deleted file mode 100644 index ce11a6fa1..000000000 --- a/libc/sysv/consts/PR_SET_DUMPABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_DUMPABLE,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_ENDIAN.S b/libc/sysv/consts/PR_SET_ENDIAN.S deleted file mode 100644 index 6c0721fde..000000000 --- a/libc/sysv/consts/PR_SET_ENDIAN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_ENDIAN,20,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FPEMU.S b/libc/sysv/consts/PR_SET_FPEMU.S deleted file mode 100644 index 553118d9d..000000000 --- a/libc/sysv/consts/PR_SET_FPEMU.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FPEMU,10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FPEXC.S b/libc/sysv/consts/PR_SET_FPEXC.S deleted file mode 100644 index 9286d0582..000000000 --- a/libc/sysv/consts/PR_SET_FPEXC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FPEXC,12,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_FP_MODE.S b/libc/sysv/consts/PR_SET_FP_MODE.S deleted file mode 100644 index c0e0a9633..000000000 --- a/libc/sysv/consts/PR_SET_FP_MODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_FP_MODE,45,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_KEEPCAPS.S b/libc/sysv/consts/PR_SET_KEEPCAPS.S deleted file mode 100644 index ee5e15f32..000000000 --- a/libc/sysv/consts/PR_SET_KEEPCAPS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_KEEPCAPS,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM.S b/libc/sysv/consts/PR_SET_MM.S deleted file mode 100644 index 459d4e9e2..000000000 --- a/libc/sysv/consts/PR_SET_MM.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM,35,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_END.S b/libc/sysv/consts/PR_SET_MM_ARG_END.S deleted file mode 100644 index 4bc2ebe7a..000000000 --- a/libc/sysv/consts/PR_SET_MM_ARG_END.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ARG_END,9,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ARG_START.S b/libc/sysv/consts/PR_SET_MM_ARG_START.S deleted file mode 100644 index fd6f32a8a..000000000 --- a/libc/sysv/consts/PR_SET_MM_ARG_START.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ARG_START,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_AUXV.S b/libc/sysv/consts/PR_SET_MM_AUXV.S deleted file mode 100644 index 7f0d3726e..000000000 --- a/libc/sysv/consts/PR_SET_MM_AUXV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_AUXV,12,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_BRK.S b/libc/sysv/consts/PR_SET_MM_BRK.S deleted file mode 100644 index bf84d9aff..000000000 --- a/libc/sysv/consts/PR_SET_MM_BRK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_BRK,7,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_END_CODE.S b/libc/sysv/consts/PR_SET_MM_END_CODE.S deleted file mode 100644 index 39311d767..000000000 --- a/libc/sysv/consts/PR_SET_MM_END_CODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_END_CODE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_END_DATA.S b/libc/sysv/consts/PR_SET_MM_END_DATA.S deleted file mode 100644 index e8b856808..000000000 --- a/libc/sysv/consts/PR_SET_MM_END_DATA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_END_DATA,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_END.S b/libc/sysv/consts/PR_SET_MM_ENV_END.S deleted file mode 100644 index f23384115..000000000 --- a/libc/sysv/consts/PR_SET_MM_ENV_END.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ENV_END,11,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_ENV_START.S b/libc/sysv/consts/PR_SET_MM_ENV_START.S deleted file mode 100644 index dbc7f89ca..000000000 --- a/libc/sysv/consts/PR_SET_MM_ENV_START.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_ENV_START,10,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_EXE_FILE.S b/libc/sysv/consts/PR_SET_MM_EXE_FILE.S deleted file mode 100644 index b36a437a4..000000000 --- a/libc/sysv/consts/PR_SET_MM_EXE_FILE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_EXE_FILE,13,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP.S b/libc/sysv/consts/PR_SET_MM_MAP.S deleted file mode 100644 index 9ecc3c198..000000000 --- a/libc/sysv/consts/PR_SET_MM_MAP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_MAP,14,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S b/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S deleted file mode 100644 index d4a755863..000000000 --- a/libc/sysv/consts/PR_SET_MM_MAP_SIZE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_MAP_SIZE,15,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_BRK.S b/libc/sysv/consts/PR_SET_MM_START_BRK.S deleted file mode 100644 index 424305ca1..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_BRK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_BRK,6,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_CODE.S b/libc/sysv/consts/PR_SET_MM_START_CODE.S deleted file mode 100644 index 92f18baf1..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_CODE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_CODE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_DATA.S b/libc/sysv/consts/PR_SET_MM_START_DATA.S deleted file mode 100644 index 470747118..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_DATA.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_DATA,3,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_MM_START_STACK.S b/libc/sysv/consts/PR_SET_MM_START_STACK.S deleted file mode 100644 index 5488e02e7..000000000 --- a/libc/sysv/consts/PR_SET_MM_START_STACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_MM_START_STACK,5,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_NAME.S b/libc/sysv/consts/PR_SET_NAME.S deleted file mode 100644 index f8db3d489..000000000 --- a/libc/sysv/consts/PR_SET_NAME.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_NAME,15,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S b/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S deleted file mode 100644 index 8d17b8295..000000000 --- a/libc/sysv/consts/PR_SET_NO_NEW_PRIVS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_NO_NEW_PRIVS,38,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PDEATHSIG.S b/libc/sysv/consts/PR_SET_PDEATHSIG.S deleted file mode 100644 index 3eeb2d91d..000000000 --- a/libc/sysv/consts/PR_SET_PDEATHSIG.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PDEATHSIG,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PTRACER.S b/libc/sysv/consts/PR_SET_PTRACER.S deleted file mode 100644 index afdb5374f..000000000 --- a/libc/sysv/consts/PR_SET_PTRACER.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PTRACER,0x59616d61,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_PTRACER_ANY.S b/libc/sysv/consts/PR_SET_PTRACER_ANY.S deleted file mode 100644 index d955036a1..000000000 --- a/libc/sysv/consts/PR_SET_PTRACER_ANY.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_PTRACER_ANY,-1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SECCOMP.S b/libc/sysv/consts/PR_SET_SECCOMP.S deleted file mode 100644 index 6cd99bf03..000000000 --- a/libc/sysv/consts/PR_SET_SECCOMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SECCOMP,22,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SECUREBITS.S b/libc/sysv/consts/PR_SET_SECUREBITS.S deleted file mode 100644 index dedc7fa57..000000000 --- a/libc/sysv/consts/PR_SET_SECUREBITS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SECUREBITS,28,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S b/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S deleted file mode 100644 index 068eadfcd..000000000 --- a/libc/sysv/consts/PR_SET_SPECULATION_CTRL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_SPECULATION_CTRL,53,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_THP_DISABLE.S b/libc/sysv/consts/PR_SET_THP_DISABLE.S deleted file mode 100644 index 5ac7f0af2..000000000 --- a/libc/sysv/consts/PR_SET_THP_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_THP_DISABLE,41,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TIMERSLACK.S b/libc/sysv/consts/PR_SET_TIMERSLACK.S deleted file mode 100644 index fb7177863..000000000 --- a/libc/sysv/consts/PR_SET_TIMERSLACK.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TIMERSLACK,29,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TIMING.S b/libc/sysv/consts/PR_SET_TIMING.S deleted file mode 100644 index fee4162b1..000000000 --- a/libc/sysv/consts/PR_SET_TIMING.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TIMING,14,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_TSC.S b/libc/sysv/consts/PR_SET_TSC.S deleted file mode 100644 index 3facbf5c0..000000000 --- a/libc/sysv/consts/PR_SET_TSC.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_TSC,26,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SET_UNALIGN.S b/libc/sysv/consts/PR_SET_UNALIGN.S deleted file mode 100644 index c5f5f0fc7..000000000 --- a/libc/sysv/consts/PR_SET_UNALIGN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SET_UNALIGN,6,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_DISABLE.S b/libc/sysv/consts/PR_SPEC_DISABLE.S deleted file mode 100644 index 02ed8d3ab..000000000 --- a/libc/sysv/consts/PR_SPEC_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_DISABLE,4,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_ENABLE.S b/libc/sysv/consts/PR_SPEC_ENABLE.S deleted file mode 100644 index dc0756fd9..000000000 --- a/libc/sysv/consts/PR_SPEC_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_ENABLE,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S b/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S deleted file mode 100644 index a610707ac..000000000 --- a/libc/sysv/consts/PR_SPEC_FORCE_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_FORCE_DISABLE,8,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S b/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S deleted file mode 100644 index d848f40a4..000000000 --- a/libc/sysv/consts/PR_SPEC_NOT_AFFECTED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_NOT_AFFECTED,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_PRCTL.S b/libc/sysv/consts/PR_SPEC_PRCTL.S deleted file mode 100644 index abb92d3fb..000000000 --- a/libc/sysv/consts/PR_SPEC_PRCTL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_PRCTL,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S b/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S deleted file mode 100644 index 07bf3f364..000000000 --- a/libc/sysv/consts/PR_SPEC_STORE_BYPASS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_SPEC_STORE_BYPASS,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S b/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S deleted file mode 100644 index 8a8d0657e..000000000 --- a/libc/sysv/consts/PR_TASK_PERF_EVENTS_DISABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TASK_PERF_EVENTS_DISABLE,31,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S b/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S deleted file mode 100644 index c44f7ba4d..000000000 --- a/libc/sysv/consts/PR_TASK_PERF_EVENTS_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TASK_PERF_EVENTS_ENABLE,0x20,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TIMING_STATISTICAL.S b/libc/sysv/consts/PR_TIMING_STATISTICAL.S deleted file mode 100644 index 287a2a6d8..000000000 --- a/libc/sysv/consts/PR_TIMING_STATISTICAL.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TIMING_STATISTICAL,0,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TIMING_TIMESTAMP.S b/libc/sysv/consts/PR_TIMING_TIMESTAMP.S deleted file mode 100644 index e44d31a21..000000000 --- a/libc/sysv/consts/PR_TIMING_TIMESTAMP.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TIMING_TIMESTAMP,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TSC_ENABLE.S b/libc/sysv/consts/PR_TSC_ENABLE.S deleted file mode 100644 index 3ac5b3c40..000000000 --- a/libc/sysv/consts/PR_TSC_ENABLE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TSC_ENABLE,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_TSC_SIGSEGV.S b/libc/sysv/consts/PR_TSC_SIGSEGV.S deleted file mode 100644 index c189af59e..000000000 --- a/libc/sysv/consts/PR_TSC_SIGSEGV.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_TSC_SIGSEGV,2,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_UNALIGN_NOPRINT.S b/libc/sysv/consts/PR_UNALIGN_NOPRINT.S deleted file mode 100644 index da14fbf25..000000000 --- a/libc/sysv/consts/PR_UNALIGN_NOPRINT.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_UNALIGN_NOPRINT,1,0,0,0,0,0 diff --git a/libc/sysv/consts/PR_UNALIGN_SIGBUS.S b/libc/sysv/consts/PR_UNALIGN_SIGBUS.S deleted file mode 100644 index 3e05888ff..000000000 --- a/libc/sysv/consts/PR_UNALIGN_SIGBUS.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon pr,PR_UNALIGN_SIGBUS,2,0,0,0,0,0 diff --git a/libc/sysv/consts/RLIMIT_AS.S b/libc/sysv/consts/RLIMIT_AS.S index 00f1f8ea2..3a9cdf8e6 100644 --- a/libc/sysv/consts/RLIMIT_AS.S +++ b/libc/sysv/consts/RLIMIT_AS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon rlimit,RLIMIT_AS,9,5,10,127,10,127 +.syscon rlimit,RLIMIT_AS,9,5,10,2,10,9 diff --git a/libc/sysv/consts/__NR_exit.S b/libc/sysv/consts/__NR_exit.S index aab333d47..de72e4a7c 100644 --- a/libc/sysv/consts/__NR_exit.S +++ b/libc/sysv/consts/__NR_exit.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon nr,__NR_exit,0x003c,0x2000001,0x0001,0x0001,0x001,0xfff +.syscon nr,__NR_exit,0x003c,0x2000169,0x01af,0x012e,0x136,0xfff diff --git a/libc/sysv/consts/pr.h b/libc/sysv/consts/pr.h index 2e28b55ce..4238bd629 100644 --- a/libc/sysv/consts/pr.h +++ b/libc/sysv/consts/pr.h @@ -1,216 +1,101 @@ #ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ #define COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ -#include "libc/runtime/symbolic.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -extern const long PR_CAPBSET_DROP; -extern const long PR_CAPBSET_READ; -extern const long PR_CAP_AMBIENT; -extern const long PR_CAP_AMBIENT_CLEAR_ALL; -extern const long PR_CAP_AMBIENT_IS_SET; -extern const long PR_CAP_AMBIENT_LOWER; -extern const long PR_CAP_AMBIENT_RAISE; -extern const long PR_ENDIAN_BIG; -extern const long PR_ENDIAN_LITTLE; -extern const long PR_ENDIAN_PPC_LITTLE; -extern const long PR_FPEMU_NOPRINT; -extern const long PR_FPEMU_SIGFPE; -extern const long PR_FP_EXC_ASYNC; -extern const long PR_FP_EXC_DISABLED; -extern const long PR_FP_EXC_DIV; -extern const long PR_FP_EXC_INV; -extern const long PR_FP_EXC_NONRECOV; -extern const long PR_FP_EXC_OVF; -extern const long PR_FP_EXC_PRECISE; -extern const long PR_FP_EXC_RES; -extern const long PR_FP_EXC_SW_ENABLE; -extern const long PR_FP_EXC_UND; -extern const long PR_FP_MODE_FR; -extern const long PR_FP_MODE_FRE; -extern const long PR_GET_CHILD_SUBREAPER; -extern const long PR_GET_DUMPABLE; -extern const long PR_GET_ENDIAN; -extern const long PR_GET_FPEMU; -extern const long PR_GET_FPEXC; -extern const long PR_GET_FP_MODE; -extern const long PR_GET_KEEPCAPS; -extern const long PR_GET_NAME; -extern const long PR_GET_NO_NEW_PRIVS; -extern const long PR_GET_PDEATHSIG; -extern const long PR_GET_SECCOMP; -extern const long PR_GET_SECUREBITS; -extern const long PR_GET_SPECULATION_CTRL; -extern const long PR_GET_THP_DISABLE; -extern const long PR_GET_TID_ADDRESS; -extern const long PR_GET_TIMERSLACK; -extern const long PR_GET_TIMING; -extern const long PR_GET_TSC; -extern const long PR_GET_UNALIGN; -extern const long PR_MCE_KILL; -extern const long PR_MCE_KILL_CLEAR; -extern const long PR_MCE_KILL_DEFAULT; -extern const long PR_MCE_KILL_EARLY; -extern const long PR_MCE_KILL_GET; -extern const long PR_MCE_KILL_LATE; -extern const long PR_MCE_KILL_SET; -extern const long PR_MPX_DISABLE_MANAGEMENT; -extern const long PR_MPX_ENABLE_MANAGEMENT; -extern const long PR_SET_CHILD_SUBREAPER; -extern const long PR_SET_DUMPABLE; -extern const long PR_SET_ENDIAN; -extern const long PR_SET_FPEMU; -extern const long PR_SET_FPEXC; -extern const long PR_SET_FP_MODE; -extern const long PR_SET_KEEPCAPS; -extern const long PR_SET_MM; -extern const long PR_SET_MM_ARG_END; -extern const long PR_SET_MM_ARG_START; -extern const long PR_SET_MM_AUXV; -extern const long PR_SET_MM_BRK; -extern const long PR_SET_MM_END_CODE; -extern const long PR_SET_MM_END_DATA; -extern const long PR_SET_MM_ENV_END; -extern const long PR_SET_MM_ENV_START; -extern const long PR_SET_MM_EXE_FILE; -extern const long PR_SET_MM_MAP; -extern const long PR_SET_MM_MAP_SIZE; -extern const long PR_SET_MM_START_BRK; -extern const long PR_SET_MM_START_CODE; -extern const long PR_SET_MM_START_DATA; -extern const long PR_SET_MM_START_STACK; -extern const long PR_SET_NAME; -extern const long PR_SET_NO_NEW_PRIVS; -extern const long PR_SET_PDEATHSIG; -extern const long PR_SET_PTRACER; -extern const long PR_SET_PTRACER_ANY; -extern const long PR_SET_SECCOMP; -extern const long PR_SET_SECUREBITS; -extern const long PR_SET_SPECULATION_CTRL; -extern const long PR_SET_THP_DISABLE; -extern const long PR_SET_TIMERSLACK; -extern const long PR_SET_TIMING; -extern const long PR_SET_TSC; -extern const long PR_SET_UNALIGN; -extern const long PR_SPEC_DISABLE; -extern const long PR_SPEC_ENABLE; -extern const long PR_SPEC_FORCE_DISABLE; -extern const long PR_SPEC_NOT_AFFECTED; -extern const long PR_SPEC_PRCTL; -extern const long PR_SPEC_STORE_BYPASS; -extern const long PR_TASK_PERF_EVENTS_DISABLE; -extern const long PR_TASK_PERF_EVENTS_ENABLE; -extern const long PR_TIMING_STATISTICAL; -extern const long PR_TIMING_TIMESTAMP; -extern const long PR_TSC_ENABLE; -extern const long PR_TSC_SIGSEGV; -extern const long PR_UNALIGN_NOPRINT; -extern const long PR_UNALIGN_SIGBUS; +#define PR_GET_SECCOMP 21 +#define PR_SET_SECCOMP 22 +#define SECCOMP_MODE_DISABLED 0 +#define SECCOMP_MODE_STRICT 1 +#define SECCOMP_MODE_FILTER 2 -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#define PR_SET_NAME 15 +#define PR_GET_NAME 0x10 -#define PR_CAPBSET_DROP SYMBOLIC(PR_CAPBSET_DROP) -#define PR_CAPBSET_READ SYMBOLIC(PR_CAPBSET_READ) -#define PR_CAP_AMBIENT SYMBOLIC(PR_CAP_AMBIENT) -#define PR_CAP_AMBIENT_CLEAR_ALL SYMBOLIC(PR_CAP_AMBIENT_CLEAR_ALL) -#define PR_CAP_AMBIENT_IS_SET SYMBOLIC(PR_CAP_AMBIENT_IS_SET) -#define PR_CAP_AMBIENT_LOWER SYMBOLIC(PR_CAP_AMBIENT_LOWER) -#define PR_CAP_AMBIENT_RAISE SYMBOLIC(PR_CAP_AMBIENT_RAISE) -#define PR_ENDIAN_BIG SYMBOLIC(PR_ENDIAN_BIG) -#define PR_ENDIAN_LITTLE SYMBOLIC(PR_ENDIAN_LITTLE) -#define PR_ENDIAN_PPC_LITTLE SYMBOLIC(PR_ENDIAN_PPC_LITTLE) -#define PR_FPEMU_NOPRINT SYMBOLIC(PR_FPEMU_NOPRINT) -#define PR_FPEMU_SIGFPE SYMBOLIC(PR_FPEMU_SIGFPE) -#define PR_FP_EXC_ASYNC SYMBOLIC(PR_FP_EXC_ASYNC) -#define PR_FP_EXC_DISABLED SYMBOLIC(PR_FP_EXC_DISABLED) -#define PR_FP_EXC_DIV SYMBOLIC(PR_FP_EXC_DIV) -#define PR_FP_EXC_INV SYMBOLIC(PR_FP_EXC_INV) -#define PR_FP_EXC_NONRECOV SYMBOLIC(PR_FP_EXC_NONRECOV) -#define PR_FP_EXC_OVF SYMBOLIC(PR_FP_EXC_OVF) -#define PR_FP_EXC_PRECISE SYMBOLIC(PR_FP_EXC_PRECISE) -#define PR_FP_EXC_RES SYMBOLIC(PR_FP_EXC_RES) -#define PR_FP_EXC_SW_ENABLE SYMBOLIC(PR_FP_EXC_SW_ENABLE) -#define PR_FP_EXC_UND SYMBOLIC(PR_FP_EXC_UND) -#define PR_FP_MODE_FR SYMBOLIC(PR_FP_MODE_FR) -#define PR_FP_MODE_FRE SYMBOLIC(PR_FP_MODE_FRE) -#define PR_GET_CHILD_SUBREAPER SYMBOLIC(PR_GET_CHILD_SUBREAPER) -#define PR_GET_DUMPABLE SYMBOLIC(PR_GET_DUMPABLE) -#define PR_GET_ENDIAN SYMBOLIC(PR_GET_ENDIAN) -#define PR_GET_FPEMU SYMBOLIC(PR_GET_FPEMU) -#define PR_GET_FPEXC SYMBOLIC(PR_GET_FPEXC) -#define PR_GET_FP_MODE SYMBOLIC(PR_GET_FP_MODE) -#define PR_GET_KEEPCAPS SYMBOLIC(PR_GET_KEEPCAPS) -#define PR_GET_NAME SYMBOLIC(PR_GET_NAME) -#define PR_GET_NO_NEW_PRIVS SYMBOLIC(PR_GET_NO_NEW_PRIVS) -#define PR_GET_PDEATHSIG SYMBOLIC(PR_GET_PDEATHSIG) -#define PR_GET_SECCOMP SYMBOLIC(PR_GET_SECCOMP) -#define PR_GET_SECUREBITS SYMBOLIC(PR_GET_SECUREBITS) -#define PR_GET_SPECULATION_CTRL SYMBOLIC(PR_GET_SPECULATION_CTRL) -#define PR_GET_THP_DISABLE SYMBOLIC(PR_GET_THP_DISABLE) -#define PR_GET_TID_ADDRESS SYMBOLIC(PR_GET_TID_ADDRESS) -#define PR_GET_TIMERSLACK SYMBOLIC(PR_GET_TIMERSLACK) -#define PR_GET_TIMING SYMBOLIC(PR_GET_TIMING) -#define PR_GET_TSC SYMBOLIC(PR_GET_TSC) -#define PR_GET_UNALIGN SYMBOLIC(PR_GET_UNALIGN) -#define PR_MCE_KILL SYMBOLIC(PR_MCE_KILL) -#define PR_MCE_KILL_CLEAR SYMBOLIC(PR_MCE_KILL_CLEAR) -#define PR_MCE_KILL_DEFAULT SYMBOLIC(PR_MCE_KILL_DEFAULT) -#define PR_MCE_KILL_EARLY SYMBOLIC(PR_MCE_KILL_EARLY) -#define PR_MCE_KILL_GET SYMBOLIC(PR_MCE_KILL_GET) -#define PR_MCE_KILL_LATE SYMBOLIC(PR_MCE_KILL_LATE) -#define PR_MCE_KILL_SET SYMBOLIC(PR_MCE_KILL_SET) -#define PR_MPX_DISABLE_MANAGEMENT SYMBOLIC(PR_MPX_DISABLE_MANAGEMENT) -#define PR_MPX_ENABLE_MANAGEMENT SYMBOLIC(PR_MPX_ENABLE_MANAGEMENT) -#define PR_SET_CHILD_SUBREAPER SYMBOLIC(PR_SET_CHILD_SUBREAPER) -#define PR_SET_DUMPABLE SYMBOLIC(PR_SET_DUMPABLE) -#define PR_SET_ENDIAN SYMBOLIC(PR_SET_ENDIAN) -#define PR_SET_FPEMU SYMBOLIC(PR_SET_FPEMU) -#define PR_SET_FPEXC SYMBOLIC(PR_SET_FPEXC) -#define PR_SET_FP_MODE SYMBOLIC(PR_SET_FP_MODE) -#define PR_SET_KEEPCAPS SYMBOLIC(PR_SET_KEEPCAPS) -#define PR_SET_MM SYMBOLIC(PR_SET_MM) -#define PR_SET_MM_ARG_END SYMBOLIC(PR_SET_MM_ARG_END) -#define PR_SET_MM_ARG_START SYMBOLIC(PR_SET_MM_ARG_START) -#define PR_SET_MM_AUXV SYMBOLIC(PR_SET_MM_AUXV) -#define PR_SET_MM_BRK SYMBOLIC(PR_SET_MM_BRK) -#define PR_SET_MM_END_CODE SYMBOLIC(PR_SET_MM_END_CODE) -#define PR_SET_MM_END_DATA SYMBOLIC(PR_SET_MM_END_DATA) -#define PR_SET_MM_ENV_END SYMBOLIC(PR_SET_MM_ENV_END) -#define PR_SET_MM_ENV_START SYMBOLIC(PR_SET_MM_ENV_START) -#define PR_SET_MM_EXE_FILE SYMBOLIC(PR_SET_MM_EXE_FILE) -#define PR_SET_MM_MAP SYMBOLIC(PR_SET_MM_MAP) -#define PR_SET_MM_MAP_SIZE SYMBOLIC(PR_SET_MM_MAP_SIZE) -#define PR_SET_MM_START_BRK SYMBOLIC(PR_SET_MM_START_BRK) -#define PR_SET_MM_START_CODE SYMBOLIC(PR_SET_MM_START_CODE) -#define PR_SET_MM_START_DATA SYMBOLIC(PR_SET_MM_START_DATA) -#define PR_SET_MM_START_STACK SYMBOLIC(PR_SET_MM_START_STACK) -#define PR_SET_NAME SYMBOLIC(PR_SET_NAME) -#define PR_SET_NO_NEW_PRIVS SYMBOLIC(PR_SET_NO_NEW_PRIVS) -#define PR_SET_PDEATHSIG SYMBOLIC(PR_SET_PDEATHSIG) -#define PR_SET_PTRACER SYMBOLIC(PR_SET_PTRACER) -#define PR_SET_PTRACER_ANY SYMBOLIC(PR_SET_PTRACER_ANY) -#define PR_SET_SECCOMP SYMBOLIC(PR_SET_SECCOMP) -#define PR_SET_SECUREBITS SYMBOLIC(PR_SET_SECUREBITS) -#define PR_SET_SPECULATION_CTRL SYMBOLIC(PR_SET_SPECULATION_CTRL) -#define PR_SET_THP_DISABLE SYMBOLIC(PR_SET_THP_DISABLE) -#define PR_SET_TIMERSLACK SYMBOLIC(PR_SET_TIMERSLACK) -#define PR_SET_TIMING SYMBOLIC(PR_SET_TIMING) -#define PR_SET_TSC SYMBOLIC(PR_SET_TSC) -#define PR_SET_UNALIGN SYMBOLIC(PR_SET_UNALIGN) -#define PR_SPEC_DISABLE SYMBOLIC(PR_SPEC_DISABLE) -#define PR_SPEC_ENABLE SYMBOLIC(PR_SPEC_ENABLE) -#define PR_SPEC_FORCE_DISABLE SYMBOLIC(PR_SPEC_FORCE_DISABLE) -#define PR_SPEC_NOT_AFFECTED SYMBOLIC(PR_SPEC_NOT_AFFECTED) -#define PR_SPEC_PRCTL SYMBOLIC(PR_SPEC_PRCTL) -#define PR_SPEC_STORE_BYPASS SYMBOLIC(PR_SPEC_STORE_BYPASS) -#define PR_TASK_PERF_EVENTS_DISABLE SYMBOLIC(PR_TASK_PERF_EVENTS_DISABLE) -#define PR_TASK_PERF_EVENTS_ENABLE SYMBOLIC(PR_TASK_PERF_EVENTS_ENABLE) -#define PR_TIMING_STATISTICAL SYMBOLIC(PR_TIMING_STATISTICAL) -#define PR_TIMING_TIMESTAMP SYMBOLIC(PR_TIMING_TIMESTAMP) -#define PR_TSC_ENABLE SYMBOLIC(PR_TSC_ENABLE) -#define PR_TSC_SIGSEGV SYMBOLIC(PR_TSC_SIGSEGV) -#define PR_UNALIGN_NOPRINT SYMBOLIC(PR_UNALIGN_NOPRINT) -#define PR_UNALIGN_SIGBUS SYMBOLIC(PR_UNALIGN_SIGBUS) +#define PR_GET_TSC 25 +#define PR_SET_TSC 26 +#define PR_TSC_ENABLE 1 +#define PR_TSC_SIGSEGV 2 + +#define PR_GET_FPEXC 11 +#define PR_SET_FPEXC 12 +#define PR_FP_EXC_SW_ENABLE 0x80 +#define PR_FP_EXC_DIV 0x010000 +#define PR_FP_EXC_OVF 0x020000 +#define PR_FP_EXC_UND 0x040000 +#define PR_FP_EXC_RES 0x080000 +#define PR_FP_EXC_INV 0x100000 +#define PR_FP_EXC_DISABLED 0 +#define PR_FP_EXC_NONRECOV 1 +#define PR_FP_EXC_ASYNC 2 +#define PR_FP_EXC_PRECISE 3 + +#define PR_MCE_KILL_CLEAR 0 +#define PR_MCE_KILL_LATE 0 +#define PR_SPEC_NOT_AFFECTED 0 +#define PR_SPEC_STORE_BYPASS 0 +#define PR_CAP_AMBIENT_IS_SET 1 +#define PR_FPEMU_NOPRINT 1 +#define PR_MCE_KILL_EARLY 1 +#define PR_MCE_KILL_SET 1 +#define PR_SET_MM_START_CODE 1 +#define PR_SET_PDEATHSIG 1 +#define PR_SPEC_PRCTL 1 +#define PR_CAP_AMBIENT_RAISE 2 +#define PR_FPEMU_SIGFPE 2 +#define PR_GET_PDEATHSIG 2 +#define PR_MCE_KILL_DEFAULT 2 +#define PR_SET_MM_END_CODE 2 +#define PR_SPEC_ENABLE 2 +#define PR_CAP_AMBIENT_LOWER 3 +#define PR_GET_DUMPABLE 3 +#define PR_SET_MM_START_DATA 3 +#define PR_CAP_AMBIENT_CLEAR_ALL 4 +#define PR_SET_DUMPABLE 4 +#define PR_SET_MM_END_DATA 4 +#define PR_SPEC_DISABLE 4 +#define PR_SET_MM_START_STACK 5 +#define PR_SET_MM_START_BRK 6 +#define PR_GET_KEEPCAPS 7 +#define PR_SET_MM_BRK 7 +#define PR_SET_KEEPCAPS 8 +#define PR_SET_MM_ARG_START 8 +#define PR_SPEC_FORCE_DISABLE 8 +#define PR_GET_FPEMU 9 +#define PR_SET_MM_ARG_END 9 +#define PR_SET_FPEMU 10 +#define PR_SET_MM_ENV_START 10 +#define PR_GET_FPEXC 11 +#define PR_SET_MM_ENV_END 11 +#define PR_SET_FPEXC 12 +#define PR_SET_MM_AUXV 12 +#define PR_SET_MM_EXE_FILE 13 +#define PR_SET_MM_MAP 14 +#define PR_SET_MM_MAP_SIZE 15 +#define PR_CAPBSET_READ 23 +#define PR_CAPBSET_DROP 24 +#define PR_GET_TSC 25 +#define PR_SET_TSC 26 +#define PR_GET_SECUREBITS 27 +#define PR_SET_SECUREBITS 28 +#define PR_SET_TIMERSLACK 29 +#define PR_GET_TIMERSLACK 30 +#define PR_TASK_PERF_EVENTS_DISABLE 31 +#define PR_TASK_PERF_EVENTS_ENABLE 0x20 +#define PR_MCE_KILL 33 +#define PR_MCE_KILL_GET 34 +#define PR_SET_MM 35 +#define PR_SET_CHILD_SUBREAPER 36 +#define PR_GET_CHILD_SUBREAPER 37 +#define PR_SET_NO_NEW_PRIVS 38 +#define PR_GET_NO_NEW_PRIVS 39 +#define PR_GET_TID_ADDRESS 40 +#define PR_SET_THP_DISABLE 41 +#define PR_GET_THP_DISABLE 42 +#define PR_MPX_ENABLE_MANAGEMENT 43 +#define PR_MPX_DISABLE_MANAGEMENT 44 +#define PR_CAP_AMBIENT 47 +#define PR_GET_SPECULATION_CTRL 52 +#define PR_SET_SPECULATION_CTRL 53 +#define PR_SET_PTRACER 0x59616d61 +#define PR_SET_PTRACER_ANY -1 #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_PR_H_ */ diff --git a/libc/sysv/consts/seccomp.h b/libc/sysv/consts/seccomp.h new file mode 100644 index 000000000..fb7e495f3 --- /dev/null +++ b/libc/sysv/consts/seccomp.h @@ -0,0 +1,29 @@ +#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_ +#define COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_ + +#define SECCOMP_SET_MODE_STRICT 0 +#define SECCOMP_SET_MODE_FILTER 1 +#define SECCOMP_GET_ACTION_AVAIL 2 +#define SECCOMP_GET_NOTIF_SIZES 3 +#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) +#define SECCOMP_FILTER_FLAG_LOG (1UL << 1) +#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) +#define SECCOMP_FILTER_FLAG_NEW_LISTENER (1UL << 3) +#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4) +#define SECCOMP_RET_KILL_PROCESS 0x80000000U +#define SECCOMP_RET_KILL_THREAD 0x00000000U +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD +#define SECCOMP_RET_TRAP 0x00030000U +#define SECCOMP_RET_ERRNO 0x00050000U +#define SECCOMP_RET_USER_NOTIF 0x7fc00000U +#define SECCOMP_RET_TRACE 0x7ff00000U +#define SECCOMP_RET_LOG 0x7ffc0000U +#define SECCOMP_RET_ALLOW 0x7fff0000U +#define SECCOMP_RET_ACTION_FULL 0xffff0000U +#define SECCOMP_RET_ACTION 0x7fff0000U +#define SECCOMP_RET_DATA 0x0000ffffU +#define SECCOMP_USER_NOTIF_FLAG_CONTINUE (1UL << 0) +#define SECCOMP_ADDFD_FLAG_SETFD (1UL << 0) +#define SECCOMP_ADDFD_FLAG_SEND (1UL << 1) + +#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_SECCOMP_H_ */ diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index 3af4e8599..b0ee6af7a 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -178,7 +178,7 @@ scall munlock 0x0cc0cc0cc20cc096 globl scall mlockall 0x0f210f1442144097 globl scall munlockall 0x0f31101452145098 globl scall sys_setrlimit 0x0c30c30c320c30a0 globl hidden -scall chroot 0x03d03d03d203d0a1 globl +scall sys_chroot 0x03d03d03d203d0a1 globl hidden scall sys_sync 0xfff02402420240a2 globl hidden scall acct 0x03303303320330a3 globl scall settimeofday 0x1a304407a207a0a4 globl @@ -208,7 +208,7 @@ scall vhangup 0xfffffffffffff099 globl scall modify_ldt 0xfffffffffffff09a globl scall pivot_root 0xfffffffffffff09b globl scall _sysctl 0xfffffffffffff09c globl -scall prctl 0xfffffffffffff09d globl +#scall prctl 0xfffffffffffff09d globl # wrapped manually scall sys_arch_prctl 0xfff0a50a5ffff09e globl hidden # sysarch() on bsd scall adjtimex 0xfffffffffffff09f globl scall swapon 0xffffff05520550a7 globl @@ -349,7 +349,7 @@ scall finit_module 0xfffffffffffff139 globl scall sched_setattr 0xfffffffffffff13a globl # ├─ desktop replaced with tablet-first gui inspired by mac os x scall sched_getattr 0xfffffffffffff13b globl # ├─ karen sandler requires systemd init and boot for tablet gui scall renameat2 0xfffffffffffff13c globl # └─ debian founder ian murdock found strangled with vacuum cord -scall seccomp 0xfffffffffffff13d globl +#scall seccomp 0xfffffffffffff13d globl # wrapped manually scall sys_getrandom 0xfff00723321f413e globl hidden # Linux 3.17+ and getentropy() on XNU/OpenBSD, coming to NetBSD in 9.2 scall memfd_create 0xfffffffffffff13f globl # wut scall kexec_file_load 0xfffffffffffff140 globl diff --git a/libc/thread/exit.c b/libc/thread/exit.c index c2cf0c578..268514128 100644 --- a/libc/thread/exit.c +++ b/libc/thread/exit.c @@ -16,28 +16,31 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/sysv/consts/nr.h" +#include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/lockxadd.h" +#include "libc/runtime/runtime.h" #include "libc/thread/descriptor.h" #include "libc/thread/exit.h" #include "libc/thread/self.h" +/** + * Exits cosmopolitan thread. + * + * @param rc is exit code + * @see _Exit1() for the raw system call + * @threadsafe + * @noreturn + */ wontreturn void cthread_exit(int rc) { - cthread_t td = cthread_self(); + cthread_t td; + STRACE("cthread_exit(%d)", rc); + td = cthread_self(); td->rc = rc; - size_t size = (intptr_t)(td->alloc.top) - (intptr_t)(td->alloc.bottom); - - int state; - asm volatile("lock xadd\t%1, %0\n\t" // mark thread as finished - "test\t%2, %b1\n\t" // test if thread was detached - "jz .L.cthread_exit.%=\n\t" // skip unmap if not detached - "syscall\n" // unmap thread - ".L.cthread_exit.%=:\n\t" - "mov\t%%rbx, %%rdi\n\t" // rc - "mov\t$60, %%rax\n\t" - "syscall" // thread exit - : "+m"(td->state), "=&r"(state) - : "I"(cthread_detached), "1"(cthread_finished), "a"(__NR_munmap), - "b"(rc), "D"(td->alloc.bottom), "S"(size) - : "rcx", "r11", "cc", "memory"); - unreachable; + _lockxadd(&td->state, cthread_finished); + if (~td->state & cthread_detached) { + sys_munmap(td->alloc.bottom, + (intptr_t)td->alloc.top - (intptr_t)td->alloc.bottom); + } + _Exit1(rc); } diff --git a/test/libc/calls/access_test.c b/test/libc/calls/access_test.c index e4832d01c..e69dc2b62 100644 --- a/test/libc/calls/access_test.c +++ b/test/libc/calls/access_test.c @@ -29,8 +29,20 @@ char testlib_enable_tmp_setup_teardown; -TEST(access, testNull_returnsEfault) { +TEST(access, efault) { ASSERT_SYS(EFAULT, -1, access(0, F_OK)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, access((void *)77, F_OK)); +} + +TEST(access, enoent) { + ASSERT_SYS(ENOENT, -1, access("doesnotexist", F_OK)); + ASSERT_SYS(ENOENT, -1, access("o/doesnotexist", F_OK)); +} + +TEST(access, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, access("o/doesnotexist", F_OK)); } TEST(access, test) { diff --git a/test/libc/calls/chdir_test.c b/test/libc/calls/chdir_test.c new file mode 100644 index 000000000..8c91665e9 --- /dev/null +++ b/test/libc/calls/chdir_test.c @@ -0,0 +1,51 @@ +/*-*- 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" +#include "libc/errno.h" +#include "libc/sysv/consts/o.h" +#include "libc/testlib/testlib.h" + +char testlib_enable_tmp_setup_teardown; + +TEST(chdir, efault) { + ASSERT_SYS(EFAULT, -1, chdir(0)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, chdir((void *)77)); +} + +TEST(chdir, enoent) { + ASSERT_SYS(ENOENT, -1, chdir("doesnotexist")); + ASSERT_SYS(ENOENT, -1, chdir("o/doesnotexist")); +} + +TEST(chdir, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, chdir("o/doesnotexist")); +} + +TEST(chdir, test) { + ASSERT_SYS(0, 0, mkdir("o", 0755)); + ASSERT_SYS(0, 0, touch("o/file", 0644)); + ASSERT_SYS(0, 3, open("o/file", O_RDONLY)); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(0, 0, chdir("o")); + ASSERT_SYS(0, 3, open("file", O_RDONLY)); + ASSERT_SYS(0, 0, close(3)); + ASSERT_SYS(ENOENT, -1, open("o/file", O_RDONLY)); +} diff --git a/test/libc/calls/open_test.c b/test/libc/calls/open_test.c index 7bf2fc618..cc6852d77 100644 --- a/test/libc/calls/open_test.c +++ b/test/libc/calls/open_test.c @@ -16,12 +16,35 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/dce.h" +#include "libc/errno.h" #include "libc/sysv/consts/o.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" char testlib_enable_tmp_setup_teardown; +TEST(open, efault) { + ASSERT_SYS(EFAULT, -1, open(0, O_RDONLY)); + if (IsWindows() && !IsAsan()) return; // not possible + ASSERT_SYS(EFAULT, -1, open((void *)77, O_RDONLY)); +} + +TEST(open, enoent) { + ASSERT_SYS(ENOENT, -1, open("doesnotexist", O_RDONLY)); + ASSERT_SYS(ENOENT, -1, open("o/doesnotexist", O_RDONLY)); +} + +TEST(open, enotdir) { + ASSERT_SYS(0, 0, touch("o", 0644)); + ASSERT_SYS(ENOTDIR, -1, open("o/doesnotexist", O_RDONLY)); +} + +TEST(open, eexist) { + ASSERT_SYS(0, 0, touch("exists", 0644)); + ASSERT_SYS(EEXIST, -1, open("exists", O_WRONLY | O_CREAT | O_EXCL)); +} + TEST(open, testOpenExistingForWriteOnly_seeksToStart) { char buf[8] = {0}; ASSERT_SYS(0, 0, xbarf("hello.txt", "hello", -1)); diff --git a/test/libc/calls/seccomp_test.c b/test/libc/calls/seccomp_test.c new file mode 100644 index 000000000..c575a32ed --- /dev/null +++ b/test/libc/calls/seccomp_test.c @@ -0,0 +1,72 @@ +/*-*- 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" +#include "libc/calls/struct/iovec.h" +#include "libc/intrin/kprintf.h" +#include "libc/runtime/runtime.h" +#include "libc/sock/sock.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/pr.h" +#include "libc/sysv/consts/seccomp.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" + +bool __is_linux_2_6_23(void) { + if (!IsLinux()) return false; + return prctl(PR_GET_SECCOMP) != -1; // errno should be EINVAL +} + +void SetUp(void) { + if (!__is_linux_2_6_23()) { + exit(0); + } +} + +TEST(seccompStrictMode, evilProcess_getsKill9d) { + int ws, pid; + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_STRICT, 0, 0)); + open("/etc/passwd", O_RDWR); + _Exit1(127); + } + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFSIGNALED(ws)); + EXPECT_EQ(SIGKILL, WTERMSIG(ws)); +} + +TEST(seccompStrictMode, goodProcess_isAuthorized) { + int ws, pid; + int pfds[2]; + char buf[3] = {0}; + ASSERT_SYS(0, 0, pipe(pfds)); + ASSERT_NE(-1, (pid = fork())); + if (!pid) { + EXPECT_EQ(0, seccomp(SECCOMP_SET_MODE_STRICT, 0, 0)); + write(pfds[1], "hi", 3); + _Exit1(0); + } + EXPECT_SYS(0, 0, close(pfds[1])); + EXPECT_SYS(0, 3, read(pfds[0], buf, 3)); + EXPECT_SYS(0, 0, close(pfds[0])); + EXPECT_NE(-1, wait(&ws)); + EXPECT_TRUE(WIFEXITED(ws)); + EXPECT_EQ(0, WEXITSTATUS(ws)); + EXPECT_STREQ("hi", buf); +} diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 7cbe59169..1fcf0e440 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -22,6 +22,7 @@ #include "libc/calls/sigbits.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/sigaction.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/log/check.h" @@ -114,25 +115,30 @@ TEST(setrlimit, testFileSizeLimit) { } int SetKernelEnforcedMemoryLimit(size_t n) { - struct rlimit rlim = {n, n}; - if (IsWindows() || IsXnu()) return -1; - return setrlimit(!IsOpenbsd() ? RLIMIT_AS : RLIMIT_DATA, &rlim); + struct rlimit rlim; + getrlimit(RLIMIT_AS, &rlim); + rlim.rlim_cur = n; + return setrlimit(RLIMIT_AS, &rlim); } TEST(setrlimit, testMemoryLimit) { char *p; + bool gotsome; int i, wstatus; - if (IsAsan()) return; /* b/c we use sys_mmap */ - if (IsXnu()) return; /* doesn't work on darwin */ - if (IsWindows()) return; /* of course it doesn't work on windows */ + if (IsAsan()) return; /* b/c we use sys_mmap */ ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); - for (i = 0; i < (MEM * 2) / PAGESIZE; ++i) { - p = sys_mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) - .addr; - if (p == MAP_FAILED) { + for (gotsome = i = 0; i < (MEM * 2) / PAGESIZE; ++i) { + p = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); + if (p != MAP_FAILED) { + gotsome = true; + } else { + if (!IsNetbsd()) { + // TODO(jart): what's going on with NetBSD? + ASSERT_TRUE(gotsome); + } ASSERT_EQ(ENOMEM, errno); _exit(0); } diff --git a/test/libc/runtime/clone_test.c b/test/libc/runtime/clone_test.c index 6754115ec..3e3464965 100644 --- a/test/libc/runtime/clone_test.c +++ b/test/libc/runtime/clone_test.c @@ -43,6 +43,8 @@ TEST(clone, test) { EXPECT_NE(-1, (tid = clone(thread, stack + FRAMESIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0, &ptid, &tls, &ctid))); - while ((nowl() - t) < 1 && !x) __builtin_ia32_pause(); + while ((nowl() - t) < 1 && !x) { + __builtin_ia32_pause(); + } ASSERT_EQ(42, x); } diff --git a/third_party/infozip/zip/unix/unix.c b/third_party/infozip/zip/unix/unix.c index 095cafbfe..2d6da7198 100644 --- a/third_party/infozip/zip/unix/unix.c +++ b/third_party/infozip/zip/unix/unix.c @@ -45,21 +45,6 @@ local time_t label_utim = 0; /* Local functions */ local char *readd OF((DIR *)); - -#ifdef NO_DIR /* for AT&T 3B1 */ -#ifndef dirent -# define dirent direct -#endif -typedef FILE DIR; -/* -** Apparently originally by Rich Salz. -** Cleaned up and modified by James W. Birdsall. -*/ - -#define closedir(dirp) fclose(dirp) -#endif /* NO_DIR */ - - local char *readd(d) DIR *d; /* directory stream to read from */ /* Return a pointer to the next name in the directory stream d, or NULL if diff --git a/tool/build/runit.h b/tool/build/runit.h index 5a50b794a..deaf96939 100644 --- a/tool/build/runit.h +++ b/tool/build/runit.h @@ -3,7 +3,7 @@ #define RUNITD_PORT 31337 #define RUNITD_MAGIC 0xFEEDABEEu -#define RUNITD_TIMEOUT_MS (1000 * 30) +#define RUNITD_TIMEOUT_MS (1000 * 60 * 60) enum RunitCommand { kRunitExecute, diff --git a/tool/net/help.txt b/tool/net/help.txt index efd4fbdc8..47145b422 100644 --- a/tool/net/help.txt +++ b/tool/net/help.txt @@ -1,6 +1,6 @@ SYNOPSIS - redbean.com [-hvduzmbagf] [-p PORT] [-D DIR] [-- SCRIPTARGS...] + redbean.com [-?BVabdfghjkmsuvz] [-p PORT] [-D DIR] [-- SCRIPTARGS...] DESCRIPTION @@ -26,7 +26,7 @@ OVERVIEW FLAGS - -h help + -h or -? help -d daemonize -u uniprocess -z print port @@ -39,6 +39,7 @@ FLAGS -E show crash reports to public ips -j enable ssl client verify -k disable ssl fetch verify + -Z log worker system calls -f log worker function calls -B only use stronger cryptography -s increase silence [repeatable] @@ -1184,7 +1185,7 @@ RE MODULE re.NEWLINE Use this flag to change the handling of NEWLINE (\x0a) characters. When this flag is set, (1) a NEWLINE shall not be matched by a "." - or any form of a non-matching list, (2) a "^" shall match the + or any form of a non-matching list, () a "^" shall match the zero-length string immediately after a NEWLINE (regardless of re.NOTBOL), and (3) a "$" shall match the zero-length string immediately before a NEWLINE (regardless of re.NOTEOL). @@ -1226,53 +1227,57 @@ MAXMIND MODULE UNIX MODULE - This module exports the best raw system calls from Cosmopolitan Libc. - These UNIX APIs are supported across all supported operating systems, - and that includes Windows. - - fork exit stat open close seek read write access fcntl chdir chown - chmod getcwd kill raise wait pipe dup mkdir rmdir opendir rename - link unlink symlink sync fsync fdatasync truncate umask getppid - getpgrp getpgid setpgid getsid setsid getpid getuid getgid gettime - nanosleep socket socketpair bind listen accept connect recvfrom - sendto shutdown getpeername getsockname sigaction sigprocmask - strerror - - This module also provides the following magic numbers: - - O_RDONLY O_WRONLY O_RDWR O_ACCMODE O_CREAT O_EXCL O_TRUNC - O_CLOEXEC O_APPEND O_TMPFILE O_NOFOLLOW O_SYNC O_ASYNC O_NOCTTY - O_NOATIME O_EXEC O_SEARCH O_DSYNC O_RSYNC O_PATH O_VERIFY O_SHLOCK - O_EXLOCK O_RANDOM O_SEQUENTIAL O_COMPRESSED O_INDEXED SEEK_SET - SEEK_CUR SEEK_END F_GETFD F_SETFD F_GETFL F_SETFL F_UNLCK F_RDLCK - F_WRLCK F_SETLK F_SETLKW FD_CLOEXEC R_OK W_OK X_OK F_OK WNOHANG - CLOCK_REALTIME CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW - CLOCK_REALTIME_COARSE CLOCK_MONOTONIC_COARSE - CLOCK_PROCESS_CPUTIME_ID CLOCK_TAI CLOCK_PROF CLOCK_BOOTTIME - CLOCK_REALTIME_ALARM CLOCK_BOOTTIME_ALARM AF_UNSPEC AF_UNIX - AF_INET SOCK_STREAM SOCK_DGRAM SOCK_CLOEXEC IPPROTO_TCP - IPPROTO_UDP SHUT_RD SHUT_WR SHUT_RDWR MSG_WAITALL MSG_DONTROUTE - MSG_PEEK MSG_OOB MSG_NOSIGNAL DT_UNKNOWN DT_REG DT_DIR DT_BLK - DT_LNK DT_CHR DT_FIFO DT_SOCK AT_FDCWD AT_SYMLINK_NOFOLLOW - SIG_BLOCK SIG_UNBLOCK SIG_SETMASK SIG_DFL SIG_IGN - - Please see the Cosmopolitan Libc documentation for further details. - There's also a /unix.lua file in redbean-demo.com that provides a - glimpse of how these powerful APIs can be used. Here's a synopsis: - - unix.open(path, flags[, mode]) → fd, errno - - Opens file. - - unix.read(fd[, bufsiz, offset]) → data, errno + unix.read(fd:int[, bufsiz:int, offset:int]) → data:str, errno:int Reads from file descriptor. - unix.write(fd, data[, offset]) → rc, errno + unix.write(fd:int, data[, offset]) → rc:int, errno:int Writes to file descriptor. - unix.close(fd) → rc, errno + unix.open(path:str, flags:int[, mode:int]) → fd:int[, errno:int] + + Opens file. + + `flags` should have one of `O_RDONLY`, `O_WRONLY`, or `O_RDWR`. + The following values may also be OR'd into `flags`: + + - `O_CREAT`: Create file if it doesn't exist. + - `O_TRUNC` Automatic truncate(fd,0) if exists. + - `O_CLOEXEC`: Automatic close() upon execve(). + - `O_EXCL`: Exclusive access. See below. + - `O_APPEND`: Open file for append only. + - `O_DIRECT` (not supported on Apple and OpenBSD) + - `O_DIRECTORY` (hint on UNIX but required on NT) + - `O_TMPFILE` (for Linux and Windows only) + - `O_NOFOLLOW` (zero on Windows) + - `O_DSYNC` (zero on non-Linux/Apple) + - `O_RSYNC` (zero on non-Linux/Apple) + - `O_PATH` (zero on non-Linux) + - `O_VERIFY` (zero on non-FreeBSD) + - `O_SHLOCK` (zero on non-BSD) + - `O_EXLOCK` (zero on non-BSD) + - `O_RANDOM` (zero on non-Windows) + - `O_SEQUENTIAL` (zero on non-Windows) + - `O_COMPRESSED` (zero on non-Windows) + - `O_INDEXED` (zero on non-Windows) + + There are three regular combinations for the above flags: + + - `O_RDONLY`: Opens existing file for reading. If it doesn't + exist then nil is returned and errno will be `ENOENT` (or in + some other cases `ENOTDIR`). + + - `O_WRONLY|O_CREAT|O_TRUNC`: Creates file. If it already + exists, then the existing copy is destroyed and the opened + file will start off with a length of zero. This is the + behavior of the traditional creat() system call. + + - `O_WRONLY|O_CREAT|O_EXCL`: Create file only if doesn't exist + already. If it does exist then `nil` is returned along with + `errno` set to `EEXIST`. + + unix.close(fd:int) → rc:int, errno:int Closes file descriptor. @@ -1280,14 +1285,15 @@ UNIX MODULE Invokes `_Exit(exitcode)` on the process. This will immediately halt the current process. Memory will be freed. File descriptors - will be closed. Any open connections it owns will be reset. + will be closed. Any open connections it owns will be reset. This + function never returns. - unix.fork() → childpid|0, errno + unix.fork() → childpid|0, errno:int Creates a new process mitosis style. This returns twice. The parent process gets the nonzero pid. The child gets zero. - unix.commandv(prog) → path, errno + unix.commandv(prog) → path, errno:int Performs `$PATH` lookup of executable. We automatically suffix `.com` and `.exe` automatically for all platforms when path @@ -1309,120 +1315,131 @@ UNIX MODULE The first element in `argv` should be `prog`. This function is normally called after forking. - unix.access(path, mode) → rc, errno + unix.access(path:str, how) → rc:int, errno:int Checks if effective user of current process has permission to - access file. `mode` can be `R_OK`, `W_OK`, `X_OK`, or `F_OK` to + access file. `how` can be `R_OK`, `W_OK`, `X_OK`, or `F_OK` to check for read, write, execute, and existence respectively. - unix.mkdir(path, mode) → rc, errno + unix.mkdir(path:str, mode) → rc:int, errno:int Makes directory. `mode` should be octal, e.g. `0755`. - unix.chdir(path) → rc, errno - + unix.chdir(path:str) → rc:int, errno:int + Changes current directory to `path`. - unix.unlink(path) → rc, errno + unix.unlink(path:str) → rc:int, errno:int Removes file at `path`. - unix.rmdir(path) → rc, errno + unix.rmdir(path:str) → rc:int, errno:int Removes empty directory at `path`. - unix.rename(oldpath, newpath) → rc, errno - unix.link(existingpath, newpath) → rc, errno - unix.symlink(target, linkpath) → rc, errno - unix.chown(path, uid, gid) → rc, errno - unix.chmod(path, mode) → rc, errno - unix.getcwd(path, mode) → rc, errno + unix.chroot(path:str) → rc:int, errno:int + + Changes root directory. Raises `ENOSYS` on Windows. + + unix.dup(oldfd[, newfd[, flags]]) → newfd:int, errno:int + + Duplicates file descriptor. `flags` can have `O_CLOEXEC`. + + unix.pipe([flags]) → reader, writer, errno:int + + Creates fifo which enables communication between processes. + Returns two file descriptors: one for reading and one for + writing. `flags` can have `O_CLOEXEC`. On error, `reader` and + `writer` will be `nil` and `errno` will be set to non-nil. + + unix.rename(oldpath, newpath) → rc:int, errno:int + unix.link(existingpath, newpath) → rc:int, errno:int + unix.symlink(target, linkpath) → rc:int, errno:int + unix.chown(path:str, uid, gid) → rc:int, errno:int + unix.chmod(path:str, mode) → rc:int, errno:int + unix.getcwd(path:str, mode) → rc:int, errno:int unix.getpid() → pid unix.getppid() → pid - unix.kill(pid, sig) → rc, errno - unix.raise(sig) → rc, errno - unix.wait(pid[, options]) → pid, wstatus, nil, errno - unix.fcntl(fd, cmd[, arg]) → rc, errno - unix.dup(oldfd[, newfd[, flags]]) → newfd, errno - flags can have O_CLOEXEC - unix.pipe([flags]) → reader, writer, errno - flags can have O_CLOEXEC - unix.getsid(pid) → sid, errno - unix.getpgrp() → pgid, errno - unix.getpgid(pid) → pgid, errno - unix.setpgid(pid, pgid) → pgid, errno - unix.setsid() → sid, errno - unix.getuid() → uid, errno - unix.getgid() → gid, errno - unix.umask(mask) → rc, errno - unix.gettime([clock]) → seconds, nanos, errno - unix.nanosleep(seconds, nanos) → remseconds, remnanos, errno - unix.sync(fd) - unix.fsync(fd) → rc, errno - unix.fdatasync(fd) → rc, errno + unix.kill(pid, sig) → rc:int, errno:int + unix.raise(sig) → rc:int, errno:int + unix.wait(pid[, options]) → pid, wstatus, nil, errno:int + unix.fcntl(fd:int, cmd[, arg]) → rc:int, errno:int + unix.getsid(pid) → sid, errno:int + unix.getpgrp() → pgid, errno:int + unix.getpgid(pid) → pgid, errno:int + unix.setpgid(pid, pgid) → pgid, errno:int + unix.setsid() → sid, errno:int + unix.getuid() → uid, errno:int + unix.getgid() → gid, errno:int + unix.umask(mask) → rc:int, errno:int + unix.gettime([clock]) → seconds, nanos, errno:int + unix.nanosleep(seconds, nanos) → remseconds, remnanos, errno:int + unix.sync(fd:int) + unix.fsync(fd:int) → rc:int, errno:int + unix.fdatasync(fd:int) → rc:int, errno:int - unix.seek(fd, offset, whence) → newpos, errno + unix.seek(fd:int, offset, whence) → newpos, errno:int where whence ∈ {SEEK_SET, SEEK_CUR, SEEK_END} whence defaults to SEEK_SET - unix.truncate(path, length) → rc, errno - unix.truncate(fd, length) → rc, errno + unix.truncate(path:str, length) → rc:int, errno:int + unix.truncate(fd:int, length) → rc:int, errno:int - unix.socket([family[, type[, protocol]]]) → fd, errno + unix.socket([family[, type[, protocol]]]) → fd:int[, errno:int] `SOCK_CLOEXEC` may be or'd into type `family` defaults to `AF_INET` `type` defaults to `SOCK_STREAM` `protocol` defaults to `IPPROTO_TCP` - unix.socketpair([family[, type[, protocol]]]) → fd1, fd2, errno + unix.socketpair([family[, type[, protocol]]]) → fd1, fd2, errno:int `SOCK_CLOEXEC` may be or'd into type `family` defaults to `AF_INET` `type` defaults to `SOCK_STREAM` `protocol` defaults to `IPPROTO_TCP` - unix.bind(fd, ip, port) → rc, errno + unix.bind(fd:int, ip, port) → rc:int, errno:int - unix.connect(fd, ip, port) → rc, errno + unix.connect(fd:int, ip, port) → rc:int, errno:int - unix.listen(fd[, backlog]) → rc, errno + unix.listen(fd:int[, backlog]) → rc:int, errno:int - unix.getsockname(fd) → ip, port, errno + unix.getsockname(fd:int) → ip, port, errno:int - unix.getpeername(fd) → ip, port, errno + unix.getpeername(fd:int) → ip, port, errno:int - unix.accept(serverfd) → clientfd, ip, port, errno + unix.accept(serverfd) → clientfd, ip, port, errno:int - unix.recv(fd[, bufsiz[, flags]]) → data, errno + unix.recv(fd:int[, bufsiz[, flags]]) → data, errno:int `flags` can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. - unix.recvfrom(fd[, bufsiz[, flags]]) → data, ip, port, errno + unix.recvfrom(fd:int[, bufsiz[, flags]]) → data, ip, port, errno:int `flags` can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. - unix.send(fd, data[, flags]) → sent, errno + unix.send(fd:int, data[, flags]) → sent, errno:int This is the same as `write` except it has a `flags` argument that's intended for sockets. `flags` can have `MSG_OOB`, `MSG_DONTROUTE`, or `MSG_NOSIGNAL`. - unix.sendto(fd, data, ip, port[, flags]) → sent, errno + unix.sendto(fd:int, data, ip, port[, flags]) → sent, errno:int This is useful for sending messages over UDP sockets to specific addresses. The `flags` parameter can have `MSG_OOB`, `MSG_DONTROUTE`, or `MSG_NOSIGNAL`. - unix.shutdown(fd, how) → rc, errno + unix.shutdown(fd:int, how:int) → rc:int, errno:int Partially closes socket. `how` can be `SHUT_RD`, `SHUT_WR`, or `SHUT_RDWR`. - unix.sigprocmask(how[, mask]) → oldmask, errno + unix.sigprocmask(how[, mask]) → oldmask, errno:int `how` can be `SIG_BLOCK`, `SIG_UNBLOCK`, `SIG_SETMASK` - unix.sigaction(sig[, handler[, flags[, mask]]]) → handler, flags, mask, errno + unix.sigaction(sig[, handler[, flags[, mask]]]) → handler, flags, mask, errno:int `handler` can be `SIG_IGN`, `SIG_DFL`, `intptr_t`, or a Lua function. `sig` can be `SIGINT`, `SIGQUIT`, `SIGTERM`, etc. @@ -1443,7 +1460,7 @@ UNIX MODULE Waits for signal to be delivered. unix.setitimer(which[, intsec, intmicros, valsec, valmicros]) - → intsec, intns, valsec, valns, errno + → intsec, intns, valsec, valns, errno:int Causes `SIGALRM` signals to be generated at some point(s) in the future. The `which` parameter should be `ITIMER_REAL`. @@ -1474,38 +1491,387 @@ UNIX MODULE Turns platform-specific `sig` code into its name, e.g. `strsignal(9)` always returns `"SIGKILL"`. - Here's your UnixStat* object. + unix.stat(x) → UnixStat*, errno:int + + Gets information about file or directory. `x` may be a file or + directory path string, or it may be a file descriptor int that + was made by open(). + + unix.opendir(path:str) → UnixDir*, errno:int + + Opens directory for listing its contents. + + unix.opendir(fd:int) → UnixDir*, errno:int + + Opens directory for listing its contents, using a file + descriptor from `open(path, O_RDONLY|O_DIRECTORY)`. + + UnixDir* Object + + UnixDir:close() → rc:int[, errno:int] + + may be called multiple times + called by the garbage collector too + + UnixDir:read() → name:str, kind:int, ino:int, off:int[, errno:int] + + Returns `nil` if there are no more entries. Or error, `nil` will + be returned and `errno` will be non-nil. + + `kind` can be `DT_UNKNOWN`, `DT_REG`, `DT_DIR`, `DT_BLK`, + `DT_LNK`, `DT_CHR`, `DT_FIFO`, or `DT_SOCK`. + + UnixDir:fd() → fd:int[, errno:int] + + EOPNOTSUPP if using /zip/ + EOPNOTSUPP if IsWindows() + + UnixDir:tell() → offset:int + + Returns current arbitrary offset into stream. + + UnixDir:rewind() + + Resets stream back to beginning. + + UnixStat* object. - unix.stat(path) → UnixStat*, errno - unix.stat(fd) → UnixStat*, errno UnixStat:size() → bytes:int + + Size of file in bytes. + UnixStat:mode() → mode:int + + Contains file type and permissions. + + For example, `0010644` is what you might see for a file and + `0040755` is what you might see for a directory. + + To determine the file type: + + - `(st:mode() & 0170000) == 0010000` means fifo or pipe + - `(st:mode() & 0170000) == 0020000` means character device + - `(st:mode() & 0170000) == 0040000` means directory + - `(st:mode() & 0170000) == 0060000` means block device + - `(st:mode() & 0170000) == 0100000` means regular file + - `(st:mode() & 0170000) == 0120000` means symbolic link + - `(st:mode() & 0170000) == 0140000` means socket + + UnixStat:atim() → secs:int, nanos:int + + Size of file in bytes. + + UnixStat:uid() → int + + User ID of file owner. + + UnixStat:gid() → int + + Group ID of file owner. + + UnixStat:mtim() → secs:int, nanos:int + + Last modified time. + + UnixStat:birthtim() → secs:int, nanos:int + + Creation time. Note that on Linux this is the mimimum of + atom/mtim/ctim. + + UnixStat:ctim() → secs:int, nanos:int + + Complicated time. Means time file status was last changed on + UNIX. Means creation time on Windows. + + UnixStat:blocks() → int + + Number of blocks used by storage medium. + + UnixStat:blksize() → int + + Block size is usually 4096 for file system files. + UnixStat:dev() → int UnixStat:ino() → int UnixStat:rdev() → int - UnixStat:uid() → int - UnixStat:gid() → int - UnixStat:atim() → secs:int, nanos:int - UnixStat:mtim() → secs:int, nanos:int - UnixStat:ctim() → secs:int, nanos:int - UnixStat:blocks() → int - UnixStat:blksize() → int - Here's your UnixDir* object. + Here are your error numbers: + + - `EINVAL`: Invalid argument. Raised by [pretty much everything]. + + - `ENOSYS`: System call not available on this platform. On Windows + this is raised by chroot(), setuid(), setgid(). + + - `EPERM`: Operation not permitted. Raised by accept(), adjtimex(), + arch_prctl(), bdflush(), capget(), chmod(), chown(), chroot(), + clock_getres(), copy_file_range(), execve(), fcntl(), + get_robust_list(), getdomainname(), getgroups(), gethostname(), + getpriority(), getrlimit(), getsid(), gettimeofday(), kill(), + link(), mbind(), membarrier(), migrate_pages(), mkdir(), mknod(), + mlock(), mmap(), msgctl(), nice(), open(), prctl(), ptrace(), + reboot(), rename(), rmdir(), sched_setaffinity(), + sched_setattr(), sched_setparam(), sched_setscheduler(), + seteuid(), setfsgid(), setfsuid(), setgid(), setpgid(), + setresuid(), setreuid(), setsid(), setuid(), setup(), shmget(), + sigaltstack(), stime(), swapon(), symlink(), syslog(), + timer_create(), timerfd_create(), tkill(), truncate(), u + unlink(), utime(), utimensat(), vhangup(), vm86(), write(). + + - `ENOENT`: no such file or directory. Raised by access(), + alloc_hugepages(), bind(), chdir(), chmod(), chown(), chroot(), + clock_getres(), execve(), opendir(), inotify_add_watch(), kcmp(), + link(), mkdir(), mknod(), msgget(), open(), readlink(), rename(), + rmdir(), semget(), shmget(), stat(), swapon(), symlink(), + truncate(), unlink(), utime(), utimensat(). + + - `ESRCH`: No such process. Raised by getpriority(), getrlimit(), + getsid(), ioprio_set(), kill(), setpgid(), tkill(), utimensat(), + + - `EINTR`: The greatest of all errnos; crucial for building real + time reliable software. Raised by accept(), clock_nanosleep(), + close(), connect(), dup(), fcntl(), flock(), getrandom(), + nanosleep(), open(), pause(), poll(), ptrace(), read(), recv(), + select(), send(), sigsuspend(), sigwaitinfo(), truncate(), + wait(), write() + + - `EIO`: Raised by access() acct() chdir() chmod() chown() chroot() + close() copy_file_range() execve() fallocate() fsync() ioperm() + link() madvise() mbind() pciconfig_read() ptrace() read() + readlink() sendfile() statfs() symlink() sync_file_range() + truncate() unlink() write() + + - `ENXIO`: No such device or address. Raised by lseek(), open(), + prctl() + + - `E2BIG`: Argument list too long. Raised by execve(), msgop(), + sched_setattr(), semop() + + - `ENOEXEC`: exec format error. Raised by execve(), kexec_load(), + uselib() + + - `EBADF`: bad file descriptor; cf. EBADFD. Raised by accept(), + access(), bind(), chdir(), chmod(), chown(), close(), connect(), + copy_file_range(), dup(), fcntl(), flock(), fsync(), futimesat(), + opendir(), getpeername(), getsockname(), getsockopt(), + inotify_add_watch(), inotify_rm_watch(), ioctl(), kcmp(), + kexec_load(), link(), listen(), llseek(), lseek(), mkdir(), + mknod(), mmap(), open(), prctl(), read(), readahead(), + readlink(), recv(), rename(), select(), send(), shutdown(), + splice(), stat(), symlink(), sync(), sync_file_range(), + timerfd_create(), truncate(), unlink(), utimensat(), write(), + + - `ECHILD`: no child process. Raised by wait(), waitpid(), + waitid(), wait3(), wait4() + + - `EAGAIN`: resource temporarily unavailable (e.g. SO_RCVTIMEO + expired, too many processes, too much memory locked, read or + write with O_NONBLOCK needs polling, etc.). Raised by accept(), + connect(), eventfd(), fcntl(), fork(), getrandom(), mincore(), + mlock(), mmap(), mremap(), msgop(), poll(), read(), select(), + send(), setresuid(), setreuid(), setuid(), sigwaitinfo(), + splice(), tee(), timer_create(), timerfd_create(), tkill(), + write(), + + - `ENOMEM`: We require more vespene gas. Raised by access(), + bind(), chdir(), chmod(), chown(), chroot(), clone(), + copy_file_range(), create_module(), eventfd(), execve(), + fanotify_init(), fork(), getgroups(), getrlimit(), + inotify_add_watch(), inotify_init(), ioperm(), kexec_load(), + link(), mbind(), memfd_create(), mincore(), mkdir(), mknod(), + mlock(), mmap(), mprotect(), mremap(), msgget(), msgop(), + msync(), open(), poll(), readlink(), recv(), rename(), rmdir(), + select(), semget(), send(), shmget(), sigaltstack(), splice(), + stat(), subpage_prot(), swapon(), symlink(), sync_file_range(), + tee(), timer_create(), timerfd_create(), unlink(). + + - `EACCES`: Permission denied. Raised by access(), bind(), bpf(), + chdir(), chmod(), chown(), chroot(), clock_getres(), connect(), + execve(), fcntl(), getpriority(), inotify_add_watch(), link(), + mkdir(), mknod(), mmap(), mprotect(), msgctl(), msgget(), + msgop(), open(), prctl(), ptrace(), readlink(), rename(), + rmdir(), semget(), send(), setpgid(), shmget(), socket(), stat(), + symlink(), truncate(), unlink(), uselib(), utime(), utimensat(), + + - `ENOTBLK`: Block device required. Raised by umount(). + + - `EBUSY`: Device or resource busy. Raised by bdflush(), dup(), + fcntl(), msync(), prctl(), ptrace(), rename(), + rmdir(). + + - `EEXIST`: File exists. Raised by bpf(), create_module(), + inotify_add_watch(), link(), mkdir(), mknod(), mmap(), msgget(), + open(), rename(), rmdir(), semget(), shmget(), symlink() + + - `EXDEV`: Improper link. Raised by copy_file_range(), link(), + rename() + + - `ENODEV`: No such device. Raised by arch_prctl(), eventfd(), + mmap(), open(), prctl(), timerfd_create() + + - `ENOTDIR`: Not a directory. This means that a directory component + in a supplied path *existed* but wasn't a directory. For example, + if you try to `open("foo/bar")` and `foo` is a regular file, then + `ENOTDIR` will be returned. Raised by open(), access(), chdir(), + chmod(), chown(), chroot(), execve(), fcntl(), futimesat(), + inotify_add_watch(), link(), mkdir(), mknod(), opendir(), + readlink(), rename(), rmdir(), stat(), symlink(), sysctl(), + truncate(), unlink(), utimensat(), bind(). + + - `EISDIR`: Is a a directory. Raised by copy_file_range(), + execve(), open(), read(), rename(), truncate(), unlink(). + + - `ENFILE`: Too many open files in system. Raised by accept(), + eventfd(), execve(), inotify_init(), memfd_create(), mmap(), + open(), pipe(), shmget(), socket(), socketpair(), swapon(), + timerfd_create(), uselib(), userfaultfd(). + + - `EMFILE`: Too many open files. Raised by accept(), dup(), + eventfd(), execve(), fanotify_init(), fcntl(), inotify_init(), + memfd_create(), open(), pipe(), socket(), socketpair(), + timerfd_create(). + + - `ENOTTY`: Inappropriate i/o control operation. Raised by ioctl(). + + - `ETXTBSY`: Won't open executable that's executing in write mode. + Raised by access(), copy_file_range(), execve(), mmap(), open(), + truncate(). + + - `EFBIG`: File too large. Raised by copy_file_range(), open(), + truncate(), write(). + + - `ENOSPC`: No space left on device. Raised by copy_file_range(), + fsync(), inotify_add_watch(), link(), mkdir(), mknod(), msgget(), + open(), rename(), semget(), shmget(), symlink(), + sync_file_range(), write(). + + - `EDQUOT`: Disk quota exceeded. Raised by link(), mkdir(), + mknod(), open(), rename(), symlink(), write() + + - `ESPIPE`: Invalid seek. Raised by lseek(), splice(), + sync_file_range(). + + - `EROFS`: Read-only filesystem. Raised by access(), bind(), + chmod(), chown(), link(), mkdir(), mknod(), open(), rename(), + rmdir(), symlink(), truncate(), unlink(), utime(), utimensat() + + - `EMLINK`: Too many links; raised by link(), mkdir(), rename() + + - `EPIPE`: Broken pipe. Raised by send(), write(). + + - `ERANGE`: Result too large. Raised by prctl(), semop(). + + - `EDEADLK`: Resource deadlock avoided. Raised by fcntl(). + + - `ENAMETOOLONG`: Filename too long. Raised by access(), bind(), + chdir(), chmod(), chown(), chroot(), execve(), gethostname(), + inotify_add_watch(), link(), mkdir(), mknod(), open(), + readlink(), rename(), rmdir(), stat(), symlink(), + truncate(), u unlink(), utimensat() + + - `ENOLCK`: No locks available. Raised by fcntl(), flock(). + + - `ENOTEMPTY`: Directory not empty. Raised by rmdir(). + + - `ELOOP`: Too many levels of symbolic links. Raised by access(), + bind(), chdir(), chmod(), chown(), chroot(), execve(), link(), + mkdir(), mknod(), open(), readlink(), rename(), rmdir(), stat(), + symlink(), truncate(), unlink(), utimensat(). + + - `ENOMSG`: Raised by msgop(). + + - `EIDRM`: Identifier removed. Raised by msgctl(), msgget(), + msgop(), shmget(). + + - `ETIME`: Timer expired; timer expired. Raised by connect(). + + - `EPROTO`: Raised by accept(), connect(), socket(), socketpair(). + + - `EOVERFLOW`: Raised by copy_file_range(), fanotify_init(), + lseek(), mmap(), open(), stat(), statfs() + + - `ENOTSOCK`: Not a socket. Raised by accept(), bind(), + connect(), getpeername(), getsockname(), getsockopt(), + listen(), recv(), send(), shutdown(). + + - `EDESTADDRREQ`: Destination address required. Raised by send(), + write(). + + - `EMSGSIZE`: Message too long. Raised by send(). + + - `EPROTOTYPE`: Protocol wrong type for socket. Raised by + connect(). + + - `ENOPROTOOPT`: Protocol not available. Raised by getsockopt(), + accept(). + + - `EPROTONOSUPPORT`: Protocol not supported. Raised by socket(), + socketpair(). + + - `ESOCKTNOSUPPORT`: Socket type not supported. + + - `ENOTSUP`: Operation not supported. Raised by chmod(), + clock_getres(), clock_nanosleep(), timer_create() + + - `EOPNOTSUPP`: Socket operation not supported. Raised by accept(), + listen(), mmap(), prctl(), readv(), send(), socketpair(), + + - `EPFNOSUPPORT`: protocol family not supported + + - `EAFNOSUPPORT`: address family not supported. Raised by + connect(), socket(), socketpair() + + - `EADDRINUSE`: address already in use. Raised by bind(), + connect(), listen() + + - `EADDRNOTAVAIL`: address not available. Raised by bind(), + connect(). + + - `ENETDOWN`: network is down; ; WSAENETDOWN. Raised + by accept() + + - `ENETUNREACH`: host is unreachable; ; + WSAENETUNREACH. Raised by accept(), connect() + + - `ENETRESET`: connection reset by network + + - `ECONNABORTED`: connection reset before accept. Raised by + accept() + + - `ECONNRESET`: connection reset by client. Raised by send(), + + - `ENOBUFS`: no buffer space available; + raised by getpeername(), getsockname(), send(), + + - `EISCONN`: socket is connected. Raised by + connect(), send(). + + - `ENOTCONN`: socket is not connected. Raised by getpeername(), + recv(), send(), shutdown(), + + - `ESHUTDOWN`: cannot send after transport endpoint shutdown; note + that shutdown write is an `EPIPE` + + - `ETOOMANYREFS`: too many references: cannot splice. Raised by + sendmsg(), + + - `ETIMEDOUT`: connection timed out; ; WSAETIMEDOUT; raised by + connect(), + + - `ECONNREFUSED`: system-imposed limit on the number of threads was + encountered.; WSAECONNREFUSED. Raised by connect(), listen(), + recv() + + - `EHOSTDOWN`: Host is down. Raised by accept() + + - `EHOSTUNREACH`: Host is unreachable. Raised by accept() + + - `EALREADY`: Connection already in progress. Raised by connect(), + send() + + - `ENODATA`: No message is available in xsi stream or named pipe is + being closed; no data available; barely in posix; returned by + ioctl; very close in spirit to EPIPE? - unix.opendir(path) → UnixDir*, errno - unix.opendir(fd) → UnixDir*, errno - UnixDir:close() - may be called multiple times - called by the garbage collector too - UnixDir:read() → name, kind, ino, off - returns nil if no more entries - kind can be DT_UNKNOWN/REG/DIR/BLK/LNK/CHR/FIFO/SOCK - UnixDir:fd() → fd, errno - EOPNOTSUPP if using /zip/ - EOPNOTSUPP if IsWindows() - UnixDir:tell() → off - UnixDir:rewind() CONSTANTS diff --git a/tool/net/lunix.c b/tool/net/lunix.c index ab35ccd75..f11628947 100644 --- a/tool/net/lunix.c +++ b/tool/net/lunix.c @@ -47,8 +47,10 @@ #include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/itimer.h" #include "libc/sysv/consts/msg.h" +#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/ok.h" +#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/sig.h" @@ -132,12 +134,11 @@ static void FreeStringList(char **p) { // System Calls // unix.exit([exitcode]) → ⊥ -static int LuaUnixExit(lua_State *L) { +static wontreturn int LuaUnixExit(lua_State *L) { _Exit(luaL_optinteger(L, 1, 0)); - unreachable; } -// unix.access(path, mode) → rc, errno +// unix.access(path, mode) → rc[, errno] // mode can be: R_OK, W_OK, X_OK, F_OK static int LuaUnixAccess(lua_State *L) { const char *file; @@ -149,7 +150,7 @@ static int LuaUnixAccess(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.mkdir(path, mode) → rc, errno +// unix.mkdir(path, mode) → rc[, errno] // mode should be octal static int LuaUnixMkdir(lua_State *L) { const char *file; @@ -161,7 +162,7 @@ static int LuaUnixMkdir(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.chdir(path) → rc, errno +// unix.chdir(path) → rc[, errno] static int LuaUnixChdir(lua_State *L) { int rc, olderr; const char *file; @@ -171,7 +172,7 @@ static int LuaUnixChdir(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.unlink(path) → rc, errno +// unix.unlink(path) → rc[, errno] static int LuaUnixUnlink(lua_State *L) { int rc, olderr; const char *file; @@ -181,7 +182,7 @@ static int LuaUnixUnlink(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.rmdir(path) → rc, errno +// unix.rmdir(path) → rc[, errno] static int LuaUnixRmdir(lua_State *L) { const char *file; int rc, olderr; @@ -191,7 +192,7 @@ static int LuaUnixRmdir(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.rename(oldpath, newpath) → rc, errno +// unix.rename(oldpath, newpath) → rc[, errno] static int LuaUnixRename(lua_State *L) { const char *oldpath, *newpath; int rc, olderr; @@ -202,7 +203,7 @@ static int LuaUnixRename(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.link(existingpath, newpath) → rc, errno +// unix.link(existingpath, newpath) → rc[, errno] static int LuaUnixLink(lua_State *L) { const char *existingpath, *newpath; int rc, olderr; @@ -213,7 +214,7 @@ static int LuaUnixLink(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.symlink(target, linkpath) → rc, errno +// unix.symlink(target, linkpath) → rc[, errno] static int LuaUnixSymlink(lua_State *L) { const char *target, *linkpath; int rc, olderr; @@ -224,7 +225,7 @@ static int LuaUnixSymlink(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.chown(path, uid, gid) → rc, errno +// unix.chown(path, uid, gid) → rc[, errno] static int LuaUnixChown(lua_State *L) { const char *file; int rc, uid, gid, olderr; @@ -236,7 +237,7 @@ static int LuaUnixChown(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.chmod(path, mode) → rc, errno +// unix.chmod(path, mode) → rc[, errno] static int LuaUnixChmod(lua_State *L) { const char *file; int rc, mode, olderr; @@ -247,7 +248,7 @@ static int LuaUnixChmod(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.getcwd(path, mode) → rc, errno +// unix.getcwd(path, mode) → rc[, errno] static int LuaUnixGetcwd(lua_State *L) { char *path; path = getcwd(0, 0); @@ -297,24 +298,65 @@ static int LuaUnixExecve(lua_State *L) { return 1; } -// unix.commandv(prog) → path, errno +// unix.commandv(prog) → path[, errno] static int LuaUnixCommandv(lua_State *L) { - int olderr; const char *prog; + int rc, olderr, pushed; char *pathbuf, *resolved; olderr = errno; pathbuf = xmalloc(PATH_MAX); prog = luaL_checkstring(L, 1); if ((resolved = commandv(prog, pathbuf))) { lua_pushstring(L, resolved); - lua_pushnil(L); + pushed = 1; } else { lua_pushnil(L); lua_pushinteger(L, errno); errno = olderr; + pushed = 2; } free(pathbuf); - return 2; + return pushed; +} + +// unix.chroot(path) → rc[, errno] +static int LuaUnixChroot(lua_State *L) { + int rc, olderr; + const char *path; + olderr = errno; + path = luaL_checkstring(L, 1); + rc = chroot(path); + return ReturnRc(L, rc, olderr); +} + +// unix.setrlimit(resource:int, soft:int[, hard:int]) → rc:int[, errno:int] +static int LuaUnixSetrlimit(lua_State *L) { + struct rlimit rlim; + int rc, olderr, resource; + olderr = errno; + resource = luaL_checkinteger(L, 1); + rlim.rlim_cur = luaL_checkinteger(L, 2); + rlim.rlim_max = luaL_optinteger(L, 3, rlim.rlim_cur); + return ReturnRc(L, setrlimit(resource, &rlim), olderr); +} + +// unix.getrlimit(resource:int) → soft:int, hard:int[, errno:int] +static int LuaUnixGetrlimit(lua_State *L) { + struct rlimit rlim; + int rc, olderr, resource; + olderr = errno; + resource = luaL_checkinteger(L, 1); + if (!getrlimit(resource, &rlim)) { + lua_pushinteger(L, rlim.rlim_cur); + lua_pushinteger(L, rlim.rlim_max); + return 2; + } else { + lua_pushnil(L); + lua_pushnil(L); + lua_pushinteger(L, errno); + errno = olderr; + return 3; + } } // unix.getpid() → pid @@ -329,7 +371,7 @@ static int LuaUnixGetppid(lua_State *L) { return 1; } -// unix.kill(pid, sig) → rc, errno +// unix.kill(pid, sig) → rc[, errno] static int LuaUnixKill(lua_State *L) { int rc, pid, sig, olderr; olderr = errno; @@ -339,7 +381,7 @@ static int LuaUnixKill(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.raise(sig) → rc, errno +// unix.raise(sig) → rc[, errno] static int LuaUnixRaise(lua_State *L) { int rc, sig, olderr; olderr = errno; @@ -369,7 +411,7 @@ static int LuaUnixWait(lua_State *L) { } } -// unix.fcntl(fd, cmd[, arg]) → rc, errno +// unix.fcntl(fd, cmd[, arg]) → rc[, errno] static int LuaUnixFcntl(lua_State *L) { intptr_t arg; int rc, fd, cmd, olderr; @@ -442,7 +484,7 @@ static int LuaUnixGetpgid(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.umask(mask) → rc, errno +// unix.umask(mask) → rc[, errno] static int LuaUnixUmask(lua_State *L) { int rc, mask, olderr; olderr = errno; @@ -532,7 +574,7 @@ static int LuaUnixSync(lua_State *L) { return 0; } -// unix.fsync(fd) → rc, errno +// unix.fsync(fd) → rc[, errno] static int LuaUnixFsync(lua_State *L) { int rc, fd, olderr; olderr = errno; @@ -541,7 +583,7 @@ static int LuaUnixFsync(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.fdatasync(fd) → rc, errno +// unix.fdatasync(fd) → rc[, errno] static int LuaUnixFdatasync(lua_State *L) { int rc, fd, olderr; olderr = errno; @@ -562,7 +604,7 @@ static int LuaUnixOpen(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.close(fd) → rc, errno +// unix.close(fd) → rc[, errno] static int LuaUnixClose(lua_State *L) { int rc, fd, olderr; olderr = errno; @@ -585,8 +627,8 @@ static int LuaUnixSeek(lua_State *L) { return ReturnRc(L, newpos, olderr); } -// unix.truncate(path, length) → rc, errno -// unix.truncate(fd, length) → rc, errno +// unix.truncate(path, length) → rc[, errno] +// unix.truncate(fd, length) → rc[, errno] static int LuaUnixTruncate(lua_State *L) { int64_t length; const char *path; @@ -611,7 +653,7 @@ static int LuaUnixTruncate(lua_State *L) { static int LuaUnixRead(lua_State *L) { char *buf; size_t got; - int fd, olderr; + int fd, olderr, pushed; int64_t rc, bufsiz, offset; olderr = errno; fd = luaL_checkinteger(L, 1); @@ -627,17 +669,18 @@ static int LuaUnixRead(lua_State *L) { if (rc != -1) { got = rc; lua_pushlstring(L, buf, got); - lua_pushnil(L); + pushed = 1; } else { lua_pushnil(L); lua_pushinteger(L, errno); errno = olderr; + pushed = 2; } free(buf); - return 2; + return pushed; } -// unix.write(fd, data[, offset]) → rc, errno +// unix.write(fd, data[, offset]) → rc[, errno] static int LuaUnixWrite(lua_State *L) { size_t size; int fd, olderr; @@ -656,8 +699,8 @@ static int LuaUnixWrite(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.stat(path) → UnixStat*, errno -// unix.stat(fd) → UnixStat*, errno +// unix.stat(path) → UnixStat*[, errno] +// unix.stat(fd) → UnixStat*[, errno] static int LuaUnixStat(lua_State *L) { const char *path; int rc, fd, olderr; @@ -688,8 +731,8 @@ static int LuaUnixStat(lua_State *L) { return 1; } -// unix.opendir(path) → UnixDir*, errno -// unix.opendir(fd) → UnixDir*, errno +// unix.opendir(path) → UnixDir*[, errno] +// unix.opendir(fd) → UnixDir*[, errno] static int LuaUnixOpendir(lua_State *L) { DIR *rc; int fd, olderr; @@ -738,7 +781,7 @@ static int LuaUnixSocket(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.socketpair([family[, type[, protocol]]]) → fd1, fd2, errno +// unix.socketpair([family[, type[, protocol]]]) → fd1, fd2[, errno] // SOCK_CLOEXEC may be or'd into type // family defaults to AF_INET // type defaults to SOCK_STREAM @@ -762,7 +805,7 @@ static int LuaUnixSocketpair(lua_State *L) { } } -// unix.bind(fd, ip, port) → rc, errno +// unix.bind(fd, ip, port) → rc[, errno] // SOCK_CLOEXEC may be or'd into type // family defaults to AF_INET // type defaults to SOCK_STREAM @@ -779,7 +822,7 @@ static int LuaUnixBind(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.connect(fd, ip, port) → rc, errno +// unix.connect(fd, ip, port) → rc[, errno] // SOCK_CLOEXEC may be or'd into type // family defaults to AF_INET // type defaults to SOCK_STREAM @@ -796,7 +839,7 @@ static int LuaUnixConnect(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.listen(fd[, backlog]) → rc, errno +// unix.listen(fd[, backlog]) → rc[, errno] static int LuaUnixListen(lua_State *L) { int rc, fd, olderr, backlog; olderr = errno; @@ -875,7 +918,7 @@ static int LuaUnixAccept(lua_State *L) { } } -// unix.recvfrom(fd[, bufsiz[, flags]]) → data, ip, port, errno +// unix.recvfrom(fd[, bufsiz[, flags]]) → data, ip, port[, errno] // flags can have MSG_{WAITALL,DONTROUTE,PEEK,OOB}, etc. static int LuaUnixRecvfrom(lua_State *L) { char *buf; @@ -883,7 +926,7 @@ static int LuaUnixRecvfrom(lua_State *L) { ssize_t rc; uint32_t addrsize; struct sockaddr_in sa; - int fd, flags, bufsiz, olderr; + int fd, flags, bufsiz, olderr, pushed; olderr = errno; bzero(&sa, sizeof(sa)); addrsize = sizeof(sa); @@ -898,24 +941,25 @@ static int LuaUnixRecvfrom(lua_State *L) { lua_pushlstring(L, buf, got); lua_pushinteger(L, ntohl(sa.sin_addr.s_addr)); lua_pushinteger(L, ntohs(sa.sin_port)); - lua_pushnil(L); + pushed = 3; } else { lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushinteger(L, errno); errno = olderr; + pushed = 4; } free(buf); - return 4; + return pushed; } -// unix.recv(fd[, bufsiz[, flags]]) → data, errno +// unix.recv(fd[, bufsiz[, flags]]) → data[, errno] static int LuaUnixRecv(lua_State *L) { char *buf; size_t got; ssize_t rc; - int fd, flags, bufsiz, olderr; + int fd, flags, bufsiz, olderr, pushed; olderr = errno; fd = luaL_checkinteger(L, 1); bufsiz = luaL_optinteger(L, 2, 1500); @@ -926,14 +970,15 @@ static int LuaUnixRecv(lua_State *L) { if (rc != -1) { got = rc; lua_pushlstring(L, buf, got); - lua_pushnil(L); + pushed = 1; } else { lua_pushnil(L); lua_pushinteger(L, errno); errno = olderr; + pushed = 2; } free(buf); - return 4; + return pushed; } // unix.send(fd, data[, flags]) → sent, errno @@ -971,7 +1016,7 @@ static int LuaUnixSendto(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.shutdown(fd, how) → rc, errno +// unix.shutdown(fd, how) → rc[, errno] // how can be SHUT_RD, SHUT_WR, or SHUT_RDWR static int LuaUnixShutdown(lua_State *L) { int rc, fd, how, olderr; @@ -982,7 +1027,7 @@ static int LuaUnixShutdown(lua_State *L) { return ReturnRc(L, rc, olderr); } -// unix.sigprocmask(how[, mask]) → oldmask, errno +// unix.sigprocmask(how[, mask]) → oldmask[, errno] // how can be SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK static int LuaUnixSigprocmask(lua_State *L) { uint64_t imask; @@ -1025,7 +1070,7 @@ static void LuaUnixOnSignal(int sig, siginfo_t *si, ucontext_t *ctx) { } } -// unix.sigaction(sig[, handler[, flags[, mask]]]) → handler, flags, mask, errno +// unix.sigaction(sig[,handler[,flags[,mask]]]) → handler,flags,mask[,errno] // // unix = require "unix" // unix.sigaction(unix.SIGUSR1, function(sig) @@ -1109,7 +1154,7 @@ static int LuaUnixSigaction(lua_State *L) { lua_pushnil(L); lua_pushinteger(L, errno); errno = olderr; - return 2; + return 4; } } @@ -1127,7 +1172,7 @@ static int LuaUnixSigsuspend(lua_State *L) { } // unix.setitimer(which[, intsec, intmicros, valsec, valmicros]) -// → intsec, intns, valsec, valns, errno +// → intsec, intns, valsec, valns[, errno] // // ticks = 0 // unix.sigaction(unix.SIGALRM, function(sig) @@ -1244,6 +1289,10 @@ static int LuaUnixStatCtim(lua_State *L) { return ReturnTimespec(L, &GetUnixStat(L)->st_ctim); } +static int LuaUnixStatBirthtim(lua_State *L) { + return ReturnTimespec(L, &GetUnixStat(L)->st_birthtim); +} + static void FreeUnixStat(struct UnixStat *stat) { if (!--stat->refs) { free(stat); @@ -1261,20 +1310,21 @@ static int LuaUnixStatGc(lua_State *L) { } static const luaL_Reg kLuaUnixStatMeth[] = { - {"size", LuaUnixStatSize}, // - {"mode", LuaUnixStatMode}, // - {"dev", LuaUnixStatDev}, // - {"ino", LuaUnixStatIno}, // - {"nlink", LuaUnixStatNlink}, // - {"rdev", LuaUnixStatRdev}, // - {"uid", LuaUnixStatUid}, // - {"gid", LuaUnixStatGid}, // - {"atim", LuaUnixStatAtim}, // - {"mtim", LuaUnixStatMtim}, // - {"ctim", LuaUnixStatCtim}, // - {"blocks", LuaUnixStatBlocks}, // - {"blksize", LuaUnixStatBlksize}, // - {0}, // + {"size", LuaUnixStatSize}, // + {"mode", LuaUnixStatMode}, // + {"dev", LuaUnixStatDev}, // + {"ino", LuaUnixStatIno}, // + {"nlink", LuaUnixStatNlink}, // + {"rdev", LuaUnixStatRdev}, // + {"uid", LuaUnixStatUid}, // + {"gid", LuaUnixStatGid}, // + {"atim", LuaUnixStatAtim}, // + {"mtim", LuaUnixStatMtim}, // + {"ctim", LuaUnixStatCtim}, // + {"birthtim", LuaUnixStatBirthtim}, // + {"blocks", LuaUnixStatBlocks}, // + {"blksize", LuaUnixStatBlksize}, // + {0}, // }; static const luaL_Reg kLuaUnixStatMeta[] = { @@ -1307,38 +1357,49 @@ static DIR *GetDirOrDie(lua_State *L) { unreachable; } -static void FreeUnixDir(struct UnixDir *dir) { - if (!--dir->refs) { - closedir(dir->dir); - } +static int FreeUnixDir(struct UnixDir *dir) { + if (--dir->refs) return 0; + return closedir(dir->dir); } -// UnixDir:close() +// UnixDir:close() → rc[, errno] // may be called multiple times // called by the garbage collector too static int LuaUnixDirClose(lua_State *L) { + int rc, olderr; struct UnixDir **udir; udir = GetUnixDirSelf(L); - if (*udir) { - FreeUnixDir(*udir); - *udir = 0; - } - return 0; + if (!*udir) return 0; + olderr = 0; + rc = FreeUnixDir(*udir); + *udir = 0; + return ReturnRc(L, rc, olderr); } -// UnixDir:read() → name, kind, ino, off +// UnixDir:read() → name, kind, ino, off[, errno] // returns nil if no more entries // kind can be DT_UNKNOWN/REG/DIR/BLK/LNK/CHR/FIFO/SOCK static int LuaUnixDirRead(lua_State *L) { + int olderr; struct dirent *ent; + olderr = errno; + errno = 0; if ((ent = readdir(GetDirOrDie(L)))) { lua_pushlstring(L, ent->d_name, strnlen(ent->d_name, sizeof(ent->d_name))); lua_pushinteger(L, ent->d_type); lua_pushinteger(L, ent->d_ino); lua_pushinteger(L, ent->d_off); return 4; + } else if (!ent && !errno) { + return 0; // end of listing } else { - return 0; + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + lua_pushinteger(L, errno); + errno = olderr; + return 5; } } @@ -1433,7 +1494,10 @@ static const luaL_Reg kLuaUnix[] = { {"fsync", LuaUnixFsync}, // flush open file {"fdatasync", LuaUnixFdatasync}, // flush open file w/o metadata {"truncate", LuaUnixTruncate}, // shrink or extend file medium - {"umask", LuaUnixUmask}, // set file mode creation mask + {"umask", LuaUnixChroot}, // change root directory + {"chroot", LuaUnixGetppid}, // get parent process id + {"setrlimit", LuaUnixSetrlimit}, // prevent cpu memory bombs + {"getrlimit", LuaUnixGetrlimit}, // query resource limits {"getppid", LuaUnixGetppid}, // get parent process id {"getpgrp", LuaUnixGetpgrp}, // get process group id {"getpgid", LuaUnixGetpgid}, // get process group id of pid @@ -1544,6 +1608,13 @@ int LuaUnix(lua_State *L) { LuaSetIntField(L, "X_OK", X_OK); LuaSetIntField(L, "F_OK", F_OK); + // rlimit() resources + LuaSetIntField(L, "RLIMIT_AS", RLIMIT_AS); + LuaSetIntField(L, "RLIMIT_CPU", RLIMIT_CPU); + LuaSetIntField(L, "RLIMIT_FSIZE", RLIMIT_FSIZE); + LuaSetIntField(L, "RLIMIT_NPROC", RLIMIT_NPROC); + LuaSetIntField(L, "RLIMIT_NOFILE", RLIMIT_NOFILE); + // wait() options LuaSetIntField(L, "WNOHANG", WNOHANG); diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 2b33d50bf..8c2b5b50d 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -22,6 +22,7 @@ #include "libc/bits/popcnt.h" #include "libc/bits/safemacros.internal.h" #include "libc/calls/calls.h" +#include "libc/calls/issandboxed.h" #include "libc/calls/math.h" #include "libc/calls/sigbits.h" #include "libc/calls/strace.internal.h" @@ -52,6 +53,7 @@ #include "libc/nexgen32e/rdtsc.h" #include "libc/nexgen32e/rdtscp.h" #include "libc/nt/enum/fileflagandattributes.h" +#include "libc/nt/runtime.h" #include "libc/rand/rand.h" #include "libc/runtime/clktck.h" #include "libc/runtime/directmap.internal.h" @@ -81,11 +83,14 @@ #include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" +#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/poll.h" +#include "libc/sysv/consts/pr.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/rusage.h" #include "libc/sysv/consts/s.h" +#include "libc/sysv/consts/seccomp.h" #include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/so.h" @@ -180,6 +185,11 @@ STATIC_YOINK("zip_uri_support"); #define HeaderEqualCase(H, S) \ SlicesEqualCase(S, strlen(S), HeaderData(H), HeaderLength(H)) +// letters not used: EIJNOQWXYinoqwxy +// digits not used: 0123456789 +// puncts not used: !"#$%&'()*+,-./;<=>@[\]^_`{|}~ +#define GETOPTS "BSVZabdfghjkmsuvzA:C:D:F:G:H:K:L:M:P:R:T:U:c:e:l:p:r:t:" + static const uint8_t kGzipHeader[] = { 0x1F, // MAGNUM 0x8B, // MAGNUM @@ -345,6 +355,7 @@ static bool zombied; static bool gzipped; static bool branded; static bool funtrace; +static bool systrace; static bool meltdown; static bool printport; static bool daemonize; @@ -356,6 +367,7 @@ static bool terminated; static bool uniprocess; static bool invalidated; static bool logmessages; +static bool issandboxed; static bool isinitialized; static bool checkedmethod; static bool sslinitialized; @@ -5817,7 +5829,7 @@ static void HandleHeartbeat(void) { LuaRunAsset("/.heartbeat.lua", false); CollectGarbage(); #endif - for (i = 0; i < servers.n; ++i) { + for (i = 1; i < servers.n; ++i) { if (polls[i].fd < 0) { polls[i].fd = -polls[i].fd; } @@ -6569,12 +6581,11 @@ static void CloseServerFds(void) { } static int ExitWorker(void) { - if (!IsModeDbg()) { - _Exit(0); - } else { + if (IsModeDbg() && !issandboxed) { isexitingworker = true; return eintr(); } + _Exit(0); } // returns 0 otherwise -1 if worker needs to unwind stack and exit @@ -6597,8 +6608,9 @@ static int HandleConnection(size_t i) { case 0: meltdown = false; connectionclose = false; - if (funtrace && !IsTiny()) { - ftrace_install(); + if (!IsTiny()) { + if (systrace) __strace = 1; + if (funtrace) ftrace_install(); } if (hasonworkerstart) { CallSimpleHook("OnWorkerStart"); @@ -6990,19 +7002,19 @@ static void MemDestroy(void) { static void GetOpts(int argc, char *argv[]) { int opt; bool storeasset = false; - while ((opt = getopt(argc, argv, - "jkazhdugvVsmbfB" - "e:A:l:p:r:R:H:c:L:P:U:G:D:t:M:C:K:F:T:")) != -1) { + while ((opt = getopt(argc, argv, GETOPTS)) != -1) { switch (opt) { CASE('v', ++__log_level); CASE('s', --__log_level); CASE('f', funtrace = true); + CASE('Z', systrace = true); CASE('b', logbodies = true); CASE('z', printport = true); CASE('d', daemonize = true); CASE('a', logrusage = true); CASE('u', uniprocess = true); CASE('g', loglatency = true); + CASE('S', issandboxed = true); CASE('m', logmessages = true); CASE('l', ProgramAddr(optarg)); CASE('H', ProgramHeader(optarg)); diff --git a/tool/viz/getopts.c b/tool/viz/getopts.c new file mode 100644 index 000000000..531806593 --- /dev/null +++ b/tool/viz/getopts.c @@ -0,0 +1,188 @@ +/*-*- 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/stdio/stdio.h" +#include "libc/str/str.h" + +/** + * @fileoverview Tool for printing which getopt() letters are used, e.g. + * + * o//tool/viz/getopts.com jkazhdugvVsmbBfe:A:l:p:r:R:H + */ + +int letters_used[256]; +bool letters_with_args[256]; + +bool IsLegal(int c) { + return isgraph(c) && c != ':' && c != '?'; +} + +int main(int argc, char *argv[]) { + int i, j; + bool hasargless; + + for (i = 1; i < argc; ++i) { + for (j = 0; argv[i][j]; ++j) { + ++letters_used[argv[i][j] & 255]; + if (argv[i][j + 1] == ':') { + letters_with_args[argv[i][j] & 255] = true; + } + } + } + + // usage report + fprintf(stderr, "options used: "); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i]) { + if (j++) fprintf(stderr, ""); + fprintf(stderr, "%c", i); + } + } + if (!j) fprintf(stderr, "none"); + fprintf(stderr, "\n"); + fprintf(stderr, "letters not used: "); + for (j = i = 0; i < 128; ++i) { + if (!isalpha(i)) continue; + if (!letters_used[i]) { + if (j++) fprintf(stderr, ""); + fprintf(stderr, "%c", i); + } + } + if (!j) fprintf(stderr, "none"); + fprintf(stderr, "\n"); + fprintf(stderr, "digits not used: "); + for (j = i = 0; i < 128; ++i) { + if (!isdigit(i)) continue; + if (!letters_used[i]) { + if (j++) fprintf(stderr, ""); + fprintf(stderr, "%c", i); + } + } + if (!j) fprintf(stderr, "none"); + fprintf(stderr, "\n"); + fprintf(stderr, "puncts not used: "); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (isalnum(i)) continue; + if (!letters_used[i]) { + if (j++) fprintf(stderr, ""); + fprintf(stderr, "%c", i); + } + } + if (!j) fprintf(stderr, "none"); + fprintf(stderr, "\n"); + fprintf(stderr, "letters duplicated: "); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i] > 1) { + if (j++) fprintf(stderr, ""); + fprintf(stderr, "%c", i); + } + } + if (!j) fprintf(stderr, "none"); + fprintf(stderr, "\n"); + + // generated code + hasargless = false; + printf("\n#define GETOPTS \""); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i] && !letters_with_args[i]) { + printf("%c", i); + hasargless = true; + } + } + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i] && letters_with_args[i]) { + printf("%c:", i); + } + } + printf("\"\n"); + printf("\n#define USAGE \"\\\n"); + printf("Usage: program.com"); + if (hasargless) { + printf(" [-"); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i] && !letters_with_args[i]) { + printf("%c", i); + hasargless = true; + } + } + printf("]"); + } + printf(" ARGS...\\n\\\n"); + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i]) { + printf(" -%c the %c option\\n\\\n", i, i); + } + } + for (j = i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i]) { + printf(" -%c VAL the %c option\\n\\\n", i, i); + } + } + printf("\"\n\n"); + + for (i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i]) { + if (isalpha(i) || i == '_') { + printf("int %cflag;\n", i); + } + } + } + + printf("\n\ +static void GetOpts(int argc, char *argv[]) {\n\ + while ((opt = getopt(argc, argv, GETOPTS)) != -1) {\n\ + switch (opt) {\n"); + for (i = 0; i < 128; ++i) { + if (!IsLegal(i)) continue; + if (letters_used[i]) { + printf(" case '%c':\n", i); + if (isalpha(i) || i == '_') { + printf(" %cflag", i); + } else { + printf(" XXXflag", i); + } + if (letters_with_args[i]) { + printf(" = optarg;\n"); + } else { + printf("++;\n"); + } + printf(" break;\n"); + } + } + + printf(" case '?':\n"); + printf(" write(1, USAGE, strlen(USAGE));\n"); + printf(" exit(0);\n"); + printf(" default:\n"); + printf(" write(2, USAGE, strlen(USAGE));\n"); + printf(" exit(64);\n"); + printf(" }\n"); + printf(" }\n"); + printf("}\n"); + + return 0; +}