Compare commits

..
1 Commits
Author SHA1 Message Date
Justine Tunney af2ef0d223 Fix the build 2022-10-14 11:18:40 -07:00
578 changed files with 3939 additions and 13071 deletions

No files matched your search

+2 -4
View File
@@ -60,7 +60,7 @@
# build/config.mk
SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10 win10:31336
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win10 xnu
MAKEFLAGS += -j --no-builtin-rules
.SUFFIXES:
@@ -92,7 +92,6 @@ o/$(MODE): \
.UNVEIL = \
libc/integral \
libc/disclaimer.inc \
rwc:/dev/shm \
rx:build/bootstrap \
rx:o/third_party/gcc \
/proc/stat \
@@ -128,7 +127,6 @@ include ape/ape.mk # │
include libc/fmt/fmt.mk # │
include libc/vga/vga.mk #─┘
include libc/calls/calls.mk #─┐
include third_party/getopt/getopt.mk # │
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
include libc/crt/crt.mk # │ You can issue system calls
include third_party/nsync/nsync.mk # │
@@ -152,6 +150,7 @@ include dsp/mpeg/mpeg.mk # │
include dsp/dsp.mk # │
include third_party/zlib/gz/gz.mk # │
include third_party/musl/musl.mk # │
include third_party/getopt/getopt.mk # │
include libc/libc.mk #─┘
include libc/sock/sock.mk #─┐
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
@@ -172,7 +171,6 @@ include third_party/maxmind/maxmind.mk
include net/finger/finger.mk
include third_party/double-conversion/test/test.mk
include third_party/lua/lua.mk
include third_party/tr/tr.mk
include third_party/sed/sed.mk
include third_party/awk/awk.mk
include third_party/make/make.mk
+1 -5
View File
@@ -246,16 +246,12 @@ gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| Linux | 2.6.18 | 2007 |
| Windows | 8 [1] | 2012 |
| Windows | 8 | 2012 |
| Mac OS X | 15.6 | 2018 |
| OpenBSD | 6.4 | 2018 |
| FreeBSD | 13 | 2020 |
| NetBSD | 9.2 | 2021 |
[1] See our [vista branch](https://github.com/jart/cosmopolitan/tree/vista)
for a community supported version of Cosmopolitan that works on Windows
Vista and Windows 7.
## Special Thanks
Funding for this project is crowdsourced using
+1 -9
View File
@@ -112,15 +112,7 @@ cstr: .endobj cstr,globl,hidden # ←for gdb readability
//
// @param dl is drive number
// @noreturn
ape_mz:
#if SupportsWindows() || SupportsMetal()
.asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
#else
// Avoid virus scanner reputation damage when targeting System Five.
// WARNING: This prefix is experimental; it may be removed sometime.
// TODO(jart): Find another prefix that will work with BIOS loading.
.asciz "JTqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
#endif
ape_mz: .asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
.short 0x1000 # MZ: lowers upper bound load / 16
.short 0xf800 # MZ: roll greed on bss
.short 0 # MZ: lower bound on stack segment
+1 -3
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ "$(id -u)" -eq 0 ]; then
if [ $UID -eq 0 ]; then
SUDO=
else
SUDO=sudo
@@ -97,8 +97,6 @@ if [ x"$(uname -s)" = xLinux ]; then
echo you may need to edit configs to persist across reboot >&2
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-sysv:M::JTqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-sysv:M::JTqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo done >&2
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
-4
View File
@@ -11,7 +11,6 @@ fi
echo "APE Uninstaller intends to run"
echo
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE'"
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv'"
echo " $SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo
echo "You may then use ape/apeinstall.sh to reinstall it"
@@ -22,7 +21,4 @@ set -ex
if [ -f /proc/sys/fs/binfmt_misc/APE ]; then
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit
fi
if [ -f /proc/sys/fs/binfmt_misc/APE-sysv ]; then
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE-sysv' || exit
fi
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
-30
View File
@@ -1,30 +0,0 @@
#ifndef COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern unsigned char _base[];
extern unsigned char _ehead[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char _ezip[];
extern unsigned char _end[];
extern unsigned char _ereal[];
extern unsigned char __privileged_start[];
extern unsigned char __privileged_addr[];
extern unsigned char __privileged_size[];
extern unsigned char __privileged_end[];
extern unsigned char __test_start[];
extern unsigned char __ro[];
extern unsigned char *__relo_start[];
extern unsigned char *__relo_end[];
extern uint8_t __zip_start[];
extern uint8_t __zip_end[];
extern uint8_t __data_start[];
extern uint8_t __data_end[];
extern uint8_t __bss_start[];
extern uint8_t __bss_end[];
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_ */
Binary file not shown.
Binary file not shown.
+6 -27
View File
@@ -29,7 +29,7 @@ endif
#
ifeq ($(MODE),fastbuild)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O
CONFIG_CPPFLAGS += -DSYSDEBUG -DDWARFLESS
CONFIG_CPPFLAGS += -DSYSDEBUG
CONFIG_OFLAGS += -g0
CONFIG_LDFLAGS += -S
TARGET_ARCH ?= -msse3
@@ -125,22 +125,6 @@ TARGET_ARCH ?= -msse3
OVERRIDE_CCFLAGS += -fno-pie
endif
# System Five Mode
#
# - `make MODE=sysv`
# - Optimized
# - Backtraces
# - Debuggable
# - Syscall tracing
# - Function tracing
# - No Windows bloat!
#
ifeq ($(MODE), sysv)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
TARGET_ARCH ?= -msse3
endif
# Tiny Mode
#
# - `make MODE=tiny`
@@ -167,8 +151,7 @@ CONFIG_CCFLAGS += \
-fschedule-insns2 \
-fomit-frame-pointer \
-momit-leaf-frame-pointer \
-foptimize-sibling-calls \
-DDWARFLESS
-foptimize-sibling-calls
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
@@ -198,8 +181,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=1 \
-DDWARFLESS
-DSUPPORT_VECTOR=1
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
@@ -235,8 +217,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=113 \
-DDWARFLESS
-DSUPPORT_VECTOR=113
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
@@ -271,8 +252,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=121 \
-DDWARFLESS
-DSUPPORT_VECTOR=121
DEFAULT_COPTS += \
-mred-zone
CONFIG_CCFLAGS += \
@@ -307,8 +287,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=251 \
-DDWARFLESS
-DSUPPORT_VECTOR=251
CONFIG_CCFLAGS += \
-Os \
-fno-align-functions \
+3 -9
View File
@@ -7,12 +7,12 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/dce.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/kprintf.h"
#include "libc/dce.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
@@ -59,15 +59,9 @@
int main(int argc, char *argv[]) {
if (!IsAsan()) {
kprintf("this example is intended for MODE=asan or MODE=dbg\n");
printf("this example is intended for MODE=asan or MODE=dbg\n");
exit(1);
}
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
char *buffer;
ShowCrashReports(); /* not needed but yoinks appropriate symbols */
buffer = malloc(13);
-7
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/runtime/symbols.internal.h"
@@ -25,12 +24,6 @@
*/
noubsan int main(int argc, char *argv[]) {
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
volatile int64_t x;
ShowCrashReports();
return 1 / (x = 0);
+1 -23
View File
@@ -49,12 +49,12 @@ EXAMPLES_DIRECTDEPS = \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
LIBC_NT_USER32 \
LIBC_NT_WS2_32 \
LIBC_NT_ADVAPI32 \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
@@ -71,7 +71,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_ZIPOS \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_AWK \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_DOUBLECONVERSION \
@@ -85,9 +84,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_QUICKJS \
THIRD_PARTY_SED \
THIRD_PARTY_STB \
THIRD_PARTY_TR \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
TOOL_BUILD_LIB \
@@ -146,25 +143,6 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
$(EXAMPLES_BOOTLOADER)
@$(APELINK)
# # force symtab.com to be a zip file, by pulling a zip asset into linkage
# # we wouldn't need to do this if we depended on functions like localtime
# o/$(MODE)/examples/symtab.com.dbg: \
# $(EXAMPLES_DEPS) \
# o/$(MODE)/examples/symtab.o \
# o/$(MODE)/examples/symtab.c.zip.o \
# o/$(MODE)/examples/examples.pkg \
# $(EXAMPLES_BOOTLOADER)
# @$(APELINK)
# modify .com so it can read the symbol table without needing the .com.dbg file
o/$(MODE)/examples/symtab.com: \
o/$(MODE)/examples/symtab.com.dbg \
o/$(MODE)/third_party/zip/zip.com \
o/$(MODE)/tool/build/symtab.com
@$(MAKE_OBJCOPY)
@$(MAKE_SYMTAB_CREATE)
@$(MAKE_SYMTAB_ZIP)
o/$(MODE)/examples/picol.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
-1
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/errno.h"
+1 -1
View File
@@ -47,7 +47,7 @@
#include "third_party/libcxx/vector"
#include "tool/viz/lib/knobs.h"
STATIC_YOINK("zipos");
STATIC_YOINK("zip_uri_support");
#define USAGE \
" [ROM] [FMV]\n\
-1
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "ape/sections.internal.h"
#include "libc/dce.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
-42
View File
@@ -1,42 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
/**
* @fileoverview example of how to embed symbol table in .com file
*
* # build our binary
* make -j16 o//examples/symtab.com
*
* # move binary somewhere else
* # so it can't find the .com.dbg binary
* cp o//examples/symtab.com /tmp
*
* # run program
* # notice that it has a symbolic backtrace
* /tmp/symtab.com
*
* @see examples/examples.mk
*/
int main(int argc, char *argv[]) {
// this links all the debugging and zip functionality
ShowCrashReports();
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
volatile int64_t x;
return 1 / (x = 0);
}
+6 -13
View File
@@ -7,20 +7,13 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/runtime/runtime.h"
#include "libc/dce.h"
#include "libc/stdio/stdio.h"
/**
* @fileoverview Cosmopolitan Command Interpreter Demo
* Yes this works on Windows.
*/
STATIC_YOINK("_tr");
STATIC_YOINK("_sed");
int main(int argc, char *argv[]) {
system("x=world\n"
"echo hello $x |\n"
" tr a-z A-Z |\n"
" sed 's/\\(.\\)/\\1 /g'");
if (IsWindows()) {
system("notepad");
} else {
system("ls | tr a-z A-Z");
}
}
+3 -3
View File
@@ -17,7 +17,7 @@ void __assert_fail(const char *, const char *, int) hidden relegated;
#endif
#ifdef __GNUC__
#if !defined(TINY) && !defined(MODE_DBG)
#ifndef TINY
/**
* Specifies expression can't possibly be false.
*
@@ -36,7 +36,7 @@ void __assert_fail(const char *, const char *, int) hidden relegated;
* In `MODE=tiny` these assertions are redefined as undefined behavior.
*/
#define _npassert(x) \
__extension__({ \
({ \
if (__builtin_expect(!(x), 0)) { \
notpossible; \
} \
@@ -63,7 +63,7 @@ void __assert_fail(const char *, const char *, int) hidden relegated;
* that's capable of debugging this macro.
*/
#define _unassert(x) \
__extension__({ \
({ \
if (__builtin_expect(!(x), 0)) { \
unreachable; \
} \
+6 -3
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/sig.internal.h"
@@ -108,6 +107,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
STRACE("delivering %G", sig);
// enter the signal
__sig_lock();
rva = __sighandrvas[sig];
flags = __sighandflags[sig];
if ((~flags & SA_NODEFER) || (flags & SA_RESETHAND)) {
@@ -118,6 +118,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
// signal handler. in that case you must use SA_NODEFER.
__sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL;
}
__sig_unlock();
// setup the somewhat expensive information args
// only if they're requested by the user in sigaction()
@@ -139,9 +140,11 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
// since sigaction() is @asyncsignalsafe we only restore it if the
// user didn't change it during the signal handler. we also don't
// need to do anything if this was a oneshot signal or nodefer.
__sig_lock();
if (__sighandrvas[sig] == (int32_t)(intptr_t)SIG_DFL) {
__sighandrvas[sig] = rva;
}
__sig_unlock();
}
if (!restartable) {
@@ -224,12 +227,12 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
int rc;
struct Signal *mem;
if (1 <= sig && sig <= 64) {
__sig_lock();
if (__sighandrvas[sig] == (unsigned)(intptr_t)SIG_IGN) {
STRACE("ignoring %G", sig);
rc = 0;
} else {
STRACE("enqueuing %G", sig);
__sig_lock();
++__sig_count;
if ((mem = __sig_alloc())) {
mem->tid = tid;
@@ -241,8 +244,8 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
} else {
rc = enomem();
}
__sig_unlock();
}
__sig_unlock();
} else {
rc = einval();
}
+1 -6
View File
@@ -16,9 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/tls.h"
@@ -47,10 +45,7 @@ textwindows int __sig_mask(int how, const sigset_t *neu, sigset_t *old) {
} else {
x = y;
}
x &= ~(0
#define M(x) | GetSigBit(x)
#include "libc/intrin/sigisprecious.inc"
);
x &= ~(GetSigBit(SIGKILL) | GetSigBit(SIGSTOP) | GetSigBit(SIGABRT));
*mask = x;
}
return 0;
-19
View File
@@ -1,19 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_INTERNAL_H_
#include "libc/calls/struct/sigset.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define BLOCK_SIGNALS \
do { \
sigset_t _SigMask; \
_SigMask = _sigblockall()
#define ALLOW_SIGNALS \
_sigsetmask(_SigMask); \
} \
while (0)
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_INTERNAL_H_ */
+42 -42
View File
@@ -65,13 +65,13 @@ char *ttyname(int);
int access(const char *, int) dontthrow;
int arch_prctl();
int chdir(const char *);
int chmod(const char *, unsigned);
int chown(const char *, unsigned, unsigned);
int chmod(const char *, uint32_t);
int chown(const char *, uint32_t, uint32_t);
int chroot(const char *);
int close(int);
int close_range(unsigned, unsigned, unsigned);
int closefrom(int);
int creat(const char *, unsigned);
int creat(const char *, uint32_t);
int dup(int);
int dup2(int, int);
int dup3(int, int, int);
@@ -84,22 +84,25 @@ int execv(const char *, char *const[]);
int execve(const char *, char *const[], char *const[]);
int execvp(const char *, char *const[]);
int execvpe(const char *, char *const[], char *const[]);
int fexecve(int, char *const[], char *const[]);
int faccessat(int, const char *, int, int);
int fadvise(int, uint64_t, uint64_t, int);
int fchdir(int);
int fchmod(int, unsigned) dontthrow;
int fchmodat(int, const char *, unsigned, int);
int fchown(int, unsigned, unsigned);
int fchownat(int, const char *, unsigned, unsigned, int);
int fchmod(int, uint32_t) dontthrow;
int fchmodat(int, const char *, uint32_t, int);
int fchown(int, uint32_t, uint32_t);
int fchownat(int, const char *, uint32_t, uint32_t, int);
int fcntl(int, int, ...);
int fdatasync(int);
int fexecve(int, char *const[], char *const[]);
int flock(int, int);
int fork(void);
int fsync(int);
int ftruncate(int, int64_t);
int getdomainname(char *, size_t);
int getgroups(int, unsigned[]);
uint32_t getegid(void) nosideeffect;
uint32_t geteuid(void) nosideeffect;
uint32_t getgid(void) nosideeffect;
int getgroups(int size, uint32_t list[]);
int gethostname(char *, size_t);
int getloadavg(double *, int);
int getpgid(int) libcesque;
@@ -107,29 +110,36 @@ int getpgrp(void) nosideeffect;
int getpid(void) nosideeffect libcesque;
int getppid(void);
int getpriority(int, unsigned);
int getresgid(unsigned *, unsigned *, unsigned *);
int getresuid(unsigned *, unsigned *, unsigned *);
int getresgid(uint32_t *, uint32_t *, uint32_t *);
int getresuid(uint32_t *, uint32_t *, uint32_t *);
int getsid(int) nosideeffect libcesque;
int gettid(void) libcesque;
uint32_t getuid(void) libcesque;
int sys_iopl(int);
int ioprio_get(int, int);
int ioprio_set(int, int, int);
int issetugid(void);
int kill(int, int);
int killpg(int, int);
int lchmod(const char *, unsigned);
int lchown(const char *, unsigned, unsigned);
int lchmod(const char *, uint32_t);
int lchown(const char *, uint32_t, uint32_t);
int link(const char *, const char *) dontthrow;
int linkat(int, const char *, int, const char *, int);
int madvise(void *, uint64_t, int);
int makedirs(const char *, unsigned);
int memfd_create(const char *, unsigned int);
int mincore(void *, size_t, unsigned char *);
int mkdir(const char *, unsigned);
int mkdirat(int, const char *, unsigned);
int mkfifo(const char *, unsigned);
int mkfifoat(int, const char *, unsigned);
int mknod(const char *, unsigned, uint64_t);
int mknodat(int, const char *, int, uint64_t);
int makedirs(const char *, unsigned);
int mkfifo(const char *, uint32_t);
int mkfifoat(int, const char *, uint32_t);
int mknod(const char *, uint32_t, uint64_t);
int mknodat(int, const char *, int32_t, uint64_t);
int sys_mlock(const void *, size_t);
int sys_mlock2(const void *, size_t, int);
int sys_mlockall(int);
int sys_munlock(const void *, size_t);
int sys_munlockall(void);
int nice(int);
int open(const char *, int, ...);
int openat(int, const char *, int, ...);
@@ -151,19 +161,19 @@ int renameat2(long, const char *, long, const char *, int);
int rmdir(const char *);
int sched_yield(void);
int seccomp(unsigned, unsigned, void *);
int setegid(unsigned);
int seteuid(unsigned);
int setegid(uint32_t);
int seteuid(uint32_t);
int setfsgid(unsigned);
int setfsuid(unsigned);
int setgid(unsigned);
int setgroups(size_t, const unsigned[]);
int setgroups(size_t, const uint32_t[]);
int setpgid(int, int);
int setpgrp(void);
int setpriority(int, unsigned, int);
int setregid(unsigned, unsigned);
int setresgid(unsigned, unsigned, unsigned);
int setresuid(unsigned, unsigned, unsigned);
int setreuid(unsigned, unsigned);
int setregid(uint32_t, uint32_t);
int setresgid(uint32_t, uint32_t, uint32_t);
int setresuid(uint32_t, uint32_t, uint32_t);
int setreuid(uint32_t, uint32_t);
int setsid(void);
int setuid(unsigned);
int sigignore(int);
@@ -171,22 +181,16 @@ int siginterrupt(int, int);
int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned);
int sys_iopl(int);
int sys_mlock(const void *, size_t);
int sys_mlock2(const void *, size_t, int);
int sys_mlockall(int);
int sys_munlock(const void *, size_t);
int sys_munlockall(void);
int sys_ptrace(int, ...);
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int tcgetpgrp(int);
int tcsetpgrp(int, int);
int tcsetpgrp(int, int32_t);
int tgkill(int, int, int);
int tkill(int, int);
int tmpfd(void);
int touch(const char *, unsigned);
int touch(const char *, uint32_t);
int truncate(const char *, int64_t);
int ttyname_r(int, char *, size_t);
unsigned umask(unsigned);
int unlink(const char *);
int unlink_s(const char **);
int unlinkat(int, const char *, int);
@@ -195,10 +199,11 @@ int usleep(unsigned);
int vfork(void) returnstwice;
int wait(int *);
int waitpid(int, int *, int);
int32_t tcgetpgrp(int);
intptr_t syscall(int, ...);
long ptrace(int, ...);
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, unsigned);
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
ssize_t getfiledescriptorsize(int);
ssize_t lseek(int, int64_t, int);
ssize_t pread(int, void *, size_t, int64_t);
@@ -207,13 +212,8 @@ ssize_t read(int, void *, size_t);
ssize_t readansi(int, char *, size_t);
ssize_t readlink(const char *, char *, size_t);
ssize_t readlinkat(int, const char *, char *, size_t);
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t);
ssize_t write(int, const void *, size_t);
unsigned getegid(void) nosideeffect;
unsigned geteuid(void) nosideeffect;
unsigned getgid(void) nosideeffect;
unsigned getuid(void) libcesque;
unsigned umask(unsigned);
void sync(void);
COSMOPOLITAN_C_END_
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -16,15 +16,13 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/consts/sig.h"
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
/**
* Returns true if you're not authorized to block this signal.
*/
int sigisprecious(int sig) {
return 0
#define M(x) || sig == x
#include "libc/intrin/sigisprecious.inc"
;
uint32_t cfgetispeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ispeed;
}
}
+28
View File
@@ -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 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/termios.h"
#include "libc/sysv/consts/termios.h"
uint32_t cfgetospeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ospeed;
}
}
+33
View File
@@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 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/termios.h"
#include "libc/sysv/errfuns.h"
int cfsetispeed(struct termios *t, unsigned speed) {
if (speed) {
if (CBAUD) {
if (speed & ~CBAUD) return einval();
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
} else {
t->c_ispeed = speed;
}
}
return 0;
}
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ 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 │
@@ -16,19 +16,21 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
int sys_fork(void) {
axdx_t ad;
int ax, dx;
ad = __sys_fork();
ax = ad.ax;
dx = ad.dx;
if (IsXnu() && ax != -1) {
// eax always returned with childs pid
// edx is 0 for parent and 1 for child
ax &= dx - 1;
int cfsetospeed(struct termios *t, unsigned speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
return 0;
} else {
return einval();
}
} else {
t->c_ospeed = speed;
return 0;
}
return ax;
}
-88
View File
@@ -1,88 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 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/termios.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
/**
* Returns input baud rate.
* @asyncsignalsafe
*/
uint32_t cfgetispeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ispeed;
}
}
/**
* Returns output baud rate.
* @asyncsignalsafe
*/
uint32_t cfgetospeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ospeed;
}
}
/**
* Sets input baud rate.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int cfsetispeed(struct termios *t, unsigned speed) {
if (speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
} else {
return einval();
}
} else {
t->c_ispeed = speed;
}
}
return 0;
}
/**
* Sets output baud rate.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int cfsetospeed(struct termios *t, unsigned speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
return 0;
} else {
return einval();
}
} else {
t->c_ospeed = speed;
return 0;
}
}
+1 -1
View File
@@ -36,7 +36,7 @@
int chdir(const char *path) {
int rc;
GetProgramExecutableName(); // XXX: ugly workaround
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
rc = efault();
} else if (!IsWindows()) {
rc = sys_chdir(path);
+1 -1
View File
@@ -49,7 +49,7 @@
*/
int chroot(const char *path) {
int rc;
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
rc = efault();
} else {
rc = sys_chroot(path);
+1 -1
View File
@@ -84,7 +84,7 @@ int clock_gettime(int clock, struct timespec *ts) {
rc = __clock_gettime(clock, ts);
}
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock),
DescribeTimespec(rc, ts), rc);
}
+1 -1
View File
@@ -113,7 +113,7 @@ errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
}
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock),
DescribeSleepFlags(flags), DescribeTimespec(0, req),
DescribeTimespec(rc, rem), DescribeErrnoResult(rc));
+1 -8
View File
@@ -18,22 +18,15 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/fd.internal.h"
#include "libc/errno.h"
#include "libc/intrin/weaken.h"
#include "libc/nt/enum/filetype.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/sysv/consts/o.h"
void sys_fcntl_nt_lock_cleanup(int) hidden;
textwindows int sys_close_nt(struct Fd *fd, int fildes) {
textwindows int sys_close_nt(struct Fd *fd) {
int e;
bool ok = true;
if (_weaken(sys_fcntl_nt_lock_cleanup)) {
_weaken(sys_fcntl_nt_lock_cleanup)(fildes);
}
if (fd->kind == kFdFile && ((fd->flags & O_ACCMODE) != O_RDONLY &&
GetFileType(fd->handle) == kNtFileTypeDisk)) {
// Like Linux, closing a file on Windows doesn't guarantee it's
+2 -2
View File
@@ -16,10 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/fd.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
@@ -81,7 +81,7 @@ int close(int fd) {
} else if (__isfdkind(fd, kFdFile) || //
__isfdkind(fd, kFdConsole) || //
__isfdkind(fd, kFdProcess)) { //
rc = sys_close_nt(g_fds.p + fd, fd);
rc = sys_close_nt(g_fds.p + fd);
} else {
rc = eio();
}
+5 -2
View File
@@ -27,9 +27,12 @@
/**
* Closes extra file descriptors, e.g.
*
* if (closefrom(3))
* for (int i = 3; i < 256; ++i)
* // close all non-stdio file descriptors
* if (closefrom(3) == -1) {
* for (int i = 3; i < 256; ++i) {
* close(i);
* }
* }
*
* @return 0 on success, or -1 w/ errno
* @raise EBADF if `first` is negative
+22 -13
View File
@@ -45,18 +45,27 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
}
// allocate a new file descriptor
if (newfd == -1) {
if ((newfd = __reservefd_unlocked(start)) == -1) {
__fds_unlock();
return -1;
}
} else {
if (__ensurefds_unlocked(newfd) == -1) {
__fds_unlock();
return -1;
}
if (g_fds.p[newfd].kind) {
sys_close_nt(g_fds.p + newfd, newfd);
for (;;) {
if (newfd == -1) {
if ((newfd = __reservefd_unlocked(start)) == -1) {
__fds_unlock();
return -1;
}
break;
} else {
if (__ensurefds_unlocked(newfd) == -1) {
__fds_unlock();
return -1;
}
if (g_fds.p[newfd].kind) {
__fds_unlock();
close(newfd);
__fds_lock();
}
if (!g_fds.p[newfd].kind) {
g_fds.p[newfd].kind = kFdReserved;
break;
}
}
}
@@ -77,7 +86,7 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
}
rc = newfd;
} else {
__releasefd(newfd);
__releasefd_unlocked(newfd);
rc = __winerr();
}
+24 -33
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
@@ -41,9 +40,7 @@ static bool IsApeBinary(const char *path) {
char buf[8];
bool res = false;
if ((fd = sys_open(path, O_RDONLY, 0)) != -1) {
if (sys_read(fd, buf, 8) == 8 && //
(READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='"))) {
if (sys_read(fd, buf, 8) == 8 && READ64LE(buf) == READ64LE("MZqFpD='")) {
res = true;
}
sys_close(fd);
@@ -64,41 +61,35 @@ static const char *Join(const char *a, const char *b, char buf[PATH_MAX]) {
}
int sys_execve(const char *prog, char *const argv[], char *const envp[]) {
int e;
size_t i;
int e, rc;
char *buf;
char **shargs;
const char *ape;
e = errno;
__sys_execve(prog, argv, envp);
if (errno == ENOEXEC) {
for (i = 0; argv[i];) ++i;
buf = alloca(PATH_MAX);
shargs = alloca((i + 4) * sizeof(char *));
if (IsApeBinary(prog) &&
(CanExecute((ape = "/usr/bin/ape")) ||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
firstnonnull(getenv("HOME"), ".")),
".ape", buf))) ||
CanExecute(
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
shargs[0] = ape;
shargs[1] = "-";
shargs[2] = prog;
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
errno = e;
rc = __sys_execve(shargs[0], shargs, envp);
} else if (CanExecute(prog)) {
shargs[0] = _PATH_BSHELL;
shargs[1] = prog;
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
errno = e;
rc = __sys_execve(shargs[0], shargs, envp);
} else {
rc = enoexec();
}
if (errno != ENOEXEC) return -1;
for (i = 0; argv[i];) ++i;
buf = alloca(PATH_MAX);
shargs = alloca((i + 4) * sizeof(char *));
if (IsApeBinary(prog) &&
(CanExecute((ape = "/usr/bin/ape")) ||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
firstnonnull(getenv("HOME"), ".")),
".ape", buf))) ||
CanExecute(
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
shargs[0] = ape;
shargs[1] = "-";
shargs[2] = prog;
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
} else if (CanExecute(prog)) {
shargs[0] = _PATH_BSHELL;
shargs[1] = prog;
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
} else {
rc = -1;
return enoexec();
}
return rc;
errno = e;
return __sys_execve(shargs[0], shargs, envp);
}
+18 -6
View File
@@ -23,7 +23,6 @@
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/promises.internal.h"
@@ -54,13 +53,26 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
int rc;
size_t i;
if (!prog || !argv || !envp ||
(IsAsan() && (!__asan_is_valid_str(prog) || //
!__asan_is_valid_strlist(argv) || //
!__asan_is_valid_strlist(envp)))) {
(IsAsan() &&
(!__asan_is_valid(prog, 1) || !__asan_is_valid_strlist(argv) ||
!__asan_is_valid_strlist(envp)))) {
rc = efault();
} else {
STRACE("execve(%#s, %s, %s) → ...", prog, DescribeStringList(argv),
DescribeStringList(envp));
#ifdef SYSDEBUG
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "execve(%#s, {", prog);
for (i = 0; argv[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", argv[i]);
}
kprintf("}, {");
for (i = 0; envp[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", envp[i]);
}
kprintf("})\n");
}
#endif
if (!IsWindows()) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
+1 -1
View File
@@ -37,7 +37,7 @@
int execvpe(const char *prog, char *const argv[], char *const *envp) {
char *exe;
char pathbuf[PATH_MAX];
if (IsAsan() && !__asan_is_valid_str(prog)) return efault();
if (IsAsan() && !__asan_is_valid(prog, 1)) return efault();
if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) return -1;
return execve(exe, argv, envp);
}
+1 -1
View File
@@ -51,7 +51,7 @@
int faccessat(int dirfd, const char *path, int amode, int flags) {
int e, rc;
struct ZiposUri zipname;
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
rc = efault();
} else if (__isfdkind(dirfd, kFdZip)) {
rc = enotsup();
+1 -1
View File
@@ -44,7 +44,7 @@
*/
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
int rc;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
(rc = __zipos_notat(dirfd, path)) == -1) {
+1 -1
View File
@@ -43,7 +43,7 @@
int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
int flags) {
int rc;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
(rc = __zipos_notat(dirfd, path)) == -1) {
+41 -223
View File
@@ -16,7 +16,6 @@
│ 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/struct/fd.internal.h"
@@ -25,131 +24,63 @@
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/calls/wincrash.internal.h"
#include "libc/errno.h"
#include "libc/intrin/kmalloc.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/log/backtrace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/filelockflags.h"
#include "libc/nt/errors.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/byhandlefileinformation.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
struct FileLock {
struct FileLock *next;
int64_t off;
int64_t len;
int fd;
bool exc;
};
struct FileLocks {
pthread_mutex_t mu;
struct FileLock *list;
struct FileLock *free;
};
static struct FileLocks g_locks;
static textwindows struct FileLock *NewFileLock(void) {
struct FileLock *fl;
if (g_locks.free) {
fl = g_locks.free;
g_locks.free = fl->next;
} else {
fl = kmalloc(sizeof(*fl));
}
bzero(fl, sizeof(*fl));
fl->next = g_locks.list;
g_locks.list = fl;
return fl;
static textwindows int sys_fcntl_nt_dupfd(int fd, int cmd, int start) {
if (start < 0) return einval();
return sys_dup_nt(fd, -1, (cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0), start);
}
static textwindows void FreeFileLock(struct FileLock *fl) {
fl->next = g_locks.free;
g_locks.free = fl;
}
static textwindows bool OverlapsFileLock(struct FileLock *fl, int64_t off,
int64_t len) {
uint64_t BegA, EndA, BegB, EndB;
BegA = off;
EndA = off + (len - 1);
BegB = fl->off;
EndB = fl->off + (fl->len - 1);
return MAX(BegA, BegB) < MIN(EndA, EndB);
}
static textwindows bool EncompassesFileLock(struct FileLock *fl, int64_t off,
int64_t len) {
return off <= fl->off && fl->off + fl->len <= off + len;
}
static textwindows bool EqualsFileLock(struct FileLock *fl, int64_t off,
int64_t len) {
return fl->off == off && off + len == fl->off + fl->len;
}
hidden textwindows void sys_fcntl_nt_lock_cleanup(int fd) {
struct FileLock *fl, *ft, **flp;
pthread_mutex_lock(&g_locks.mu);
for (flp = &g_locks.list, fl = *flp; fl;) {
if (fl->fd == fd) {
*flp = fl->next;
ft = fl->next;
FreeFileLock(fl);
fl = ft;
} else {
flp = &fl->next;
fl = *flp;
}
}
pthread_mutex_unlock(&g_locks.mu);
}
static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
uintptr_t arg) {
static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) {
int e;
struct flock *l;
uint32_t flags, err;
struct FileLock *fl, *ft, **flp;
int64_t pos, off, len, end, size;
int64_t pos, off, len, size;
struct NtByHandleFileInformation info;
if (!GetFileInformationByHandle(f->handle, &info)) {
return __winerr();
}
pos = 0;
if (!SetFilePointerEx(f->handle, 0, &pos, SEEK_CUR)) {
return __winerr();
}
l = (struct flock *)arg;
len = l->l_len;
off = l->l_start;
size = (uint64_t)info.nFileSizeHigh << 32 | info.nFileSizeLow;
switch (l->l_whence) {
case SEEK_SET:
break;
case SEEK_CUR:
pos = 0;
if (SetFilePointerEx(f->handle, 0, &pos, SEEK_CUR)) {
off = pos + off;
} else {
return __winerr();
}
off = pos + off;
break;
case SEEK_END:
off = INT64_MAX - off;
off = size - off;
break;
default:
return einval();
}
if (!len) {
len = INT64_MAX - off;
len = size - off;
}
if (off < 0 || len < 0 || __builtin_add_overflow(off, len, &end)) {
if (off < 0 || len < 0) {
return einval();
}
@@ -158,57 +89,8 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
.Pointer = (void *)(uintptr_t)off};
if (l->l_type == F_RDLCK || l->l_type == F_WRLCK) {
if (cmd == F_SETLK || cmd == F_SETLKW) {
// make it possible to transition read locks to write locks
for (flp = &g_locks.list, fl = *flp; fl;) {
if (fl->fd == fd) {
if (EqualsFileLock(fl, off, len)) {
if (fl->exc == l->l_type == F_WRLCK) {
// we already have this lock
return 0;
} else {
// unlock our read lock and acquire write lock below
if (UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
*flp = fl->next;
ft = fl->next;
FreeFileLock(fl);
fl = ft;
continue;
} else {
return -1;
}
}
break;
} else if (OverlapsFileLock(fl, off, len)) {
return enotsup();
}
}
flp = &fl->next;
fl = *flp;
}
}
// return better information on conflicting locks if possible
if (cmd == F_GETLK) {
for (fl = g_locks.list; fl; fl = fl->next) {
if (fl->fd == fd && //
OverlapsFileLock(fl, off, len) &&
(l->l_type == F_WRLCK || !fl->exc)) {
l->l_whence = SEEK_SET;
l->l_start = fl->off;
l->l_len = fl->len;
l->l_type == fl->exc ? F_WRLCK : F_RDLCK;
l->l_pid = getpid();
return 0;
}
}
}
flags = 0;
if (cmd != F_SETLKW) {
// TODO(jart): we should use expo backoff in wrapper function
// should not matter since sqlite doesn't need it
flags |= kNtLockfileFailImmediately;
}
if (l->l_type == F_WRLCK) {
@@ -219,132 +101,68 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
if (ok) {
l->l_type = F_UNLCK;
if (!UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
return -1;
notpossible;
}
} else {
l->l_pid = -1;
ok = true;
}
} else if (ok) {
fl = NewFileLock();
fl->off = off;
fl->len = len;
fl->exc = l->l_type == F_WRLCK;
fl->fd = fd;
}
return ok ? 0 : -1;
}
if (l->l_type == F_UNLCK) {
if (cmd == F_GETLK) return einval();
// allow a big range to unlock many small ranges
for (flp = &g_locks.list, fl = *flp; fl;) {
if (fl->fd == fd && EncompassesFileLock(fl, off, len)) {
struct NtOverlapped ov = {.hEvent = f->handle,
.Pointer = (void *)(uintptr_t)fl->off};
if (UnlockFileEx(f->handle, 0, fl->len, fl->len >> 32, &ov)) {
*flp = fl->next;
ft = fl->next;
FreeFileLock(fl);
fl = ft;
} else {
return -1;
}
} else {
flp = &fl->next;
fl = *flp;
}
e = errno;
if (UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
return 0;
} else if (errno == ENOLCK) {
errno = e;
return 0;
} else {
return 0;
}
// win32 won't let us carve up existing locks
int overlap_count = 0;
for (fl = g_locks.list; fl; fl = fl->next) {
if (fl->fd == fd && //
OverlapsFileLock(fl, off, len)) {
++overlap_count;
}
}
// try to handle the carving cases needed by sqlite
if (overlap_count == 1) {
for (fl = g_locks.list; fl; fl = fl->next) {
if (fl->fd == fd && //
off <= fl->off && //
off + len >= fl->off && //
off + len < fl->off + fl->len) {
// cleave left side of lock
struct NtOverlapped ov = {.hEvent = f->handle,
.Pointer = (void *)(uintptr_t)fl->off};
if (!UnlockFileEx(f->handle, 0, fl->len, fl->len >> 32, &ov)) {
return -1;
}
fl->len = (fl->off + fl->len) - (off + len);
fl->off = off + len;
ov.Pointer = (void *)(uintptr_t)fl->off;
if (!LockFileEx(f->handle, kNtLockfileExclusiveLock, 0, fl->len,
fl->len >> 32, &ov)) {
return -1;
}
return 0;
}
}
}
if (overlap_count) {
return enotsup();
}
return 0;
}
return einval();
}
static textwindows int sys_fcntl_nt_dupfd(int fd, int cmd, int start) {
if (start < 0) return einval();
return sys_dup_nt(fd, -1, (cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0), start);
}
textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
int rc;
uint32_t flags;
if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) {
if (cmd == F_GETFL) {
rc = g_fds.p[fd].flags &
(O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME | O_NONBLOCK |
O_RANDOM | O_SEQUENTIAL);
return g_fds.p[fd].flags &
(O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME |
O_NONBLOCK | O_RANDOM | O_SEQUENTIAL);
} else if (cmd == F_SETFL) {
// O_APPEND doesn't appear to be tunable at cursory glance
// O_NONBLOCK might require we start doing all i/o in threads
// O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
// O_DIRECT | O_RANDOM | O_SEQUENTIAL | O_NDELAY possible but
// not worth it.
rc = enosys();
return einval();
} else if (cmd == F_GETFD) {
if (g_fds.p[fd].flags & O_CLOEXEC) {
rc = FD_CLOEXEC;
return FD_CLOEXEC;
} else {
rc = 0;
return 0;
}
} else if (cmd == F_SETFD) {
if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC;
return FD_CLOEXEC;
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0;
}
rc = 0;
} else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) {
pthread_mutex_lock(&g_locks.mu);
rc = sys_fcntl_nt_lock(g_fds.p + fd, fd, cmd, arg);
pthread_mutex_unlock(&g_locks.mu);
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
} else if (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC) {
rc = sys_fcntl_nt_dupfd(fd, cmd, arg);
return sys_fcntl_nt_dupfd(fd, cmd, arg);
} else {
rc = einval();
return einval();
}
} else {
rc = ebadf();
return ebadf();
}
return rc;
}
+12 -15
View File
@@ -31,7 +31,7 @@
#include "libc/zipos/zipos.internal.h"
/**
* Does things with file descriptor, e.g.
* Does things with file descriptor, via re-imagined hourglass api, e.g.
*
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
*
@@ -41,14 +41,12 @@
* CHECK_GE((newfd = fcntl(oldfd, F_DUPFD, 3)), 3);
* CHECK_GE((newfd = fcntl(oldfd, F_DUPFD_CLOEXEC, 3)), 3);
*
* This function implements file record locking, which lets independent
* processes (and on Linux 3.15+, threads too!) lock arbitrary ranges
* associated with a file. See `test/libc/calls/lock_test.c` and other
* locking related tests in that folder.
* This function implements POSIX Advisory Locks, which let independent
* processes (and on Windows, threads too!) read/write lock byte ranges
* of files. See `test/libc/calls/lock_test.c` for an example.
*
* On Windows, the Cosmopolitan Libc polyfill for POSIX advisory locks
* only implements enough of its nuances to support SQLite's needs. Some
* possibilities, e.g. punching holes in lock, will raise `ENOTSUP`.
* Please be warned that locks currently do nothing on Windows since
* figuring out how to polyfill them correctly is a work in progress.
*
* @param fd is the file descriptor
* @param cmd can be one of:
@@ -58,12 +56,12 @@
* - `F_SETFL` sets file descriptor status flags
* - `F_DUPFD` is like dup() but `arg` is a minimum result, e.g. 3
* - `F_DUPFD_CLOEXEC` ditto but sets `O_CLOEXEC` on returned fd
* - `F_SETLK` for record locking where `arg` is `struct flock *`
* - `F_SETLKW` ditto but waits for lock (SQLite avoids this)
* - `F_SETLK` for record locking where `arg` is `struct flock`
* - `F_SETLKW` ditto but waits (i.e. blocks) for lock
* - `F_GETLK` to retrieve information about a record lock
* - `F_OFD_SETLK` for better non-blocking lock (Linux 3.15+ only)
* - `F_OFD_SETLKW` for better blocking lock (Linux 3.15+ only)
* - `F_OFD_GETLK` for better lock querying (Linux 3.15+ only)
* - `F_OFD_SETLK` for better locks on Linux and XNU
* - `F_OFD_SETLKW` for better locks on Linux and XNU
* - `F_OFD_GETLK` for better locks on Linux and XNU
* - `F_FULLFSYNC` on MacOS for fsync() with release barrier
* - `F_BARRIERFSYNC` on MacOS for fsync() with even more barriers
* - `F_SETNOSIGPIPE` on MacOS and NetBSD to control `SIGPIPE`
@@ -73,7 +71,7 @@
* - `F_NOCACHE` on MacOS to toggle data caching
* - `F_GETPIPE_SZ` on Linux to get pipe size
* - `F_SETPIPE_SZ` on Linux to set pipe size
* - `F_NOTIFY` raise `SIGIO` upon `fd` events in `arg` (Linux only)
* - `F_NOTIFY` raise `SIGIO` upon `fd` events in `arg` on Linux
* - `DN_ACCESS` for file access
* - `DN_MODIFY` for file modifications
* - `DN_CREATE` for file creations
@@ -90,7 +88,6 @@
* @raise ENOLCK if `F_SETLKW` would have exceeded `RLIMIT_LOCKS`
* @raise EPERM if `cmd` is `F_SETOWN` and we weren't authorized
* @raise ESRCH if `cmd` is `F_SETOWN` and process group not found
* @raise ENOTSUP on Windows if locking operation isn't supported yet
* @raise EDEADLK if `cmd` was `F_SETLKW` and waiting would deadlock
* @raise EMFILE if `cmd` is `F_DUPFD` or `F_DUPFD_CLOEXEC` and
* `RLIMIT_NOFILE` would be exceeded
+17 -3
View File
@@ -21,7 +21,8 @@
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
@@ -47,8 +48,21 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
(!__asan_is_valid_strlist(argv) || !__asan_is_valid_strlist(envp)))) {
rc = efault();
} else {
STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv),
DescribeStringList(envp));
#ifdef SYSDEBUG
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "fexecve(%d, {", fd);
for (i = 0; argv[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", argv[i]);
}
kprintf("}, {");
for (i = 0; envp[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", envp[i]);
}
kprintf("})\n");
}
#endif
if (IsLinux()) {
char path[14 + 12];
FormatInt32(stpcpy(path, "/proc/self/fd/"), fd);
+1 -1
View File
@@ -51,7 +51,7 @@ bool fileexists(const char *path) {
struct ZiposUri zipname;
uint16_t path16[PATH_MAX];
e = errno;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (_weaken(__zipos_open) &&
+1 -1
View File
@@ -31,7 +31,7 @@ int32_t sys_fstatat(int32_t dirfd, const char *path, struct stat *st,
int rc;
void *p;
union metastat ms;
if (IsAsan() && !__asan_is_valid_str(path)) return efault();
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (IsLinux()) {
_Static_assert(sizeof(*st) == sizeof(ms.linux), "assumption broken");
if (IsAsan() && (st && !__asan_is_valid(st, sizeof(*st)))) return efault();
+1 -1
View File
@@ -63,7 +63,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz) {
rc = __gettimeofday(tv, tz, 0).ax;
}
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("gettimeofday([%s], %p) → %d% m", DescribeTimeval(rc, tv), tz, rc);
}
#endif
+2 -1
View File
@@ -18,6 +18,7 @@ hidden extern const struct Fd kEmptyFd;
int __reservefd(int) hidden;
int __reservefd_unlocked(int) hidden;
void __releasefd(int) hidden;
void __releasefd_unlocked(int) hidden;
int __ensurefds(int) hidden;
int __ensurefds_unlocked(int) hidden;
void __printfds(void) hidden;
@@ -42,7 +43,7 @@ forceinline size_t _clampio(size_t size) {
}
}
int sys_close_nt(struct Fd *, int) hidden;
int sys_close_nt(struct Fd *) hidden;
bool _check_interrupts(bool, struct Fd *) hidden;
int sys_openat_metal(int, const char *, int, unsigned);
+1 -1
View File
@@ -51,7 +51,7 @@ bool isdirectory(const char *path) {
union metastat st;
struct ZiposUri zipname;
e = errno;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (_weaken(__zipos_open) &&
+1 -1
View File
@@ -48,7 +48,7 @@ bool isregularfile(const char *path) {
union metastat st;
struct ZiposUri zipname;
e = errno;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (_weaken(__zipos_open) &&
+1 -1
View File
@@ -51,7 +51,7 @@ bool issymlink(const char *path) {
union metastat st;
struct ZiposUri zipname;
e = errno;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (_weaken(__zipos_open) &&
+1 -5
View File
@@ -17,10 +17,10 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/str/str.h"
/**
@@ -38,10 +38,6 @@
* >0 can be SIGINT, SIGTERM, SIGKILL, SIGUSR1, etc.
* =0 checks both if pid exists and we can signal it
* @return 0 if something was accomplished, or -1 w/ errno
* @raise ESRCH if `pid` couldn't be found
* @raise EPERM if lacked permission to signal process
* @raise EPERM if pledge() is in play without `proc` promised
* @raise EINVAL if the provided `sig` is invalid or unsupported
* @asyncsignalsafe
*/
int kill(int pid, int sig) {
+1 -1
View File
@@ -41,7 +41,7 @@ int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
int flags) {
int rc;
if (IsAsan() &&
(!__asan_is_valid_str(oldpath) || !__asan_is_valid_str(newpath))) {
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
((rc = __zipos_notat(olddirfd, oldpath)) == -1 ||
-2
View File
@@ -34,8 +34,6 @@ textwindows int64_t sys_lseek_nt(int fd, int64_t offset, int whence) {
} else {
return espipe();
}
} else if (__isfdkind(fd, kFdSocket)) {
return espipe();
} else {
return ebadf();
}
+1 -1
View File
@@ -53,7 +53,7 @@
*/
int mkdirat(int dirfd, const char *path, unsigned mode) {
int rc;
if (IsAsan() && !__asan_is_valid_str(path)) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
(rc = __zipos_notat(dirfd, path)) == -1) {
+2 -2
View File
@@ -17,10 +17,10 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/ipc.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
@@ -36,7 +36,7 @@
int mkfifo(const char *pathname, unsigned mode) {
// TODO(jart): Windows?
int rc;
if (IsAsan() && !__asan_is_valid_str(pathname)) {
if (IsAsan() && !__asan_is_valid(pathname, 1)) {
rc = efault();
} else if (IsLinux()) {
rc = sys_mknod(pathname, mode | S_IFIFO, 0);
+2 -2
View File
@@ -17,10 +17,10 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
@@ -40,7 +40,7 @@
*/
int mknod(const char *path, uint32_t mode, uint64_t dev) {
int rc;
if (IsAsan() && !__asan_is_valid_str(path)) return efault();
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (mode & S_IFREG) return creat(path, mode & ~S_IFREG);
if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR);
if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO);
+5 -7
View File
@@ -21,7 +21,9 @@
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/systeminfo.h"
#include "libc/str/oldutf16.internal.h"
#include "libc/str/str.h"
#include "libc/str/tpdecode.internal.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
@@ -59,13 +61,9 @@ textwindows int __mkntpath(const char *path,
/**
* Copies path for Windows NT.
*
* This function does the following chores:
*
* 1. Converting UTF-8 to UTF-16
* 2. Replacing forward-slashes with backslashes
* 3. Fixing drive letter paths, e.g. `/c/` → `c:\`
* 4. Add `\\?\` prefix for paths exceeding 260 chars
* 5. Remapping well-known paths, e.g. `/dev/null` → `NUL`
* This entails (1) UTF-8 to UTF-16 conversion; (2) replacing
* forward-slashes with backslashes; and (3) remapping several
* well-known paths (e.g. /dev/null → NUL) for convenience.
*
* @param flags is used by open()
* @param path16 is shortened so caller can prefix, e.g. \\.\pipe\, and
+1 -1
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/directmap.internal.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/pc.internal.h"
noasan int sys_munmap_metal(void *addr, size_t size) {
+4 -4
View File
@@ -16,11 +16,11 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/directmap.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.internal.h"
/**
* Unmaps memory directly with system.
+2 -2
View File
@@ -56,7 +56,7 @@ static long double GetTimeSample(void) {
static long double MeasureNanosPerCycle(void) {
int i, n;
long double avg, samp;
if (__tls_enabled) __get_tls()->tib_flags |= TIB_FLAG_TIME_CRITICAL;
__get_tls()->tib_flags |= TIB_FLAG_TIME_CRITICAL;
if (IsWindows()) {
n = 10;
} else {
@@ -66,7 +66,7 @@ static long double MeasureNanosPerCycle(void) {
samp = GetTimeSample();
avg += (samp - avg) / i;
}
if (__tls_enabled) __get_tls()->tib_flags &= ~TIB_FLAG_TIME_CRITICAL;
__get_tls()->tib_flags &= ~TIB_FLAG_TIME_CRITICAL;
STRACE("MeasureNanosPerCycle cpn*1000=%d", (long)(avg * 1000));
return avg;
}
+2
View File
@@ -23,6 +23,7 @@
privileged void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
if (!cr) return;
ctx->uc_flags = cr->EFlags;
ctx->uc_mcontext.eflags = cr->EFlags;
ctx->uc_mcontext.rax = cr->Rax;
ctx->uc_mcontext.rbx = cr->Rbx;
@@ -50,6 +51,7 @@ privileged void _ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
privileged void _ntlinux2context(struct NtContext *cr, const ucontext_t *ctx) {
if (!cr) return;
cr->EFlags = ctx->uc_flags;
cr->EFlags = ctx->uc_mcontext.eflags;
cr->Rax = ctx->uc_mcontext.rax;
cr->Rbx = ctx->uc_mcontext.rbx;
+2 -2
View File
@@ -18,7 +18,9 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/ntspawn.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/nt/enum/filemapflags.h"
#include "libc/nt/enum/pageflags.h"
@@ -78,8 +80,6 @@ textwindows int ntspawn(
rc = -1;
block = NULL;
if (__mkntpath(prog, prog16) == -1) return -1;
// we can't call malloc() because we're higher in the topological order
// we can't call kmalloc() because fork() calls this when kmalloc is locked
if ((handle = CreateFileMapping(-1, 0, pushpop(kNtPageReadwrite), 0,
sizeof(*block), 0)) &&
(block = MapViewOfFileEx(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
+2 -2
View File
@@ -53,7 +53,7 @@ static long double GetTimeSample(void) {
static long double MeasureNanosPerCycle(void) {
int i, n;
long double avg, samp;
if (__tls_enabled) __get_tls()->tib_flags |= TIB_FLAG_TIME_CRITICAL;
__get_tls()->tib_flags |= TIB_FLAG_TIME_CRITICAL;
if (IsWindows()) {
n = 30;
} else {
@@ -63,7 +63,7 @@ static long double MeasureNanosPerCycle(void) {
samp = GetTimeSample();
avg += (samp - avg) / i;
}
if (__tls_enabled) __get_tls()->tib_flags &= ~TIB_FLAG_TIME_CRITICAL;
__get_tls()->tib_flags &= ~TIB_FLAG_TIME_CRITICAL;
STRACE("MeasureNanosPerCycle cpn*1000=%d", (long)(avg * 1000));
return avg;
}
+1 -1
View File
@@ -88,7 +88,7 @@ textwindows int sys_open_nt(int dirfd, const char *file, uint32_t flags,
rc = sys_open_nt_file(dirfd, file, flags, mode, fd);
}
if (rc == -1) {
__releasefd(fd);
__releasefd_unlocked(fd);
}
__fds_unlock();
}
-1
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/intrin/weaken.h"
+1 -1
View File
@@ -154,7 +154,7 @@ int openat(int dirfd, const char *file, int flags, ...) {
va_start(va, flags);
mode = va_arg(va, unsigned);
va_end(va);
if (file && (!IsAsan() || __asan_is_valid_str(file))) {
if (file && (!IsAsan() || __asan_is_valid(file, 1))) {
if (!__isfdkind(dirfd, kFdZip)) {
if (_weaken(__zipos_open) &&
_weaken(__zipos_parseuri)(file, &zipname) != -1) {
+3 -3
View File
@@ -41,7 +41,7 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
return -1;
}
if ((writer = __reservefd_unlocked(-1)) == -1) {
__releasefd(reader);
__releasefd_unlocked(reader);
__fds_unlock();
return -1;
}
@@ -73,8 +73,8 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
CloseHandle(hin);
}
}
__releasefd(writer);
__releasefd(reader);
__releasefd_unlocked(writer);
__releasefd_unlocked(reader);
__fds_unlock();
return -1;
}
+10 -18
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/pledge.internal.h"
#include "libc/calls/struct/bpf.h"
@@ -1606,26 +1605,19 @@ static privileged void AllowFcntlStdio(struct Filter *f) {
// The second argument of fcntl() must be one of:
//
// - F_GETLK (0x05)
// - F_SETLK (0x06)
// - F_SETLKW (0x07)
// - F_OFD_GETLK (0x24)
// - F_OFD_SETLK (0x25)
// - F_OFD_SETLKW (0x26)
// - F_GETLK (5)
// - F_SETLK (6)
// - F_SETLKW (7)
//
static privileged void AllowFcntlLock(struct Filter *f) {
static const struct sock_filter fragment[] = {
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 9),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x05, 5, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x06, 4, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x07, 3, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x24, 2, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x25, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x26, 0, 1),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
/* next filter */
/*L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_fcntl, 0, 6 - 1),
/*L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])),
/*L2*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 5, 0, 5 - 3),
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, 8, 5 - 4, 0),
/*L4*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/*L5*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
/*L6*/ /* next filter */
};
AppendFilter(f, PLEDGE(fragment));
}
+28 -3
View File
@@ -16,9 +16,17 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/pollfd.h"
#include "libc/sock/struct/pollfd.internal.h"
#include "libc/sysv/errfuns.h"
@@ -60,8 +68,8 @@
* @norestart
*/
int poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
int rc;
size_t n;
int i, rc;
uint64_t millis;
if (IsAsan() && (__builtin_mul_overflow(nfds, sizeof(struct pollfd), &n) ||
@@ -78,7 +86,24 @@ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
rc = sys_poll_nt(fds, nfds, &millis, 0);
}
STRACE("poll(%s, %'zu, %'d) → %d% lm", DescribePollFds(rc, fds, nfds), nfds,
timeout_ms, rc);
#if defined(SYSDEBUG) && _POLLTRACE
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "poll(");
if ((!IsAsan() && kisdangerous(fds)) ||
(IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd)))) {
kprintf("%p", fds);
} else {
kprintf("[{");
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}]", i == 5 ? "..." : "");
}
kprintf(", %'zu, %'d) → %d% lm\n", nfds, timeout_ms, rc);
}
#endif
return rc;
}
+24 -5
View File
@@ -16,14 +16,15 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/sigset.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/sock/struct/pollfd.h"
#include "libc/sock/struct/pollfd.internal.h"
#include "libc/sysv/consts/sig.h"
@@ -57,7 +58,7 @@
int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout,
const sigset_t *sigmask) {
size_t n;
int e, rc;
int e, i, rc;
uint64_t millis;
sigset_t oldmask;
struct timespec ts, *tsp;
@@ -95,7 +96,25 @@ int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout,
rc = sys_poll_nt(fds, nfds, &millis, sigmask);
}
STRACE("ppoll(%s, %'zu, %s, %s) → %d% lm", DescribePollFds(rc, fds, nfds),
nfds, DescribeTimespec(0, timeout), DescribeSigset(0, sigmask), rc);
#if defined(SYSDEBUG) && _POLLTRACE
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "ppoll(");
if ((!IsAsan() && kisdangerous(fds)) ||
(IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd)))) {
kprintf("%p", fds);
} else {
kprintf("[{");
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}]", i == 5 ? "..." : "");
}
kprintf(", %'zu, %s, %s) → %d% lm\n", nfds, DescribeTimeval(0, timeout),
DescribeSigset(0, sigmask), rc);
}
#endif
return rc;
}
+17 -2
View File
@@ -16,9 +16,12 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/iovec.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/dce.h"
@@ -28,13 +31,16 @@
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
static ssize_t Preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
int e, i;
size_t got;
bool masked;
ssize_t rc, toto;
sigset_t mask, oldmask;
if (fd < 0) {
return ebadf();
@@ -88,17 +94,26 @@ static ssize_t Preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
if (rc == -1) {
if (!toto) {
toto = -1;
} else if (errno != EINTR) {
notpossible;
}
break;
}
got = rc;
toto += got;
off += got;
if (got != iov[i].iov_len) {
break;
}
if (!masked) {
sigfillset(&mask);
_npassert(!sys_sigprocmask(SIG_SETMASK, &mask, &oldmask));
masked = true;
}
}
if (masked) {
_npassert(!sys_sigprocmask(SIG_SETMASK, &oldmask, 0));
}
return toto;
+17 -2
View File
@@ -16,9 +16,12 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/iovec.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/dce.h"
@@ -28,14 +31,17 @@
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
static ssize_t Pwritev(int fd, const struct iovec *iov, int iovlen,
int64_t off) {
int i, e;
bool masked;
size_t sent;
ssize_t rc, toto;
sigset_t mask, oldmask;
if (fd < 0) {
return ebadf();
@@ -89,17 +95,26 @@ static ssize_t Pwritev(int fd, const struct iovec *iov, int iovlen,
if (rc == -1) {
if (!toto) {
toto = -1;
} else if (errno != EINTR) {
notpossible;
}
break;
}
sent = rc;
toto += sent;
off += sent;
if (sent != iov[i].iov_len) {
break;
}
if (!masked) {
sigfillset(&mask);
_npassert(!sys_sigprocmask(SIG_SETMASK, &mask, &oldmask));
masked = true;
}
}
if (masked) {
_npassert(!sys_sigprocmask(SIG_SETMASK, &oldmask, 0));
}
return toto;
+1 -1
View File
@@ -47,7 +47,7 @@ int renameat(int olddirfd, const char *oldpath, int newdirfd,
const char *newpath) {
int rc;
if (IsAsan() &&
(!__asan_is_valid_str(oldpath) || !__asan_is_valid_str(newpath))) {
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
rc = efault();
} else if (_weaken(__zipos_notat) &&
((rc = __zipos_notat(olddirfd, oldpath)) == -1 ||
+14 -12
View File
@@ -16,18 +16,25 @@
│ 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/state.internal.h"
#include "libc/calls/struct/fd.internal.h"
#include "libc/intrin/atomic.h"
#include "libc/calls/struct/sigset.h"
#include "libc/dce.h"
#include "libc/intrin/cmpxchg.h"
#include "libc/intrin/extend.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
// TODO(jart): make more of this code lockless
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static volatile size_t mapsize;
@@ -64,10 +71,9 @@ int __ensurefds(int fd) {
* @asyncsignalsafe
*/
int __reservefd_unlocked(int start) {
int fd, f1, f2;
int fd;
for (;;) {
f1 = atomic_load_explicit(&g_fds.f, memory_order_acquire);
for (fd = MAX(start, f1); fd < g_fds.n; ++fd) {
for (fd = MAX(start, g_fds.f); fd < g_fds.n; ++fd) {
if (!g_fds.p[fd].kind) {
break;
}
@@ -75,11 +81,7 @@ int __reservefd_unlocked(int start) {
fd = __ensurefds_unlocked(fd);
bzero(g_fds.p + fd, sizeof(*g_fds.p));
if (_cmpxchg(&g_fds.p[fd].kind, kFdEmpty, kFdReserved)) {
// g_fds.f isn't guarded by our mutex
do {
f2 = MAX(fd + 1, f1);
} while (!atomic_compare_exchange_weak_explicit(
&g_fds.f, &f1, f2, memory_order_release, memory_order_relaxed));
_cmpxchg(&g_fds.f, fd, fd + 1);
return fd;
}
}
+6 -2
View File
@@ -19,9 +19,9 @@
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/stdio/rand.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "libc/stdio/lcg.internal.h"
/**
* Returns handles of windows pids being tracked.
@@ -35,8 +35,12 @@
textwindows int __sample_pids(int pids[hasatleast 64],
int64_t handles[hasatleast 64],
bool exploratory) {
static uint64_t rando = 1;
static pthread_spinlock_t lock;
uint32_t i, j, base, count;
base = _rand64() >> 32;
if (__threaded) pthread_spin_lock(&lock);
base = KnuthLinearCongruentialGenerator(&rando) >> 32;
pthread_spin_unlock(&lock);
for (count = i = 0; i < g_fds.n; ++i) {
j = (base + i) % g_fds.n;
if (g_fds.p[j].kind == kFdProcess && (!exploratory || !g_fds.p[j].zombie)) {
+2 -2
View File
@@ -17,10 +17,10 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/console.h"
#include "libc/sysv/errfuns.h"
@@ -34,7 +34,7 @@ int setpgid(int pid, int pgid) {
rc = sys_setpgid(pid, pgid);
} else {
me = getpid();
if ((!pid || pid == me) && (!pgid || pgid == me)) {
if (pid == me && pgid == me) {
/*
* "When a process is created with CREATE_NEW_PROCESS_GROUP
* specified, an implicit call to SetConsoleCtrlHandler(NULL,TRUE)
+2 -2676
View File
File diff suppressed because it is too large. Load diff
+26 -18
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
@@ -30,7 +29,6 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/sigaction.internal.h"
#include "libc/calls/struct/siginfo.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-sysv.internal.h"
#include "libc/calls/ucontext.h"
@@ -85,11 +83,9 @@ union metasigaction {
struct sigaction_xnu_out xnu_out;
};
void __sigenter_xnu(int, struct siginfo *, void *) hidden;
void __sigenter_linux(int, struct siginfo *, void *) hidden;
void __sigenter_netbsd(int, struct siginfo *, void *) hidden;
void __sigenter_freebsd(int, struct siginfo *, void *) hidden;
void __sigenter_openbsd(int, struct siginfo *, void *) hidden;
void __sigenter_netbsd(int, void *, void *) hidden;
void __sigenter_freebsd(int, void *, void *) hidden;
void __sigenter_openbsd(int, void *, void *) hidden;
static void sigaction_cosmo2native(union metasigaction *sa) {
if (!sa) return;
@@ -158,7 +154,6 @@ static int __sigaction(int sig, const struct sigaction *act,
"sigaction cosmo abi needs tuning");
int64_t arg4, arg5;
int rc, rva, oldrva;
sigaction_f sigenter;
struct sigaction *ap, copy;
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
if (!(0 < sig && sig < NSIG)) return einval();
@@ -186,7 +181,11 @@ static int __sigaction(int sig, const struct sigaction *act,
ap = &copy;
if (IsXnu()) {
ap->sa_restorer = (void *)&__sigenter_xnu;
sigenter = __sigenter_xnu;
if (rva < kSigactionMinRva) {
ap->sa_sigaction = (void *)(intptr_t)rva;
} else {
ap->sa_sigaction = (void *)&__sigenter_xnu;
}
// mitigate Rosetta signal handling strangeness
// https://github.com/jart/cosmopolitan/issues/455
ap->sa_flags |= SA_SIGINFO;
@@ -195,21 +194,27 @@ static int __sigaction(int sig, const struct sigaction *act,
ap->sa_flags |= SA_RESTORER;
ap->sa_restorer = &__restore_rt;
}
sigenter = __sigenter_linux;
} else if (IsNetbsd()) {
sigenter = __sigenter_netbsd;
if (rva < kSigactionMinRva) {
ap->sa_sigaction = (void *)(intptr_t)rva;
} else {
ap->sa_sigaction = (sigaction_f)__sigenter_netbsd;
}
} else if (IsFreebsd()) {
sigenter = __sigenter_freebsd;
if (rva < kSigactionMinRva) {
ap->sa_sigaction = (void *)(intptr_t)rva;
} else {
ap->sa_sigaction = (sigaction_f)__sigenter_freebsd;
}
} else if (IsOpenbsd()) {
sigenter = __sigenter_openbsd;
if (rva < kSigactionMinRva) {
ap->sa_sigaction = (void *)(intptr_t)rva;
} else {
ap->sa_sigaction = (sigaction_f)__sigenter_openbsd;
}
} else {
return enosys();
}
if (rva < kSigactionMinRva) {
ap->sa_sigaction = (void *)(intptr_t)rva;
} else {
ap->sa_sigaction = sigenter;
}
sigaction_cosmo2native((union metasigaction *)ap);
} else {
ap = NULL;
@@ -461,6 +466,7 @@ static int __sigaction(int sig, const struct sigaction *act,
* @return 0 on success or -1 w/ errno
* @see xsigaction() for a much better api
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
@@ -468,7 +474,9 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
if (sig == SIGKILL || sig == SIGSTOP) {
rc = einval();
} else {
__sig_lock();
rc = __sigaction(sig, act, oldact);
__sig_unlock();
}
STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, DescribeSigaction(0, act),
DescribeSigaction(rc, oldact), rc);
+3 -3
View File
@@ -49,16 +49,16 @@ void _check_sigchld(void) {
i = WaitForMultipleObjects(n, handles, false, 0);
if (i == kNtWaitTimeout) return;
if (i == kNtWaitFailed) {
NTTRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
return;
}
if (__sighandrvas[SIGCHLD] == (intptr_t)SIG_IGN ||
__sighandrvas[SIGCHLD] == (intptr_t)SIG_DFL) {
NTTRACE("new zombie fd=%d handle=%ld", pids[i], handles[i]);
STRACE("new zombie fd=%d handle=%ld", pids[i], handles[i]);
return;
}
if (__sighandflags[SIGCHLD] & SA_NOCLDWAIT) {
NTTRACE("SIGCHILD SA_NOCLDWAIT fd=%d handle=%ld", pids[i], handles[i]);
STRACE("SIGCHILD SA_NOCLDWAIT fd=%d handle=%ld", pids[i], handles[i]);
CloseHandle(handles[i]);
__releasefd(pids[i]);
}
+1 -1
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
@@ -51,6 +50,7 @@ privileged void __sigenter_freebsd(int sig, struct siginfo_freebsd *freebsdinfo,
g.uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
g.uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
g.uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
g.uc.uc_flags = ctx->uc_flags;
__repmovsb(&g.uc.uc_sigmask, &ctx->uc_sigmask,
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->uc_sigmask)));
g.uc.uc_mcontext.r8 = ctx->uc_mcontext.mc_r8;
-48
View File
@@ -1,48 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 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 "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/ucontext.h"
#include "libc/intrin/likely.h"
#include "libc/math.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sa.h"
privileged void __sigenter_linux(int sig, struct siginfo *info,
ucontext_t *ctx) {
int i, rva, flags;
rva = __sighandrvas[sig & (NSIG - 1)];
if (rva >= kSigactionMinRva) {
flags = __sighandflags[sig & (NSIG - 1)];
// WSL1 doesn't set the fpregs field.
// https://github.com/microsoft/WSL/issues/2555
if ((flags & SA_SIGINFO) && UNLIKELY(!ctx->uc_mcontext.fpregs)) {
ctx->uc_mcontext.fpregs = &ctx->__fpustate;
for (i = 0; i < 8; ++i) {
long double nan = NAN;
memcpy(ctx->__fpustate.st + i, &nan, 16);
}
}
((sigaction_f)(_base + rva))(sig, info, ctx);
}
}
+1 -1
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
@@ -47,6 +46,7 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
__repstosb(&uc, 0, sizeof(uc));
__siginfo2cosmo(&si2, (void *)si);
uc.uc_mcontext.fpregs = &uc.__fpustate;
uc.uc_flags = ctx->uc_flags;
uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
uc.uc_stack.ss_size = ctx->uc_stack.ss_size;
uc.uc_stack.ss_flags = ctx->uc_stack.ss_flags;
+2 -3
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
@@ -49,8 +48,8 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
__repstosb(&g.uc, 0, sizeof(g.uc));
__siginfo2cosmo(&g.si, (void *)openbsdinfo);
g.uc.uc_mcontext.fpregs = &g.uc.__fpustate;
g.uc.uc_sigmask.__bits[0] = ctx->sc_mask;
g.uc.uc_sigmask.__bits[1] = 0;
__repmovsb(&g.uc.uc_sigmask, &ctx->sc_mask,
MIN(sizeof(g.uc.uc_sigmask), sizeof(ctx->sc_mask)));
g.uc.uc_mcontext.rdi = ctx->sc_rdi;
g.uc.uc_mcontext.rsi = ctx->sc_rsi;
g.uc.uc_mcontext.rdx = ctx->sc_rdx;
+1 -2
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
@@ -471,8 +470,8 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
} else {
__repstosb(&g, 0, sizeof(g));
if (xnuctx) {
g.uc.uc_flags = xnuctx->uc_onstack ? SA_ONSTACK : 0;
g.uc.uc_sigmask.__bits[0] = xnuctx->uc_sigmask;
g.uc.uc_sigmask.__bits[1] = 0;
g.uc.uc_stack.ss_sp = xnuctx->uc_stack.ss_sp;
g.uc.uc_stack.ss_flags = xnuctx->uc_stack.ss_flags;
g.uc.uc_stack.ss_size = xnuctx->uc_stack.ss_size;
+1 -7
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/state.internal.h"
#include "libc/str/str.h"
#include "libc/thread/thread.h"
void(__sig_lock)(void) {
@@ -28,11 +27,6 @@ void(__sig_unlock)(void) {
pthread_mutex_unlock(&__sig_lock_obj);
}
void __sig_funlock(void) {
bzero(&__sig_lock_obj, sizeof(__sig_lock_obj));
__attribute__((__constructor__)) static void init(void) {
__sig_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
}
__attribute__((__constructor__)) static void __sig_init(void) {
pthread_atfork(__sig_lock, __sig_unlock, __sig_funlock);
}
File renamed without changes.
+1
View File
@@ -26,6 +26,7 @@
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/log/log.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
-4
View File
@@ -16,10 +16,8 @@ hidden extern const struct NtSecurityAttributes kNtIsInheritable;
void __fds_lock(void);
void __fds_unlock(void);
void __fds_funlock(void);
void __sig_lock(void);
void __sig_unlock(void);
void __sig_funlock(void);
#ifdef _NOPL0
#define __fds_lock() _NOPL0("__threadcalls", __fds_lock)
@@ -37,8 +35,6 @@ void __sig_funlock(void);
#define __sig_unlock() (__threaded ? __sig_unlock() : 0)
#endif
#define __vforked (__tls_enabled && (__get_tls()->tib_flags & TIB_FLAG_VFORKED))
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_STATE_INTERNAL_H_ */
+1 -1
View File
@@ -25,7 +25,7 @@ struct Fd {
};
struct Fds {
_Atomic(int) f; /* lowest free slot */
int f; /* lowest free slot */
size_t n;
struct Fd *p, *e;
};
+1 -1
View File
@@ -9,7 +9,7 @@ struct flock { /* cosmopolitan abi */
int64_t l_start; /* starting offset */
int64_t l_len; /* no. bytes (0 means to end of file) */
int32_t l_pid; /* lock owner */
int32_t l_sysid; /* remote system id or zero for local (freebsd) */
int32_t l_sysid; /* remote system id or zero for local */
};
COSMOPOLITAN_C_END_
+2
View File
@@ -8,6 +8,8 @@
COSMOPOLITAN_C_START_
int sys_sigqueueinfo(int, const siginfo_t *) hidden;
void __sigenter_xnu(void *, int, int, struct siginfo_xnu *,
struct __darwin_ucontext *) hidden;
const char *DescribeSiginfo(char[300], int, const siginfo_t *);
#define DescribeSiginfo(x, y) DescribeSiginfo(alloca(300), x, y)
-3
View File
@@ -16,13 +16,10 @@ int sigorset(sigset_t *, const sigset_t *, const sigset_t *) paramsnonnull();
int sigisemptyset(const sigset_t *) paramsnonnull() nosideeffect;
int sigismember(const sigset_t *, int) paramsnonnull() nosideeffect;
int sigcountset(const sigset_t *) paramsnonnull() nosideeffect;
int sigisprecious(int) nosideeffect;
int sigprocmask(int, const sigset_t *, sigset_t *);
int sigsuspend(const sigset_t *);
int sigpending(sigset_t *);
int pthread_sigmask(int, const sigset_t *, sigset_t *);
sigset_t _sigsetmask(sigset_t);
sigset_t _sigblockall(void);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+2 -2
View File
@@ -17,12 +17,12 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
@@ -42,7 +42,7 @@
int symlinkat(const char *target, int newdirfd, const char *linkpath) {
int rc;
if (IsAsan() &&
(!__asan_is_valid_str(target) || !__asan_is_valid_str(linkpath))) {
(!__asan_is_valid(target, 1) || !__asan_is_valid(linkpath, 1))) {
rc = efault();
}
if (!IsWindows()) {
+2 -2
View File
@@ -17,11 +17,11 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/strace.internal.h"
#define IsPeek(request) (IsLinux() && (request)-1u < 3)
@@ -46,7 +46,7 @@ int sys_ptrace(int op, ...) {
va_end(va);
rc = __sys_ptrace(op, pid, addr, data);
#ifdef SYSDEBUG
if (UNLIKELY(__strace > 0) && strace_enabled(0) > 0) {
if (UNLIKELY(__strace > 0)) {
if (rc != -1 && IsPeek(op) && data) {
STRACE("sys_ptrace(%s, %d, %p, [%p]) → %p% m", DescribePtrace(op), pid,
addr, *data, rc);
+1 -2
View File
@@ -10,8 +10,8 @@ COSMOPOLITAN_C_START_
│ cosmopolitan § syscalls » system five » structless synthetic jump slots ─╬─│┼
╚────────────────────────────────────────────────────────────────────────────│*/
axdx_t __sys_fork(void) hidden;
axdx_t __sys_pipe(i32[hasatleast 2], i32) hidden;
axdx_t sys_fork(void) hidden;
axdx_t sys_getpid(void) hidden;
char *sys_getcwd(char *, u64) hidden;
char *sys_getcwd_xnu(char *, u64) hidden;
@@ -46,7 +46,6 @@ i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
i32 sys_fcntl(i32, i32, u64) hidden;
i32 sys_fdatasync(i32) hidden;
i32 sys_flock(i32, i32) hidden;
i32 sys_fork(void) hidden;
i32 sys_fsync(i32) hidden;
i32 sys_ftruncate(i32, i64, i64) hidden;
i32 sys_getcontext(void *) hidden;
+1 -34
View File
@@ -16,41 +16,8 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/files.h"
#include "libc/sysv/errfuns.h"
static textwindows int sys_tcdrain_nt(int fd) {
if (!__isfdopen(fd)) return ebadf();
if (!FlushFileBuffers(g_fds.p[fd].handle)) return __winerr();
return 0;
}
/**
* Waits until all written output is transmitted.
*
* @param fd is file descriptor of tty
* @raise EBADF if `fd` isn't an open file descriptor
* @raise ENOTTY if `fd` is open but not a teletypewriter
* @raise EIO if process group of writer is orphoned, calling thread is
* not blocking `SIGTTOU`, and process isn't ignoring `SIGTTOU`
* @raise ENOSYS on bare metal
* @asyncsignalsafe
*/
int tcdrain(int fd) {
int rc;
if (IsMetal()) {
rc = enosys();
} else if (!IsWindows()) {
rc = sys_ioctl(fd, TCSBRK, (void *)(intptr_t)1);
} else {
rc = sys_tcdrain_nt(fd);
}
STRACE("tcdrain(%d) → %d% m", fd, rc);
return rc;
return ioctl(fd, TCSBRK, (void *)(intptr_t)1);
}
+14 -74
View File
@@ -16,91 +16,31 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/calls/struct/termios.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/strace.internal.h"
#include "libc/mem/alloca.h"
#include "libc/nt/comms.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
#define kNtPurgeTxabort 1
#define kNtPurgeRxabort 2
static const char *DescribeFlow(char buf[12], int action) {
if (action == TCOOFF) return "TCOOFF";
if (action == TCOON) return "TCOON";
if (action == TCIOFF) return "TCIOFF";
if (action == TCION) return "TCION";
FormatInt32(buf, action);
return buf;
}
static int sys_tcflow_bsd(int fd, int action) {
int rc;
uint8_t c;
struct termios t;
if (action == TCOOFF) return sys_ioctl(fd, TIOCSTOP, 0);
if (action == TCOON) return sys_ioctl(fd, TIOCSTART, 0);
if (action != TCIOFF && action != TCION) return einval();
if (sys_ioctl(fd, TCGETS, &t) == -1) return -1;
c = t.c_cc[action == TCIOFF ? VSTOP : VSTART];
if (c == 255) return 0; // code is disabled
if (sys_write(fd, &c, 1) == -1) return -1;
return 0;
}
static dontinline textwindows int sys_tcflow_nt(int fd, int action) {
bool32 ok;
int64_t h;
if (!__isfdopen(fd)) return ebadf();
h = g_fds.p[fd].handle;
if (action == TCOOFF) {
ok = PurgeComm(h, kNtPurgeTxabort);
} else if (action == TCIOFF) {
ok = PurgeComm(h, kNtPurgeRxabort);
} else if (action == TCOON || action == TCION) {
ok = ClearCommBreak(h);
} else {
return einval();
}
return ok ? 0 : __winerr();
}
/**
* Changes flow of teletypewriter data.
*
* @param fd is file descriptor of tty
* @param action may be one of:
* - `TCOOFF` to suspend output
* - `TCOON` to resume output
* - `TCIOFF` to transmit a `STOP` character
* - `TCION` to transmit a `START` character
* @return 0 on success, or -1 w/ errno
* @raise EINVAL if `action` is invalid
* @raise ENOSYS on Windows and Bare Metal
* @raise EBADF if `fd` isn't an open file descriptor
* @raise ENOTTY if `fd` is open but not a teletypewriter
* @raise EIO if process group of writer is orphoned, calling thread is
* not blocking `SIGTTOU`, and process isn't ignoring `SIGTTOU`
* @asyncsignalsafe
* - `TCOOFF` suspends output
* - `TCOON` resumes output
* - `TCIOFF` transmits a STOP character
* - `TCION` transmits a START character
*/
int tcflow(int fd, int action) {
int rc;
if (IsMetal()) {
rc = enosys();
} else if (IsBsd()) {
rc = sys_ioctl(fd, TCXONC, action);
} else if (!IsWindows()) {
rc = sys_ioctl(fd, TCXONC, action);
} else {
rc = sys_tcflow_nt(fd, action);
uint8_t c;
struct termios t;
if (!IsBsd()) return sys_ioctl(fd, TCXONC, action);
if (action == TCOOFF) return sys_ioctl(fd, TIOCSTOP, 0);
if (action == TCOON) return sys_ioctl(fd, TIOCSTART, 0);
if (action != TCIOFF && action != TCION) return einval();
if (tcgetattr(fd, &t) == -1) return -1;
if ((c = t.c_cc[action == TCIOFF ? VSTOP : VSTART]) != 255) {
if (sys_write(fd, &c, 1) == -1) return -1;
}
STRACE("tcflow(%d, %s) → %d% m", fd, DescribeFlow(alloca(12), action), rc);
return rc;
return 0;
}
+6 -59
View File
@@ -16,70 +16,17 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/strace.internal.h"
#include "libc/mem/alloca.h"
#include "libc/nt/comms.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
#define kNtPurgeTxclear 4
#define kNtPurgeRxclear 8
static const char *DescribeFlush(char buf[12], int action) {
if (action == TCIFLUSH) return "TCIFLUSH";
if (action == TCOFLUSH) return "TCOFLUSH";
if (action == TCIOFLUSH) return "TCIOFLUSH";
FormatInt32(buf, action);
return buf;
}
static dontinline textwindows int sys_tcflush_nt(int fd, int queue) {
bool32 ok;
int64_t h;
if (!__isfdopen(fd)) return ebadf();
ok = true;
h = g_fds.p[fd].handle;
if (queue == TCIFLUSH || queue == TCIOFLUSH) {
ok &= !!PurgeComm(h, kNtPurgeRxclear);
}
if (queue == TCOFLUSH || queue == TCIOFLUSH) {
ok &= !!PurgeComm(h, kNtPurgeTxclear);
}
return ok ? 0 : __winerr();
}
/**
* Discards queued data on teletypewriter.
* Flushes teletypewriter data.
*
* @param queue may be one of:
* - `TCIFLUSH` flushes data received but not read
* - `TCOFLUSH` flushes data written but not transmitted
* - `TCIOFLUSH` does both `TCOFLUSH` and `TCIFLUSH`
* @return 0 on success, or -1 w/ errno
* @raise EINVAL if `action` is invalid
* @raise EBADF if `fd` isn't an open file descriptor
* @raise ENOTTY if `fd` is open but not a teletypewriter
* @raise EIO if process group of writer is orphoned, calling thread is
* not blocking `SIGTTOU`, and process isn't ignoring `SIGTTOU`
* @raise ENOSYS on bare metal
* @asyncsignalsafe
* - `TCIFLUSH` flushes data received but not read
* - `TCOFLUSH` flushes data written but not transmitted
* - `TCIOFLUSH` does both `TCOFLUSH` and `TCIFLUSH`
*/
int tcflush(int fd, int queue) {
int rc;
if (IsMetal()) {
rc = enosys();
} else if (!IsWindows()) {
rc = sys_ioctl(fd, TCFLSH, queue);
} else {
rc = sys_tcflush_nt(fd, queue);
}
STRACE("tcflush(%d, %s) → %d% m", fd, DescribeFlush(alloca(12), queue), rc);
return rc;
/* TODO(jart): Windows? */
return sys_ioctl(fd, TCFLSH, queue);
}
+5 -18
View File
@@ -16,29 +16,16 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
/**
* Returns which process group controls terminal.
*
* @return process group id on success, or -1 w/ errno
* @raise ENOTTY if `fd` is isn't controlling teletypewriter
* @raise EBADF if `fd` isn't an open file descriptor
* @raise ENOSYS on Windows and Bare Metal
* @asyncsignalsafe
*/
int tcgetpgrp(int fd) {
int rc, pgrp;
if (IsWindows() || IsMetal()) {
rc = enosys();
} else {
rc = sys_ioctl(fd, TIOCGPGRP, &pgrp);
}
STRACE("tcgetpgrp(%d) → %d% m", fd, rc == -1 ? rc : pgrp);
return rc == -1 ? rc : pgrp;
int32_t tcgetpgrp(int fd) {
int pgrp;
if (ioctl(fd, TIOCGPGRP, &pgrp) < 0) return -1;
return pgrp;
}
Loaded 100 of 578 files, more files were not shown because too many files have changed in this diff. Show more