From 2f3bd90216c0f881778db41f33c073672bc2a7a8 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 7 Feb 2021 06:11:44 -0800 Subject: [PATCH] Apply some touchups --- Makefile | 2 +- README.md | 15 +- build/archive | 6 +- build/assemble | 7 +- build/bootstrap/compile.com | Bin 0 -> 49152 bytes build/compile | 7 +- build/definitions.mk | 37 +- build/do | 6 +- build/findtmp | 4 +- build/getcompile | 12 + build/getlogfmt | 30 +- build/link | 7 +- build/mkdeps | 6 +- build/package | 6 +- build/rules.mk | 116 +++--- build/zipobj | 6 +- libc/calls/calls.h | 30 +- libc/calls/calls.mk | 1 - libc/calls/chmod.c | 1 - libc/calls/clock_gettime.c | 54 +-- libc/calls/execve-sysv.c | 2 +- libc/calls/faccessat.c | 1 - libc/calls/ftruncate.c | 2 +- libc/calls/getcwd-nt.c | 2 +- libc/calls/getcwd-xnu.c | 5 +- libc/calls/getenv.c | 4 +- .../{thunks/fork-sysv.S => gethostname-bsd.c} | 49 +-- .../pread-sysv.S => gethostname-linux.c} | 23 +- .../{thunks/lseek-sysv.S => gethostname-nt.c} | 38 +- libc/calls/gethostname.c | 45 +-- libc/calls/getrusage-nt.c | 3 + libc/calls/getrusage.c | 2 - libc/calls/{thunks => }/gettemppatha-flunk.S | 4 +- libc/calls/gettimeofday-sysv.S | 53 --- libc/calls/gettimeofday.c | 11 +- libc/calls/internal.h | 26 +- libc/calls/ioctl-tcgets.c | 2 +- libc/calls/ioctl-tcsets.c | 4 +- libc/calls/ktmppath.S | 2 +- libc/calls/link.c | 7 +- libc/calls/lseek.c | 8 +- libc/calls/mkntpath.c | 1 + libc/calls/nanosleep.c | 16 +- libc/calls/onntconsoleevent_init.S | 6 + libc/calls/{thunks => }/onwincrash.S | 0 libc/calls/openat.c | 2 +- libc/calls/pipe-nt.c | 6 +- libc/calls/pipe-sysv.S | 48 --- .../{thunks/sigsuspend-sysv.S => pipe-sysv.c} | 32 +- libc/calls/pipe2.c | 2 - libc/calls/pread.c | 2 +- libc/calls/preadv.c | 8 +- libc/calls/pwrite.c | 2 +- libc/calls/pwritev.c | 9 +- libc/calls/read-nt.c | 36 +- libc/calls/renameat.c | 1 - libc/calls/sigprocmask.c | 13 +- libc/calls/sigsuspend.c | 3 +- libc/calls/stat2linux.c | 8 +- libc/calls/struct/metatermios.internal.h | 2 - libc/calls/sync.c | 2 +- libc/calls/termios.internal.h | 4 +- libc/calls/termios2host.c | 10 +- libc/calls/termios2linux.c | 4 +- libc/calls/thunks/ftruncate-sysv.S | 26 -- libc/calls/thunks/onntconsoleevent.S | 26 -- libc/calls/thunks/preadv-sysv.S | 26 -- libc/calls/thunks/pwrite-sysv.S | 26 -- libc/calls/thunks/pwritev-sysv.S | 26 -- libc/calls/thunks/sigprocmask-sysv.S | 46 --- libc/calls/thunks/truncate-sysv.S | 26 -- libc/calls/truncate.c | 3 +- libc/{runtime => calls}/unsetenv.c | 35 +- libc/calls/{thunks => }/winalarm.S | 0 libc/calls/write-nt.c | 34 +- libc/dce.h | 23 +- libc/fmt/dirname.c | 5 +- libc/fmt/palandftoa.c | 2 +- libc/fmt/palandntoa.c | 2 +- libc/fmt/palandprintf.c | 2 +- ...palandprintf.internal.h => palandprintf.h} | 0 libc/fmt/pflink.h | 9 +- libc/fmt/spacepad.c | 2 +- libc/fmt/stoa.c | 2 +- libc/mem/putenv.c | 2 +- libc/runtime/directmap.c | 2 +- libc/runtime/fork.c | 18 +- libc/runtime/runtime.mk | 4 + libc/sock/sendfile.c | 2 +- libc/str/memmem.c | 60 +--- libc/str/strstr.c | 12 +- libc/sysv/calls/__sys_fork.s | 2 - libc/sysv/calls/__sys_ftruncate.s | 2 - libc/sysv/calls/__sys_gettimeofday.s | 2 - libc/sysv/calls/__sys_lseek.s | 2 - libc/sysv/calls/__sys_mmap.s | 2 - libc/sysv/calls/__sys_pread.s | 2 - libc/sysv/calls/__sys_preadv.s | 2 - libc/sysv/calls/__sys_pwrite.s | 2 - libc/sysv/calls/__sys_pwritev.s | 2 - libc/sysv/calls/__sys_sigprocmask.s | 2 - libc/sysv/calls/__sys_sigsuspend.s | 2 - libc/sysv/calls/__sys_truncate.s | 2 - libc/sysv/calls/sys_fork.s | 2 + libc/sysv/calls/sys_ftruncate.s | 2 + libc/sysv/calls/sys_gettimeofday.s | 2 + libc/sysv/calls/sys_lseek.s | 2 + libc/sysv/calls/sys_mmap.s | 2 + libc/sysv/calls/sys_pread.s | 2 + libc/sysv/calls/sys_preadv.s | 2 + libc/sysv/calls/sys_pwrite.s | 2 + libc/sysv/calls/sys_pwritev.s | 2 + libc/sysv/calls/sys_sigprocmask.s | 2 + libc/sysv/calls/sys_sigsuspend.s | 2 + libc/sysv/calls/sys_truncate.s | 2 + libc/sysv/syscalls.sh | 24 +- libc/testlib/ezbench.h | 7 + libc/testlib/formatint.c | 4 +- libc/testlib/formatrange.c | 4 +- libc/testlib/testlib.h | 122 ++++--- libc/testlib/ugly.h | 11 +- test/libc/calls/fork_test.c | 1 + .../libc/calls/getenv_test.c | 26 +- test/libc/fmt/dirname_test.c | 2 + test/libc/release/smoke.c | 5 +- test/libc/release/test.mk | 12 +- test/libc/sock/inet_pton_test.c | 5 +- test/libc/str/memcpy_test.c | 12 +- test/libc/str/memmem_test.c | 33 +- test/libc/str/strstr_test.c | 22 +- test/libc/str/tpdecode_test.c | 86 ----- test/libc/str/tpencode_test.c | 66 ---- third_party/chibicc/test/test.h | 3 + third_party/chibicc/test/test.mk | 3 + tool/build/ar.c | 67 ++-- tool/build/compile.c | 337 ++++++++++++++++++ tool/emacs/cosmo-stuff.el | 24 +- tool/viz/bf.c | 104 ++++++ tool/viz/lib/formatstringtable-testlib.h | 30 +- 139 files changed, 1188 insertions(+), 1154 deletions(-) create mode 100755 build/bootstrap/compile.com create mode 100755 build/getcompile rename libc/calls/{thunks/fork-sysv.S => gethostname-bsd.c} (71%) rename libc/calls/{thunks/pread-sysv.S => gethostname-linux.c} (77%) rename libc/calls/{thunks/lseek-sysv.S => gethostname-nt.c} (73%) rename libc/calls/{thunks => }/gettemppatha-flunk.S (97%) delete mode 100644 libc/calls/gettimeofday-sysv.S rename libc/calls/{thunks => }/onwincrash.S (100%) delete mode 100644 libc/calls/pipe-sysv.S rename libc/calls/{thunks/sigsuspend-sysv.S => pipe-sysv.c} (80%) delete mode 100644 libc/calls/thunks/ftruncate-sysv.S delete mode 100644 libc/calls/thunks/onntconsoleevent.S delete mode 100644 libc/calls/thunks/preadv-sysv.S delete mode 100644 libc/calls/thunks/pwrite-sysv.S delete mode 100644 libc/calls/thunks/pwritev-sysv.S delete mode 100644 libc/calls/thunks/sigprocmask-sysv.S delete mode 100644 libc/calls/thunks/truncate-sysv.S rename libc/{runtime => calls}/unsetenv.c (80%) rename libc/calls/{thunks => }/winalarm.S (100%) rename libc/fmt/{palandprintf.internal.h => palandprintf.h} (100%) delete mode 100644 libc/sysv/calls/__sys_fork.s delete mode 100644 libc/sysv/calls/__sys_ftruncate.s delete mode 100644 libc/sysv/calls/__sys_gettimeofday.s delete mode 100644 libc/sysv/calls/__sys_lseek.s delete mode 100644 libc/sysv/calls/__sys_mmap.s delete mode 100644 libc/sysv/calls/__sys_pread.s delete mode 100644 libc/sysv/calls/__sys_preadv.s delete mode 100644 libc/sysv/calls/__sys_pwrite.s delete mode 100644 libc/sysv/calls/__sys_pwritev.s delete mode 100644 libc/sysv/calls/__sys_sigprocmask.s delete mode 100644 libc/sysv/calls/__sys_sigsuspend.s delete mode 100644 libc/sysv/calls/__sys_truncate.s create mode 100644 libc/sysv/calls/sys_fork.s create mode 100644 libc/sysv/calls/sys_ftruncate.s create mode 100644 libc/sysv/calls/sys_gettimeofday.s create mode 100644 libc/sysv/calls/sys_lseek.s create mode 100644 libc/sysv/calls/sys_mmap.s create mode 100644 libc/sysv/calls/sys_pread.s create mode 100644 libc/sysv/calls/sys_preadv.s create mode 100644 libc/sysv/calls/sys_pwrite.s create mode 100644 libc/sysv/calls/sys_pwritev.s create mode 100644 libc/sysv/calls/sys_sigprocmask.s create mode 100644 libc/sysv/calls/sys_sigsuspend.s create mode 100644 libc/sysv/calls/sys_truncate.s rename libc/calls/thunks/mmap-sysv.S => test/libc/calls/getenv_test.c (79%) delete mode 100644 test/libc/str/tpdecode_test.c delete mode 100644 test/libc/str/tpencode_test.c create mode 100644 tool/build/compile.c create mode 100644 tool/viz/bf.c diff --git a/Makefile b/Makefile index a6ad437b7..9417f639e 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ # # TROUBLESHOOTING # -# make -j8 -O SILENT=0 o//examples/hello.com +# make -j8 -O V=1 o//examples/hello.com # make o//examples/life.elf -pn |& less # etc. # diff --git a/README.md b/README.md index 8ea2863a3..5ab71d759 100644 --- a/README.md +++ b/README.md @@ -18,21 +18,20 @@ libc](https://justine.lol/cosmopolitan/index.html) website. We also have ## Getting Started -Here's how to get started with the freestanding hermetically-sealed -monolithic source repository: +Cosmopolitan can be compiled from source on any Linux distro. ```sh -tar xf cosmopolitan-0.1.2.tar.gz # see our releases page -cd cosmo -make -j12 +tar xf cosmopolitan-0.1.2.tar.gz # see releases page +cd cosmopolitan-0.1.2 +make -j16 o//examples/hello.com +find o -name \*.com | xargs ls -rShal | less ``` -Here's how to get started with the amalgamated binaries, which let you -bring your own build system: +Alternatively you can use the release binaries: ```sh -unzip cosmopolitan-amalgamated-0.1.2.zip # see our releases page +unzip cosmopolitan-amalgamated-0.1.2.zip # see releases page echo 'main() { printf("hello world\n"); }' >hello.c gcc -g -O -static -fno-pie -no-pie -mno-red-zone -nostdlib -nostdinc \ -o hello.com.dbg hello.c -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -fuse-ld=bfd \ diff --git a/build/archive b/build/archive index f7fed1751..b378daadd 100755 --- a/build/archive +++ b/build/archive @@ -28,15 +28,15 @@ set -- o/build/bootstrap/ar.com "$@" OUT=$3 printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2 -# if [ "$SILENT" = "0" ]; then +# if [ "$V" = "0" ]; then +# printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2 +# else # # some of these windows nt archives are quite huge # COLUMNS=${COLUMNS:-80} # COLUMNS=$((COLUMNS - 4)) # printf "%s\n" "$*" | # /usr/bin/fold -s -w $COLUMNS | # sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 -# else -# printf "$LOGFMT" "${ACTION:-ARCHIVE.a}" "$OUT" >&2 # fi REASON=failed diff --git a/build/assemble b/build/assemble index 802147ef4..39678be39 100755 --- a/build/assemble +++ b/build/assemble @@ -23,13 +23,12 @@ if [ ! -d o/third_party/gcc ]; then third_party/gcc/unbundle.sh fi -export LC_ALL=C MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit -if [ "$SILENT" = "0" ]; then - printf "%s\n" "$*" >&2 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-OBJECTIFY.s}" "$TARGET" >&2 +else + printf "%s\n" "$*" >&2 fi if [ "$TARGET" ]; then diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com new file mode 100755 index 0000000000000000000000000000000000000000..3121db0148bcb3112f351d177097571f92efdb20 GIT binary patch literal 49152 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 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-COMPILE}" "${TARGET:-$OUT}" >&2 +else + printf "%s\n" "$*" >&2 fi OUTDIR="${OUT%/*}" diff --git a/build/definitions.mk b/build/definitions.mk index c135e0bdc..528cd6f24 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -13,8 +13,8 @@ # # When tuning the variables below, please note they're interpreted in # the strictest sense. For example, we don't pass CFLAGS to gcc if we -# know it's compiling a .S file. This allows our `make SILENT=0` logs -# to be succinct and informative, at the cost of being less forgiving. +# know it's compiling a .S file. This enables our `make V=0` logging +# to be succinct and informative at the cost of being less forgiving. # # Further note that link order is equally unforgiving in repositories # of this scale. We approach that by over-specifying dependencies, in @@ -42,6 +42,10 @@ # ASFLAGS assembler flags (don't use -Wa, frontend prefix) # TARGET_ARCH microarchitecture flags (e.g. -march=native) +V ?= 1 +LC_ALL = C.UTF-8 +SOURCE_DATE_EPOCH = 0 + DD ?= /bin/dd CP ?= /bin/cp -f RM ?= /bin/rm -f @@ -49,7 +53,6 @@ SED ?= /bin/sed MKDIR ?= /bin/mkdir -p TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it ARFLAGS = rcsD -SILENT ?= 0 ZFLAGS ?= XARGS ?= xargs -P4 -rs8000 NICE ?= build/actuallynice @@ -77,36 +80,51 @@ PWD := $(shell pwd) IMAGE_BASE_VIRTUAL ?= 0x400000 TMPDIR := $(shell build/findtmp) LOGFMT := $(shell build/getlogfmt) +COMPILE := $(shell build/getcompile) CCNAME := $(shell build/getccname $(CC)) CCVERSION := $(shell build/getccversion $(CC)) BLAH1 := $(shell build/zipobj 2>/dev/null) BLAH2 := $(shell build/package 2>/dev/null) export ADDR2LINE -export OBJDUMP export CCNAME export CCVERSION export CP export DD export GZ export IMAGE_BASE_VIRTUAL +export LC_ALL export LOGFMT export MKDIR export MODE +export OBJDUMP export RM export SED -export SILENT +export SOURCE_DATE_EPOCH export TMPDIR +export V export ZFLAGS +unexport COMPILER_PATH +unexport CPATH +unexport CPLUS_INCLUDE_PATH +unexport C_INCLUDE_PATH +unexport DEPENDENCIES_OUTPUT +unexport GCC_COMPARE_DEBUG +unexport GCC_EXEC_PREFIX +unexport LANG +unexport LC_CTYPE +unexport LC_MESSAGES +unexport LIBRARY_PATH +unexport OBJC_INCLUDE_PATH +unexport SUNPRO_DEPENDENCIES + FTRACE = \ -pg SANITIZER = \ -fsanitize=leak \ - -fsanitize=address \ - -fsanitize=implicit-signed-integer-truncation \ - -fsanitize=implicit-integer-sign-change + -fsanitize=address NO_MAGIC = \ -mno-fentry \ @@ -154,8 +172,7 @@ MATHEMATICAL = \ DEFAULT_CPPFLAGS = \ -DIMAGE_BASE_VIRTUAL=$(IMAGE_BASE_VIRTUAL) \ -nostdinc \ - -iquote - \ - -iquote . + -iquote. DEFAULT_CFLAGS = \ -std=gnu2x diff --git a/build/do b/build/do index e6b39f29f..932a17f03 100755 --- a/build/do +++ b/build/do @@ -46,10 +46,10 @@ if [ "$OUT" ]; then fi # Log command. -if [ "$SILENT" = "0" ]; then - printf "%s\n" "$*" >&2 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-BUILD}" "$TARGET" >&2 +else + printf "%s\n" "$*" >&2 fi exec "$@" diff --git a/build/findtmp b/build/findtmp index 602183263..b49c312bf 100755 --- a/build/findtmp +++ b/build/findtmp @@ -13,7 +13,5 @@ # environment variable. Many programs use it under the hood, e.g. gcc, # so it grants many small performance improvements. -MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit - -$MKDIR o/tmp +mkdir -p o/tmp echo o/tmp diff --git a/build/getcompile b/build/getcompile new file mode 100755 index 000000000..3d330924a --- /dev/null +++ b/build/getcompile @@ -0,0 +1,12 @@ +#!/bin/sh +#-*-mode:sh;indent-tabs-mode:nil;tab-width:2;coding:utf-8-*-┐ +#───vi: set net ft=sh ts=2 sts=2 fenc=utf-8 :vi─────────────┘ + +if ! [ o/build/bootstrap/compile.com -nt build/bootstrap/compile.com ]; then + mkdir -p o/build/bootstrap/ + cp -f build/bootstrap/compile.com o/build/bootstrap/compile.$$.com + o/build/bootstrap/compile.$$.com --do-nothing + mv -f o/build/bootstrap/compile.$$.com o/build/bootstrap/compile.com +fi + +echo o/build/bootstrap/compile.com diff --git a/build/getlogfmt b/build/getlogfmt index 87a828adb..10003eb65 100755 --- a/build/getlogfmt +++ b/build/getlogfmt @@ -11,23 +11,19 @@ # This program is invoked once by build/definitions.mk to choose the # most appropriate format string when logging command invocations. -if [ "$SILENT" = "0" ]; then - printf "''" -else - W1=15 - if [ "$TERM" = "dumb" ]; then # e.g. emacs' dismal tty - if [ "$COLUMNS" = "" ]; then - if TPUT=$(command -v tput); then - COLUMNS=$("$TPUT" cols) - else - COLUMNS=80 - fi +W1=15 +if [ "$TERM" = "dumb" ]; then + if [ "$COLUMNS" = "" ]; then + if TPUT=$(command -v tput); then + COLUMNS=$("$TPUT" cols) + else + COLUMNS=80 fi - COLUMNS=$((COLUMNS - 1)) - W2=$((COLUMNS - W1)) - printf '%%-%ds%%-%ds\\r' "$W1" "$W2" - else - echo ♥cosmo >&2 - printf '\\033[F\\033[K%%-%ds%%s\\r\\n' "$W1" fi + COLUMNS=$((COLUMNS - 1)) + W2=$((COLUMNS - W1)) + printf '%%-%ds%%-%ds\\r' "$W1" "$W2" +else + echo ♥cosmo >&2 + printf '\\033[F\\033[K%%-%ds%%s\\r\\n' "$W1" fi diff --git a/build/link b/build/link index 7439197ca..6f0fc503d 100755 --- a/build/link +++ b/build/link @@ -19,7 +19,6 @@ if [ ! -d o/third_party/gcc ]; then third_party/gcc/unbundle.sh fi -export LC_ALL=C # very important for ld MKDIR=${MKDIR:-$(command -v mkdir) -p} || exit OUT= @@ -41,10 +40,10 @@ for x; do set -- "$@" "$x" done -if [ "$SILENT" = "0" ]; then - printf "%s\n" "$*" >&2 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-LINK.elf}" "$OUT" >&2 +else + printf "%s\n" "$*" >&2 fi OUTDIR="${OUT%/*}" diff --git a/build/mkdeps b/build/mkdeps index b6919ca4b..a4cbc0da2 100755 --- a/build/mkdeps +++ b/build/mkdeps @@ -13,10 +13,10 @@ else set -- o/build/bootstrap/mkdeps.com "$@" fi -if [ "$SILENT" = "0" ]; then - printf "%s\n" "$*" >&2 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-MKDEPS}" "$3" >&2 +else + printf "%s\n" "$*" >&2 fi exec "$@" diff --git a/build/package b/build/package index 6dbcf31e2..63ca44aaa 100755 --- a/build/package +++ b/build/package @@ -20,14 +20,14 @@ else fi printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 -# if [ "$SILENT" = "0" ]; then +# if [ "$V" = "0" ]; then +# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 +# else # COLUMNS=${COLUMNS:-80} # COLUMNS=$((COLUMNS - 4)) # printf "%s\n" "$*" | # /usr/bin/fold -s -w $COLUMNS | # sed -e '1bb' -e 's/^/ /' -e ':b' -e '$b' -e 's/$/ \\/' >&2 -# else -# printf "$LOGFMT" "${ACTION:-PACKAGE}" "$3" >&2 # fi exec "$@" diff --git a/build/rules.mk b/build/rules.mk index 991e95721..0edb2153e 100644 --- a/build/rules.mk +++ b/build/rules.mk @@ -17,72 +17,72 @@ MAKEFLAGS += --no-builtin-rules o/%.a:; @$(ARCHIVE) $@ $^ -o/%.o: %.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/%.o: o/%.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/%.s: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/%.s: o/%.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/%.i: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/%.o: %.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/%.o: o/%.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/%.s: %.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< -o/%.s: o/%.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< -o/%.o: %.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< -o/%.o: o/%.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< -o/%.lds: %.lds; @ACTION=PREPROCESS build/compile $(PREPROCESS.lds) $(OUTPUT_OPTION) $< -o/%.inc: %.h; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $< +o/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/%.o: o/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.s: o/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/%.o: o/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $< +o/%.s: o/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $< +o/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/%.o: o/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $< +o/%.inc: %.h; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $< o/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) -o/%.h.ok: %.h; @ACTION=CHECK.h build/compile $(COMPILE.c) -x c -g0 -o $@ $< -o/%.h.okk: %.h; @ACTION=CHECK.h build/compile $(COMPILE.cxx) -x c++ -g0 -o $@ $< -o/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $< +o/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $< +o/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< o/%.zip.o: o/%; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $< o/$(MODE)/%.a:; @$(ARCHIVE) $@ $^ -o/$(MODE)/%: o/$(MODE)/%.dbg; @ACTION=OBJCOPY TARGET=$@ build/do $(OBJCOPY) -SO binary $< $@ -o/$(MODE)/%.o: %.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.s; @TARGET=$@ build/assemble $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/$(MODE)/%.s: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.s: o/$(MODE)/%.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.f; @ACTION=OBJECTIFY.f build/compile $(OBJECTIFY.f) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.F; @ACTION=OBJECTIFY.F build/compile $(OBJECTIFY.F) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ss: %.c; @ACTION=COMPILE.c build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ss: o/$(MODE)/%.c; @ACTION=OBJECTIFY.s build/compile $(COMPILE.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.i: %.S; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.i: %.c; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.i: %.cc; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.i: o/$(MODE)/%.c; @ACTION=PREPROCESS build/compile $(PREPROCESS) $(OUTPUT_OPTION) $< -o/$(MODE)/%.h: %.c; @ACTION=AMALGAMATE build/compile $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< -o/$(MODE)/%.h: o/$(MODE)/%.c; @ACTION=AMALGAMATE build/compile $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< -o/$(MODE)/%.o: %.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.S; @ACTION=OBJECTIFY.S build/compile $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/$(MODE)/%.s: %.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< -o/$(MODE)/%.s: o/$(MODE)/%.i; @ACTION=COMPILE.i build/compile $(COMPILE.i) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.cc; @ACTION=OBJECTIFY.cxx build/compile $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< -o/$(MODE)/%.lds: %.lds; @ACTION=PREPROCESS build/compile $(PREPROCESS.lds) $(OUTPUT_OPTION) $< -o/$(MODE)/%.h.ok: %.h; @ACTION=CHECK.h build/compile $(COMPILE.c) -x c -g0 -o $@ $< -o/$(MODE)/%.h.okk: %.h; @ACTION=CHECK.h build/compile $(COMPILE.cxx) -x c++ -g0 -o $@ $< -o/$(MODE)/%.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg build/compile $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ansi.o: %.ansi.c; @ACTION=OBJECTIFY.ansi build/compile $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ansi.o: %.c; @ACTION=OBJECTIFY.ansi build/compile $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.c99.o: %.c99.c; @ACTION=OBJECTIFY.c99 build/compile $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 build/compile $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x build/compile $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init build/compile $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc build/compile $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.real.o: %.c; @ACTION=OBJECTIFY.real build/compile $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%: o/$(MODE)/%.dbg; @ACTION=OBJCOPY TARGET=$@ $(COMPILE) $(OBJCOPY) -SO binary $< $@ +o/$(MODE)/%.o: %.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.s; @TARGET=$@ $(COMPILE) $(OBJECTIFY.s) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: o/$(MODE)/%.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ss: %.c; @ACTION=COMPILE.c $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ss: o/$(MODE)/%.c; @ACTION=OBJECTIFY.s $(COMPILE) $(COMPILE.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.S; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: %.cc; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.i: o/$(MODE)/%.c; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) $< +o/$(MODE)/%.h: %.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< +o/$(MODE)/%.h: o/$(MODE)/%.c; @ACTION=AMALGAMATE $(COMPILE) $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< +o/$(MODE)/%.o: %.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.S; @ACTION=OBJECTIFY.S $(COMPILE) $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: %.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $< +o/$(MODE)/%.s: o/$(MODE)/%.i; @ACTION=COMPILE.i $(COMPILE) $(COMPILE.i) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: %.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.cc; @ACTION=OBJECTIFY.cxx $(COMPILE) $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< +o/$(MODE)/%.lds: %.lds; @ACTION=PREPROCESS $(COMPILE) $(PREPROCESS.lds) $(OUTPUT_OPTION) $< +o/$(MODE)/%.h.ok: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.c) -x c -g0 -o $@ $< +o/$(MODE)/%.h.okk: %.h; @ACTION=CHECK.h $(COMPILE) $(COMPILE.cxx) -x c++ -g0 -o $@ $< +o/$(MODE)/%.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.greg.o: %.greg.c; @ACTION=OBJECTIFY.greg $(COMPILE) $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ansi.o: %.ansi.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ansi.o: %.c; @ACTION=OBJECTIFY.ansi $(COMPILE) $(OBJECTIFY.ansi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c99.o: %.c99.c; @ACTION=OBJECTIFY.c99 $(COMPILE) $(OBJECTIFY.c99.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c11.o: %.c11.c; @ACTION=OBJECTIFY.c11 $(COMPILE) $(OBJECTIFY.c11.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.c2x.o: %.c2x.c; @ACTION=OBJECTIFY.c2x $(COMPILE) $(OBJECTIFY.c2x.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.initabi.o: %.initabi.c; @ACTION=OBJECTIFY.init $(COMPILE) $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.ncabi.o: %.ncabi.c; @ACTION=OBJECTIFY.nc $(COMPILE) $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $< +o/$(MODE)/%.real.o: %.c; @ACTION=OBJECTIFY.real $(COMPILE) $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $< o/$(MODE)/%.runs: o/$(MODE)/%; @ACTION=CHECK.runs TARGET=$< build/runcom $< $(TESTARGS) && touch $@ o/$(MODE)/%.pkg:; @build/package $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^) o/$(MODE)/%.zip.o: %; @build/zipobj $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $< -o/$(MODE)/%-gcc.asm: %.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< +o/$(MODE)/%-gcc.asm: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< o/$(MODE)/%-clang.asm: CC = $(CLANG) -o/$(MODE)/%-clang.asm: %.c; @ACTION=OBJECTIFY.c build/compile $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ -o/$(MODE)/%-gcc.asm: %.f; @ACTION=OBJECTIFY.f build/compile $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: %.c; @ACTION=OBJECTIFY.c $(COMPILE) $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ +o/$(MODE)/%-gcc.asm: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $< o/$(MODE)/%-clang.asm: CC = $(CLANG) -o/$(MODE)/%-clang.asm: %.f; @ACTION=OBJECTIFY.f build/compile $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ -o/$(MODE)/%-gcc.asm: %.F; @ACTION=OBJECTIFY.F build/compile $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $< +o/$(MODE)/%-clang.asm: %.f; @ACTION=OBJECTIFY.f $(COMPILE) $(OBJECTIFY.f) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ +o/$(MODE)/%-gcc.asm: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $< o/$(MODE)/%-clang.asm: CC = $(CLANG) -o/$(MODE)/%-clang.asm: %.F; @ACTION=OBJECTIFY.F build/compile $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ +o/$(MODE)/%-clang.asm: %.F; @ACTION=OBJECTIFY.F $(COMPILE) $(OBJECTIFY.F) -S -g0 $(OUTPUT_OPTION) $< || echo / need $(CLANG) >$@ diff --git a/build/zipobj b/build/zipobj index dfa1a89aa..02a9097d9 100755 --- a/build/zipobj +++ b/build/zipobj @@ -42,10 +42,10 @@ else set -- o/build/bootstrap/zipobj.com "$@" fi -if [ "$SILENT" = "0" ]; then - printf "%s\n" "$*" >&2 -else +if [ "$V" = "0" ]; then printf "$LOGFMT" "${ACTION:-ZIPOBJ}" "$3" >&2 +else + printf "%s\n" "$*" >&2 fi exec "$@" diff --git a/libc/calls/calls.h b/libc/calls/calls.h index 0198a637b..100254d39 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -1,7 +1,14 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ #define COSMOPOLITAN_LIBC_CALLS_SYSCALLS_H_ +#include "libc/calls/struct/iovec.h" +#include "libc/calls/struct/rlimit.h" +#include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/sysinfo.h" #include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/tms.h" +#include "libc/calls/struct/utsname.h" #include "libc/calls/typedef/sighandler_t.h" #include "libc/dce.h" #include "libc/fmt/pflink.h" @@ -54,17 +61,6 @@ COSMOPOLITAN_C_START_ │ cosmopolitan § system calls ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ -struct dirstream; -struct iovec; -struct rlimit; -struct rusage; -struct sigaction; -struct sigset; -struct stat; -struct sysinfo; -struct tms; -struct utsname; - typedef int sig_atomic_t; typedef struct dirstream DIR; @@ -196,12 +192,12 @@ int wait(int *); int wait3(int *, int, struct rusage *); int wait4(int, int *, int, struct rusage *); int waitpid(int, int *, int); -int64_t lseek(int, int64_t, int); -int64_t pread(int, void *, size_t, int64_t); -int64_t preadv(int, struct iovec *, int, int64_t); -int64_t pwrite(int, const void *, size_t, int64_t); -int64_t pwritev(int, const struct iovec *, int, int64_t); -int64_t syscall(); +ssize_t lseek(int, int64_t, unsigned); +ssize_t pread(int, void *, size_t, int64_t); +ssize_t preadv(int, struct iovec *, int, int64_t); +ssize_t pwrite(int, const void *, size_t, int64_t); +ssize_t pwritev(int, const struct iovec *, int, int64_t); +intptr_t syscall(int, ...); void sync(void); long telldir(DIR *); int getpid(void); diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index ae2afe0e1..38227c8b2 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -17,7 +17,6 @@ LIBC_CALLS = $(LIBC_CALLS_A_DEPS) $(LIBC_CALLS_A) LIBC_CALLS_A = o/$(MODE)/libc/calls/syscalls.a LIBC_CALLS_A_FILES := \ $(wildcard libc/calls/typedef/*) \ - $(wildcard libc/calls/thunks/*) \ $(wildcard libc/calls/struct/*) \ $(wildcard libc/calls/*) LIBC_CALLS_A_HDRS = $(filter %.h,$(LIBC_CALLS_A_FILES)) diff --git a/libc/calls/chmod.c b/libc/calls/chmod.c index 7dba99b96..3404c5f41 100644 --- a/libc/calls/chmod.c +++ b/libc/calls/chmod.c @@ -44,6 +44,5 @@ * @see fchmod() */ int chmod(const char *pathname, uint32_t mode) { - if (!pathname) return efault(); return sys_fchmodat(AT_FDCWD, pathname, mode, 0); } diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index 9d64dab2e..336fe2f13 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -16,22 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/bits/safemacros.h" -#include "libc/calls/calls.h" +#include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" -#include "libc/dce.h" #include "libc/fmt/conv.h" -#include "libc/mach.h" -#include "libc/nt/struct/filetime.h" -#include "libc/nt/struct/systemtime.h" #include "libc/nt/synchronization.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/consts/fileno.h" #include "libc/sysv/errfuns.h" -#include "libc/time/time.h" /** * Returns nanosecond time. @@ -43,40 +33,34 @@ * @param clockid can be CLOCK_REALTIME, CLOCK_MONOTONIC, etc. noting * that on Linux CLOCK_MONOTONIC is redefined to use the monotonic * clock that's actually monotonic lool - * @param out_ts is where the nanoseconds are stored if non-NULL - * @return 0 on success or -1 w/ errno on error + * @param ts is where the result is stored + * @return 0 on success, or -1 w/ errno * @error ENOSYS if clockid isn't available; in which case this function - * guarantees an ordinary timestamp is still stored to out_ts; and + * guarantees an ordinary timestamp is still stored to ts; and * errno isn't restored to its original value, to detect prec. loss * @see strftime(), gettimeofday() * @asyncsignalsafe */ -int clock_gettime(int clockid, struct timespec *out_ts) { - /* TODO(jart): Just ignore O/S for MONOTONIC and measure RDTSC on start */ +int clock_gettime(int clockid, struct timespec *ts) { + int rc; + axdx_t ad; + struct NtFileTime ft; + if (!ts) return efault(); if (!IsWindows()) { - if (!IsXnu()) { - if (out_ts) { - out_ts->tv_sec = 0; - out_ts->tv_nsec = 0; + if ((rc = sys_clock_gettime(clockid, ts)) == -1 && errno == ENOSYS) { + ad = sys_gettimeofday((struct timeval *)ts, NULL, NULL); + assert(ad.ax != -1); + if (SupportsXnu() && ad.ax) { + ts->tv_sec = ad.ax; + ts->tv_nsec = ad.dx; } - return sys_clock_gettime(clockid, out_ts); - } else { - int rc; - _Static_assert(sizeof(struct timeval) == sizeof(struct timespec)); - if (out_ts) { - out_ts->tv_sec = 0; - out_ts->tv_nsec = 0; - } - rc = sys_gettimeofday((struct timeval *)out_ts, NULL); - if (out_ts) { - out_ts->tv_nsec *= 1000; - } - return rc; + ts->tv_nsec *= 1000; + rc = 0; } + return rc; } else { - struct NtFileTime ft; GetSystemTimeAsFileTime(&ft); - *out_ts = FileTimeToTimeSpec(ft); + *ts = FileTimeToTimeSpec(ft); return 0; } } diff --git a/libc/calls/execve-sysv.c b/libc/calls/execve-sysv.c index c7357be64..2c77471a5 100644 --- a/libc/calls/execve-sysv.c +++ b/libc/calls/execve-sysv.c @@ -27,7 +27,7 @@ int sys_execve(const char *prog, char *const argv[], char *const envp[]) { size_t i; char **shargs; - if (__sys_execve(prog, argv, envp) != -1) return 0; + __sys_execve(prog, argv, envp); if (errno != ENOEXEC) return -1; for (i = 0; argv[i];) ++i; shargs = alloca((i + 2) * sizeof(char *)); diff --git a/libc/calls/faccessat.c b/libc/calls/faccessat.c index 651500676..d599f14d2 100644 --- a/libc/calls/faccessat.c +++ b/libc/calls/faccessat.c @@ -34,7 +34,6 @@ * @asyncsignalsafe */ int faccessat(int dirfd, const char *path, int mode, uint32_t flags) { - if (!path) return efault(); if (!IsWindows()) { return sys_faccessat(dirfd, path, mode, flags); } else { diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c index 0fe03ff90..2a0b75473 100644 --- a/libc/calls/ftruncate.c +++ b/libc/calls/ftruncate.c @@ -33,7 +33,7 @@ */ int ftruncate(int fd, int64_t length) { if (!IsWindows()) { - return sys_ftruncate(fd, length); + return sys_ftruncate(fd, length, length); } else { return sys_ftruncate_nt(fd, length); } diff --git a/libc/calls/getcwd-nt.c b/libc/calls/getcwd-nt.c index 4c4a8550d..db109370e 100644 --- a/libc/calls/getcwd-nt.c +++ b/libc/calls/getcwd-nt.c @@ -23,7 +23,7 @@ #include "libc/sysv/errfuns.h" textwindows char *sys_getcwd_nt(char *buf, size_t size) { - uint16_t name16[PATH_MAX]; + char16_t name16[PATH_MAX]; if (GetCurrentDirectory(ARRAYLEN(name16), name16)) { tprecode16to8(buf, size, name16); return buf; diff --git a/libc/calls/getcwd-xnu.c b/libc/calls/getcwd-xnu.c index 7e404bc83..4da7837f0 100644 --- a/libc/calls/getcwd-xnu.c +++ b/libc/calls/getcwd-xnu.c @@ -24,9 +24,8 @@ #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" -#define NETBSD_F_GETPATH 15 -#define XNU_F_GETPATH 50 -#define XNU_MAXPATHLEN 1024 +#define XNU_F_GETPATH 50 +#define XNU_MAXPATHLEN 1024 char *sys_getcwd_xnu(char *res, size_t size) { int fd; diff --git a/libc/calls/getenv.c b/libc/calls/getenv.c index cff58f1e9..a85c9f6b6 100644 --- a/libc/calls/getenv.c +++ b/libc/calls/getenv.c @@ -20,6 +20,8 @@ /** * Returns value of environment variable, or NULL if not found. + * + * Environment variables can store empty string on Unix but not Windows. */ char *getenv(const char *s) { char **p; @@ -29,7 +31,7 @@ char *getenv(const char *s) { for (j = 0;; ++j) { if (!s[j]) { if (p[i][j] == '=') { - return &p[i][j + 1]; + return p[i] + j + 1; } break; } diff --git a/libc/calls/thunks/fork-sysv.S b/libc/calls/gethostname-bsd.c similarity index 71% rename from libc/calls/thunks/fork-sysv.S rename to libc/calls/gethostname-bsd.c index 55f2cb11d..23d5317c8 100644 --- a/libc/calls/thunks/fork-sysv.S +++ b/libc/calls/gethostname-bsd.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2021 Justine Alexandra Roberts Tunney │ │ │ @@ -16,26 +16,27 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/macros.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/str/str.h" -/ Makes fork() kernel ABI consistent across UNIX systems. -/ -/ @return 0 if parent, pid if child, or -1 on error -sys_fork: - push %rbp - mov %rsp,%rbp - .profilable - call __sys_fork -#if SupportsXnu() - testb IsXnu() - jz 1f - cmp $-1,%rax - je 1f - neg %edx # edx is 0 for parent and 1 for child - not %edx # eax always returned with childs pid - and %edx,%eax -#endif -1: pop %rbp - ret - .endfn sys_fork,globl,hidden +#define CTL_KERN 1 +#define KERN_HOSTNAME 10 + +int gethostname_bsd(char *name, size_t len) { + char *p; + int cmd[2]; + char buf[254]; + size_t buflen; + cmd[0] = CTL_KERN; + cmd[1] = KERN_HOSTNAME; + buflen = sizeof(buf); + if (sysctl(cmd, 2, buf, &buflen, NULL, 0) == -1) { + if (errno == ENOMEM) errno = ENAMETOOLONG; + return -1; + } + strncpy(name, buf, len); + name[len - 1] = '\0'; + if ((p = strchr(name, '.'))) *p = '\0'; + return 0; +} diff --git a/libc/calls/thunks/pread-sysv.S b/libc/calls/gethostname-linux.c similarity index 77% rename from libc/calls/thunks/pread-sysv.S rename to libc/calls/gethostname-linux.c index c046cc598..fac5b9b9c 100644 --- a/libc/calls/thunks/pread-sysv.S +++ b/libc/calls/gethostname-linux.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2020 Justine Alexandra Roberts Tunney │ │ │ @@ -16,11 +16,16 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/calls/struct/utsname.h" +#include "libc/str/str.h" +#include "libc/sysv/errfuns.h" -/ Directly calls pread() impl on host o/s if available. -sys_pread: - mov %rcx,%r8 # netbsd+openbsd:pad - jmp __sys_pread - .endfn sys_pread,globl,hidden +int gethostname_linux(char *name, size_t len) { + struct utsname u; + if (uname(&u) == -1) return -1; + memccpy(name, u.nodename, '\0', len); + name[len - 1] = '\0'; + return 0; +} diff --git a/libc/calls/thunks/lseek-sysv.S b/libc/calls/gethostname-nt.c similarity index 73% rename from libc/calls/thunks/lseek-sysv.S rename to libc/calls/gethostname-nt.c index f97982135..9d5a513be 100644 --- a/libc/calls/thunks/lseek-sysv.S +++ b/libc/calls/gethostname-nt.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2020 Justine Alexandra Roberts Tunney │ │ │ @@ -16,22 +16,20 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/macros.h" -.source __FILE__ +#include "libc/calls/calls.h" +#include "libc/calls/internal.h" +#include "libc/nt/enum/computernameformat.h" +#include "libc/nt/systeminfo.h" +#include "libc/str/str.h" -/ Directly calls lseek() impl on host o/s if available. -sys_lseek: -#if SupportsOpenbsd() || SupportsNetbsd() - testb $OPENBSD|NETBSD,__hostos(%rip) - cmovnz %rdx,%rcx # openbsd:evilpad - cmovnz %rsi,%rdx - cmovnz .Lzero(%rip),%rsi -#endif - jmp __sys_lseek - .endfn sys_lseek,globl,hidden - - .rodata.cst8 -.Lzero: .quad 0 - .endobj .Lzero - .previous +textwindows int gethostname_nt(char *name, size_t len) { + uint32_t nSize; + char16_t name16[256]; + nSize = ARRAYLEN(name16); + if (GetComputerNameEx(kNtComputerNameDnsHostname, name16, &nSize)) { + tprecode16to8(name, len, name16); + return 0; + } else { + return __winerr(); + } +} diff --git a/libc/calls/gethostname.c b/libc/calls/gethostname.c index 006c6dd3c..5e4337331 100644 --- a/libc/calls/gethostname.c +++ b/libc/calls/gethostname.c @@ -18,20 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/utsname.h" #include "libc/dce.h" -#include "libc/errno.h" -#include "libc/macros.h" -#include "libc/nt/enum/computernameformat.h" -#include "libc/nt/errors.h" -#include "libc/nt/runtime.h" -#include "libc/nt/systeminfo.h" -#include "libc/str/str.h" #include "libc/sysv/errfuns.h" -#define CTL_KERN 1 -#define KERN_HOSTNAME 10 - /** * Returns name of host system, e.g. * @@ -42,38 +31,12 @@ int gethostname(char *name, size_t len) { if (len < 1) return einval(); if (!name) return efault(); if (!IsWindows()) { - if (IsBsd()) { - char *p; - int cmd[2]; - char buf[254]; - size_t buflen; - cmd[0] = CTL_KERN; - cmd[1] = KERN_HOSTNAME; - buflen = sizeof(buf); - if (sysctl(cmd, 2, buf, &buflen, NULL, 0) == -1) { - if (errno == ENOMEM) errno = ENAMETOOLONG; - return -1; - } - strncpy(name, buf, len); - name[len - 1] = '\0'; - if ((p = strchr(name, '.'))) *p = '\0'; - return 0; + if (!IsBsd()) { + return gethostname_linux(name, len); } else { - struct utsname u; - if (uname(&u) == -1) return -1; - memccpy(name, u.nodename, '\0', len); - name[len - 1] = '\0'; - return 0; + return gethostname_bsd(name, len); } } else { - uint32_t nSize; - char16_t name16[256]; - nSize = ARRAYLEN(name16); - if (GetComputerNameEx(kNtComputerNameDnsHostname, name16, &nSize)) { - tprecode16to8(name, len, name16); - return 0; - } else { - return __winerr(); - } + return gethostname_nt(name, len); } } diff --git a/libc/calls/getrusage-nt.c b/libc/calls/getrusage-nt.c index fe8d22df9..12715daf4 100644 --- a/libc/calls/getrusage-nt.c +++ b/libc/calls/getrusage-nt.c @@ -25,12 +25,15 @@ #include "libc/nt/thread.h" #include "libc/str/str.h" #include "libc/sysv/consts/rusage.h" +#include "libc/sysv/errfuns.h" textwindows int sys_getrusage_nt(int who, struct rusage *usage) { struct NtFileTime CreationFileTime; struct NtFileTime ExitFileTime; struct NtFileTime KernelFileTime; struct NtFileTime UserFileTime; + if (!usage) return efault(); + if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */ memset(usage, 0, sizeof(*usage)); if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)( (who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(), diff --git a/libc/calls/getrusage.c b/libc/calls/getrusage.c index aa9b63915..285c8a32a 100644 --- a/libc/calls/getrusage.c +++ b/libc/calls/getrusage.c @@ -27,8 +27,6 @@ * @return 0 on success, or -1 w/ errno */ int getrusage(int who, struct rusage *usage) { - if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */ - if (!usage) return efault(); if (!IsWindows()) { return sys_getrusage(who, usage); } else { diff --git a/libc/calls/thunks/gettemppatha-flunk.S b/libc/calls/gettemppatha-flunk.S similarity index 97% rename from libc/calls/thunks/gettemppatha-flunk.S rename to libc/calls/gettemppatha-flunk.S index c1ee50493..f83cc661b 100644 --- a/libc/calls/thunks/gettemppatha-flunk.S +++ b/libc/calls/gettemppatha-flunk.S @@ -22,7 +22,7 @@ / Calls GetTempPathA() w/ different API. / / @see GetSystemDirectoryA(), GetWindowsDirectoryA() -GetTempPathA$flunk: +GetTempPathA_flunk: xchg %rcx,%rdx jmp *__imp_GetTempPathA(%rip) - .endfn GetTempPathA$flunk,globl,hidden + .endfn GetTempPathA_flunk,globl,hidden diff --git a/libc/calls/gettimeofday-sysv.S b/libc/calls/gettimeofday-sysv.S deleted file mode 100644 index f713c38f5..000000000 --- a/libc/calls/gettimeofday-sysv.S +++ /dev/null @@ -1,53 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/macros.h" - -/ Returns system wall time in microseconds. -/ -/ @param rdi points to timeval that receives result -/ @param rsi receives UTC timezone if non-NULL -/ @return always zero -/ @see clock_gettime() for nanosecond precision -/ @see strftime() for string formatting -sys_gettimeofday: - push %rbp - mov %rsp,%rbp - .profilable - test %rsi,%rsi - jz 1f - push $0 - pop (%rsi) -1: xor %esi,%esi # no one zones this way. - xor %edx,%edx # i64*mach_absolute_time - call __sys_gettimeofday -#if SupportsXnu() - testb IsXnu() # XNU might do %rax:%rdx - jz 1f - test %rdi,%rdi - jz 1f - test %rax,%rax - jz 1f - mov %rax,(%rdi) - mov %rdx,8(%rdi) -#endif -1: xor %eax,%eax # nevar fail - pop %rbp - ret - .endfn sys_gettimeofday,globl,hidden diff --git a/libc/calls/gettimeofday.c b/libc/calls/gettimeofday.c index 457581d83..81531d728 100644 --- a/libc/calls/gettimeofday.c +++ b/libc/calls/gettimeofday.c @@ -16,9 +16,11 @@ │ 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/timeval.h" #include "libc/dce.h" +#include "libc/sysv/errfuns.h" #include "libc/time/struct/timezone.h" #include "libc/time/time.h" @@ -32,8 +34,15 @@ * @see strftime() for string formatting */ int gettimeofday(struct timeval *tv, struct timezone *tz) { + axdx_t ad; if (!IsWindows()) { - return sys_gettimeofday(tv, tz); + ad = sys_gettimeofday(tv, tz, NULL); + assert(ad.ax != -1); + if (SupportsXnu() && ad.ax && tv) { + tv->tv_sec = ad.ax; + tv->tv_usec = ad.dx; + } + return 0; } else { return sys_gettimeofday_nt(tv, tz); } diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 0a6593570..c4ab6ad5a 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -100,6 +100,10 @@ forceinline size_t clampio(size_t size) { │ cosmopolitan § syscalls » system five » synthetic jump slots ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +axdx_t __sys_pipe(i32[hasatleast 2], i32) hidden; +axdx_t sys_fork(void) hidden; +axdx_t sys_getpid(void) hidden; +axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) hidden; char *sys_getcwd(char *, u64) hidden; char *sys_getcwd_xnu(char *, u64) hidden; i32 __sys_dup3(i32, i32, i32) hidden; @@ -127,11 +131,10 @@ i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden; i32 sys_fcntl(i32, i32, ...) hidden; i32 sys_fdatasync(i32) hidden; i32 sys_flock(i32, i32) hidden; -i32 sys_fork(void) hidden; i32 sys_fstat(i32, struct stat *) hidden; i32 sys_fstatat(i32, const char *, struct stat *, i32) hidden; i32 sys_fsync(i32) hidden; -i32 sys_ftruncate(i32, i64) hidden; +i32 sys_ftruncate(i32, i64, i64) hidden; i32 sys_futimes(i32, const struct timeval *) hidden; i32 sys_futimesat(i32, const char *, const struct timeval *) hidden; i32 sys_getitimer(i32, struct itimerval *) hidden; @@ -139,11 +142,10 @@ i32 sys_getppid(void) hidden; i32 sys_getpriority(i32, u32) hidden; i32 sys_getrlimit(i32, struct rlimit *) hidden; i32 sys_getrusage(i32, struct rusage *) hidden; -i32 sys_gettimeofday(struct timeval *, struct timezone *) hidden; i32 sys_ioctl(i32, u64, void *) hidden; i32 sys_kill(i32, i32, i32) hidden; i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden; -i32 sys_lseek(i32, i64, i32) hidden; +i32 sys_lseek(i32, i64, i64, i64) hidden; i32 sys_lutimes(const char *, const struct timeval *) hidden; i32 sys_madvise(void *, size_t, i32) hidden; i32 sys_memfd_create(const char *, u32) hidden; @@ -176,7 +178,7 @@ i32 sys_symlinkat(const char *, i32, const char *) hidden; i32 sys_sync(void) hidden; i32 sys_sync_file_range(i32, i64, i64, u32) hidden; i32 sys_sysinfo(struct sysinfo *) hidden; -i32 sys_truncate(const char *, u64) hidden; +i32 sys_truncate(const char *, u64, u64) hidden; i32 sys_uname(char *) hidden; i32 sys_unlinkat(i32, const char *, i32) hidden; i32 sys_utime(const char *, const struct utimbuf *) hidden; @@ -185,22 +187,21 @@ i32 sys_utimes(const char *, const struct timeval *) hidden; i32 sys_wait4(i32, i32 *, i32, struct rusage *) hidden; i64 sys_copy_file_range(i32, long *, i32, long *, u64, u32) hidden; i64 sys_getrandom(void *, u64, u32) hidden; -i64 sys_pread(i32, void *, u64, i64) hidden; -i64 sys_preadv(i32, struct iovec *, i32, i64) hidden; +i64 sys_pread(i32, void *, u64, i64, i64) hidden; +i64 sys_preadv(i32, struct iovec *, i32, i64, i64) hidden; i64 sys_ptrace(int, i32, void *, void *) hidden; -i64 sys_pwrite(i32, const void *, u64, i64) hidden; -i64 sys_pwritev(i32, const struct iovec *, i32, i64) hidden; +i64 sys_pwrite(i32, const void *, u64, i64, i64) hidden; +i64 sys_pwritev(i32, const struct iovec *, i32, i64, i64) hidden; i64 sys_read(i32, void *, u64) hidden; i64 sys_sendfile(i32, i32, i64 *, u64) hidden; i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) hidden; i64 sys_vmsplice(i32, const struct iovec *, i64, u32) hidden; i64 sys_write(i32, const void *, u64) hidden; u32 sys_getgid(void) hidden; -axdx_t sys_getpid(void) hidden; u32 sys_getsid(int) hidden; u32 sys_gettid(void) hidden; u32 sys_getuid(void) hidden; -void *sys_mmap(void *, u64, u32, u32, i64, i64) hidden; +void *sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden; void *sys_mremap(void *, u64, u64, i32, void *) hidden; /*───────────────────────────────────────────────────────────────────────────│─╗ @@ -219,6 +220,9 @@ void __stat2linux(void *) hidden; void __restore_rt_netbsd(void) hidden; void __xnutrampoline(void *, i32, i32, const struct __darwin_siginfo *, const struct __darwin_ucontext *) hidden wontreturn; +int gethostname_linux(char *, size_t) hidden; +int gethostname_bsd(char *, size_t) hidden; +int gethostname_nt(char *, size_t) hidden; /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § syscalls » windows nt » veneers ─╬─│┼ diff --git a/libc/calls/ioctl-tcgets.c b/libc/calls/ioctl-tcgets.c index 262e93e6e..2ad11362c 100644 --- a/libc/calls/ioctl-tcgets.c +++ b/libc/calls/ioctl-tcgets.c @@ -27,7 +27,7 @@ static int ioctl_tcgets_sysv(int fd, struct termios *tio) { int rc; union metatermios t; if ((rc = sys_ioctl(fd, TCGETS, &t)) != -1) { - termios2linux(tio, &t); + __termios2linux(tio, &t); } return rc; } diff --git a/libc/calls/ioctl-tcsets.c b/libc/calls/ioctl-tcsets.c index 141b3b85f..867a90783 100644 --- a/libc/calls/ioctl-tcsets.c +++ b/libc/calls/ioctl-tcsets.c @@ -21,13 +21,14 @@ #include "libc/calls/termios.internal.h" #include "libc/dce.h" #include "libc/sysv/consts/termios.h" +#include "libc/sysv/errfuns.h" int ioctl_tcsets_nt(int, uint64_t, const struct termios *); static int ioctl_tcsets_sysv(int fd, uint64_t request, const struct termios *tio) { union metatermios t; - return sys_ioctl(fd, request, termios2host(&t, tio)); + return sys_ioctl(fd, request, __termios2host(&t, tio)); } /** @@ -38,6 +39,7 @@ static int ioctl_tcsets_sysv(int fd, uint64_t request, * @see ioctl(fd, TIOCGETA{,W,F}, tio) dispatches here */ int ioctl_tcsets(int fd, uint64_t request, const struct termios *tio) { + if (!tio) return efault(); if (!IsWindows()) { return ioctl_tcsets_sysv(fd, request, tio); } else { diff --git a/libc/calls/ktmppath.S b/libc/calls/ktmppath.S index e8041acbc..a0158b81c 100644 --- a/libc/calls/ktmppath.S +++ b/libc/calls/ktmppath.S @@ -35,7 +35,7 @@ kTmpPath: movl $'/|'t<<010|'m<<020|'p<<030,(%rdi) movw $'/,4(%rdi) pushpop kTmpPathMax,%rdx - ezlea GetTempPathA$flunk,ax + ezlea GetTempPathA_flunk,ax call __getntsyspath .init.end 300,_init_kTmpPath .source __FILE__ diff --git a/libc/calls/link.c b/libc/calls/link.c index 69a975c12..36362510c 100644 --- a/libc/calls/link.c +++ b/libc/calls/link.c @@ -16,11 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/calls/internal.h" #include "libc/calls/calls.h" -#include "libc/sysv/errfuns.h" +#include "libc/calls/internal.h" +#include "libc/dce.h" #include "libc/sysv/consts/at.h" +#include "libc/sysv/errfuns.h" /** * Creates hard filesystem link. @@ -32,7 +32,6 @@ * @asyncsignalsafe */ int link(const char *existingpath, const char *newpath) { - if (!existingpath || !newpath) return efault(); if (!IsWindows()) { return sys_linkat(AT_FDCWD, existingpath, AT_FDCWD, newpath, 0); } else { diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c index d63daec35..2cc889dd0 100644 --- a/libc/calls/lseek.c +++ b/libc/calls/lseek.c @@ -29,9 +29,11 @@ * @return new position relative to beginning, or -1 on error * @asyncsignalsafe */ -int64_t lseek(int fd, int64_t offset, int whence) { - if (!IsWindows()) { - return sys_lseek(fd, offset, whence); +int64_t lseek(int fd, int64_t offset, unsigned whence) { + if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) { + return sys_lseek(fd, offset, whence, 0); + } else if (IsOpenbsd() || IsNetbsd()) { + return sys_lseek(fd, offset, offset, whence); } else { return sys_lseek_nt(fd, offset, whence); } diff --git a/libc/calls/mkntpath.c b/libc/calls/mkntpath.c index e997433a8..1c53b3a7f 100644 --- a/libc/calls/mkntpath.c +++ b/libc/calls/mkntpath.c @@ -71,6 +71,7 @@ textwindows int __mkntpath2(const char *path, * 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0" */ size_t i, n; + if (!path) return efault(); path = FixNtMagicPath(path, flags); n = tprecode8to16(path16, PATH_MAX - 16, path).ax; if (n == PATH_MAX - 16 - 1) return enametoolong(); diff --git a/libc/calls/nanosleep.c b/libc/calls/nanosleep.c index 58581590f..da817ad73 100644 --- a/libc/calls/nanosleep.c +++ b/libc/calls/nanosleep.c @@ -26,16 +26,12 @@ */ int nanosleep(const struct timespec *req, struct timespec *rem) { if (!req) return efault(); - if (!IsWindows()) { - if (!IsMetal()) { - if (!IsXnu()) { - return sys_nanosleep(req, rem); - } else { - return sys_nanosleep_xnu(req, rem); - } - } else { - return enosys(); /* TODO: Sleep on Metal */ - } + if (!IsWindows() && !IsMetal() && !IsXnu()) { + return sys_nanosleep(req, rem); + } else if (IsXnu()) { + return sys_nanosleep_xnu(req, rem); + } else if (IsMetal()) { + return enosys(); /* TODO: Sleep on Metal */ } else { return sys_nanosleep_nt(req, rem); } diff --git a/libc/calls/onntconsoleevent_init.S b/libc/calls/onntconsoleevent_init.S index deb6a748d..b493e4861 100644 --- a/libc/calls/onntconsoleevent_init.S +++ b/libc/calls/onntconsoleevent_init.S @@ -17,8 +17,14 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.h" +.text.windows .source __FILE__ +__onntconsoleevent_nt: + ezlea __onntconsoleevent,ax + jmp __nt2sysv + .endfn __onntconsoleevent_nt,globl,hidden + .init.start 300,_init_onntconsoleevent ezlea __onntconsoleevent_nt,cx pushpop 1,%rdx diff --git a/libc/calls/thunks/onwincrash.S b/libc/calls/onwincrash.S similarity index 100% rename from libc/calls/thunks/onwincrash.S rename to libc/calls/onwincrash.S diff --git a/libc/calls/openat.c b/libc/calls/openat.c index 79820ae97..6816371a8 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -39,7 +39,7 @@ * @asyncsignalsafe * @vforksafe */ -nodiscard int openat(int dirfd, const char *file, int flags, ...) { +int openat(int dirfd, const char *file, int flags, ...) { va_list va; unsigned mode; struct ZiposUri zipname; diff --git a/libc/calls/pipe-nt.c b/libc/calls/pipe-nt.c index 79782dedd..b86c959da 100644 --- a/libc/calls/pipe-nt.c +++ b/libc/calls/pipe-nt.c @@ -78,9 +78,13 @@ textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) { pipefd[1] = writer; return 0; } else { + __winerr(); CloseHandle(hin); } + } else { + __winerr(); } + __releasefd(writer); __releasefd(reader); - return __winerr(); + return -1; } diff --git a/libc/calls/pipe-sysv.S b/libc/calls/pipe-sysv.S deleted file mode 100644 index 2a436a98b..000000000 --- a/libc/calls/pipe-sysv.S +++ /dev/null @@ -1,48 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/dce.h" -#include "libc/macros.h" -.source __FILE__ - -/ Creates file descriptors for IPC. -/ -/ @param rdi points to int3[2] that gets (reader, writer) -/ @return 0 on success or -1 w/ errno -/ @asyncsignalsafe -/ @see libc/sysv/syscalls.sh -/ @see pipe2() -sys_pipe: - push %rbp - mov %rsp,%rbp -#if SupportsFreebsd() - xor %esi,%esi -#endif - call __sys_pipe -#if SupportsXnu() || SupportsNetbsd() - testb $XNU|NETBSD,__hostos(%rip) - jz 1f - cmp $-1,%rax - je 1f - mov %eax,(%rdi) - mov %edx,4(%rdi) - xor %eax,%eax -#endif -1: pop %rbp - ret - .endfn sys_pipe,globl,hidden diff --git a/libc/calls/thunks/sigsuspend-sysv.S b/libc/calls/pipe-sysv.c similarity index 80% rename from libc/calls/thunks/sigsuspend-sysv.S rename to libc/calls/pipe-sysv.c index 55b5f9064..575337099 100644 --- a/libc/calls/thunks/sigsuspend-sysv.S +++ b/libc/calls/pipe-sysv.c @@ -1,5 +1,5 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2021 Justine Alexandra Roberts Tunney │ │ │ @@ -16,19 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" #include "libc/dce.h" -#include "libc/macros.h" -/ Pauses process w/ standard ABI. -sys_sigsuspend: - push %rbp - mov %rsp,%rbp -#if SupportsOpenbsd() - testb IsOpenbsd() - jz 1f - mov (%rdi),%edi # openbsd:byvalue -#endif -1: call __sys_sigsuspend - pop %rbp - ret - .endfn sys_sigsuspend,globl +int sys_pipe(int fds[2]) { + axdx_t ad; + int ax, dx; + ad = __sys_pipe(fds, 0); + ax = ad.ax; + dx = ad.dx; + if ((IsXnu() || IsNetbsd()) && ax != -1) { + fds[0] = ax; + fds[1] = dx; + ax = 0; + } + return ax; +} diff --git a/libc/calls/pipe2.c b/libc/calls/pipe2.c index 638ffa85e..1056f8edd 100644 --- a/libc/calls/pipe2.c +++ b/libc/calls/pipe2.c @@ -16,9 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/dce.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/pread.c b/libc/calls/pread.c index 68c2406a0..ac769ed9f 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -47,7 +47,7 @@ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { rc = weaken(__zipos_read)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, buf, size, offset); } else if (!IsWindows()) { - rc = sys_pread(fd, buf, size, offset); + rc = sys_pread(fd, buf, size, offset, offset); } else if (__isfdkind(fd, kFdFile)) { rc = sys_read_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset); } else { diff --git a/libc/calls/preadv.c b/libc/calls/preadv.c index 076dfe516..f1813fc5d 100644 --- a/libc/calls/preadv.c +++ b/libc/calls/preadv.c @@ -17,12 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" -#include "libc/bits/safemacros.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/macros.h" #include "libc/sysv/consts/iov.h" #include "libc/sysv/errfuns.h" @@ -42,7 +42,7 @@ ssize_t preadv(int fd, struct iovec *iovec, int count, int64_t off) { int olderr; ssize_t rc; if (!count) return 0; - if ((count = min(count, IOV_MAX)) < 0) return einval(); + if ((count = MIN(count, IOV_MAX)) < 0) return einval(); /* * NT, XNU, and 2007-era Linux don't support this system call. @@ -58,7 +58,7 @@ ssize_t preadv(int fd, struct iovec *iovec, int count, int64_t off) { demodernize = true; } else { olderr = errno; - rc = sys_preadv(fd, iovec, count, off); + rc = sys_preadv(fd, iovec, count, off, off); if (rc == -1 && errno == ENOSYS) { errno = olderr; demodernize = true; @@ -71,7 +71,7 @@ ssize_t preadv(int fd, struct iovec *iovec, int count, int64_t off) { } if (!demodernize) { - return sys_preadv(fd, iovec, count, off); + return sys_preadv(fd, iovec, count, off, off); } else { return pread(fd, iovec[0].iov_base, iovec[0].iov_len, off); } diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index 8c78108cc..d13be02e2 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -43,7 +43,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { if (fd == -1 || offset < 0) return einval(); size = MIN(size, 0x7ffff000); if (!IsWindows()) { - rc = sys_pwrite(fd, buf, size, offset); + rc = sys_pwrite(fd, buf, size, offset, offset); } else if (__isfdkind(fd, kFdFile)) { rc = sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset); } else { diff --git a/libc/calls/pwritev.c b/libc/calls/pwritev.c index e3f1e9b72..9125cb075 100644 --- a/libc/calls/pwritev.c +++ b/libc/calls/pwritev.c @@ -16,12 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/safemacros.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/iovec.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/macros.h" #include "libc/sysv/consts/iov.h" #include "libc/sysv/errfuns.h" @@ -45,9 +45,8 @@ ssize_t pwritev(int fd, const struct iovec *iovec, int count, int64_t off) { static bool once, demodernize; int olderr; ssize_t rc; - if (!count) return 0; - if ((count = min(count, IOV_MAX)) < 0) return einval(); + if ((count = MIN(count, IOV_MAX)) < 0) return einval(); /* * NT, XNU, and 2007-era Linux don't support this system call. @@ -63,7 +62,7 @@ ssize_t pwritev(int fd, const struct iovec *iovec, int count, int64_t off) { demodernize = true; } else { olderr = errno; - rc = sys_pwritev(fd, iovec, count, off); + rc = sys_pwritev(fd, iovec, count, off, off); if (rc == -1 && errno == ENOSYS) { errno = olderr; demodernize = true; @@ -77,7 +76,7 @@ ssize_t pwritev(int fd, const struct iovec *iovec, int count, int64_t off) { } if (!demodernize) { - return sys_pwritev(fd, iovec, count, off); + return sys_pwritev(fd, iovec, count, off, off); } else { return pwrite(fd, iovec[0].iov_base, iovec[0].iov_len, off); } diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index e9b92f138..e1c86084e 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -24,21 +24,37 @@ #include "libc/nt/errors.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/overlapped.h" -#include "libc/nt/struct/teb.h" #include "libc/sysv/errfuns.h" textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov, - size_t iovlen, ssize_t opt_offset) { - uint32_t got; + size_t iovlen, ssize_t opt_offset) { + size_t i, total; + uint32_t got, size; struct NtOverlapped overlap; while (iovlen && !iov[0].iov_len) iov++, iovlen--; - if (ReadFile(fd->handle, iovlen ? iov[0].iov_base : NULL, - iovlen ? clampio(iov[0].iov_len) : 0, &got, - offset2overlap(opt_offset, &overlap))) { - return got; - } else if (NtGetErr() == kNtErrorBrokenPipe) { - return 0; /* read() doesn't EPIPE lool */ + if (iovlen) { + for (total = i = 0; i < iovlen; ++i) { + size = clampio(iov[i].iov_len); + if (ReadFile(fd->handle, iov[i].iov_base, size, &got, + offset2overlap(opt_offset, &overlap))) { + total += got; + if (opt_offset != -1) opt_offset += got; + if (got < iov[i].iov_len) break; + } else if (GetLastError() == kNtErrorBrokenPipe) { + break; /* read() doesn't EPIPE lool */ + } else { + return __winerr(); + } + } + return total; } else { - return __winerr(); + if (ReadFile(fd->handle, NULL, 0, &got, + offset2overlap(opt_offset, &overlap))) { + return got; + } else if (GetLastError() == kNtErrorBrokenPipe) { + return 0; + } else { + return __winerr(); + } } } diff --git a/libc/calls/renameat.c b/libc/calls/renameat.c index ad4ff00a4..16ce76709 100644 --- a/libc/calls/renameat.c +++ b/libc/calls/renameat.c @@ -32,7 +32,6 @@ */ int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { - if (!oldpath || !newpath) return efault(); if (!IsWindows()) { return sys_renameat(olddirfd, oldpath, newdirfd, newpath); } else { diff --git a/libc/calls/sigprocmask.c b/libc/calls/sigprocmask.c index 94cb7c188..7df83de75 100644 --- a/libc/calls/sigprocmask.c +++ b/libc/calls/sigprocmask.c @@ -20,6 +20,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/sigset.h" #include "libc/dce.h" +#include "libc/str/str.h" #include "libc/sysv/errfuns.h" /** @@ -37,8 +38,18 @@ * @vforksafe */ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) { - if (!IsWindows()) { + int32_t x; + if (!IsWindows() && !IsOpenbsd()) { return sys_sigprocmask(how, opt_set, opt_out_oldset, 8); + } else if (IsOpenbsd()) { + if (!opt_set) how = 1; + if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set); + if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) { + if (opt_out_oldset) memcpy(opt_out_oldset, &x, sizeof(x)); + return 0; + } else { + return -1; + } } else { return 0; /* TODO(jart): Implement me! */ } diff --git a/libc/calls/sigsuspend.c b/libc/calls/sigsuspend.c index 6f91a49d3..60dae7287 100644 --- a/libc/calls/sigsuspend.c +++ b/libc/calls/sigsuspend.c @@ -30,8 +30,9 @@ * @asyncsignalsafe */ int sigsuspend(const sigset_t *ignore) { - if (!ignore) return efault(); + unsigned x; if (!IsWindows()) { + if (IsOpenbsd()) ignore = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore); return sys_sigsuspend(ignore, 8); } else { return enosys(); /* TODO(jart): Implement me! */ diff --git a/libc/calls/stat2linux.c b/libc/calls/stat2linux.c index 0f9306b3e..9970d8535 100644 --- a/libc/calls/stat2linux.c +++ b/libc/calls/stat2linux.c @@ -82,13 +82,13 @@ static textstartup void __stat2linux_netbsd(union metastat *ms) { */ textstartup void __stat2linux(void *ms) { if (ms) { - if (SupportsXnu() && IsXnu()) { + if (IsXnu()) { __stat2linux_xnu((union metastat *)ms); - } else if (SupportsFreebsd() && IsFreebsd()) { + } else if (IsFreebsd()) { __stat2linux_freebsd((union metastat *)ms); - } else if (SupportsOpenbsd() && IsOpenbsd()) { + } else if (IsOpenbsd()) { __stat2linux_openbsd((union metastat *)ms); - } else if (SupportsNetbsd() && IsNetbsd()) { + } else if (IsNetbsd()) { __stat2linux_netbsd((union metastat *)ms); } } diff --git a/libc/calls/struct/metatermios.internal.h b/libc/calls/struct/metatermios.internal.h index 02b31cd0e..fa2653281 100644 --- a/libc/calls/struct/metatermios.internal.h +++ b/libc/calls/struct/metatermios.internal.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ -#ifndef __STRICT_ANSI__ #include "libc/calls/struct/termios.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -33,5 +32,4 @@ union metatermios { COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* !ANSI */ #endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_METATERMIOS_H_ */ diff --git a/libc/calls/sync.c b/libc/calls/sync.c index c6f80f994..231ae339f 100644 --- a/libc/calls/sync.c +++ b/libc/calls/sync.c @@ -21,7 +21,7 @@ #include "libc/dce.h" /** - * Flushes file system changes to disk to the greatest extent possible. + * Flushes file system changes to disk by any means necessary. */ void sync(void) { if (!IsWindows()) { diff --git a/libc/calls/termios.internal.h b/libc/calls/termios.internal.h index c8e044d02..c76a3467c 100644 --- a/libc/calls/termios.internal.h +++ b/libc/calls/termios.internal.h @@ -21,8 +21,8 @@ COSMOPOLITAN_C_START_ (TO)->c_ospeed = (FROM)->c_ospeed; \ } while (0) -void *termios2host(union metatermios *, const struct termios *); -void termios2linux(struct termios *, const union metatermios *); +void *__termios2host(union metatermios *, const struct termios *) hidden; +void __termios2linux(struct termios *, const union metatermios *) hidden; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/calls/termios2host.c b/libc/calls/termios2host.c index 121410364..a08507757 100644 --- a/libc/calls/termios2host.c +++ b/libc/calls/termios2host.c @@ -22,14 +22,14 @@ #include "libc/calls/termios.internal.h" #include "libc/dce.h" -void *termios2host(union metatermios *t, const struct termios *lt) { - if (IsXnu()) { +void *__termios2host(union metatermios *t, const struct termios *lt) { + if (!IsXnu() && !IsFreebsd() && !IsOpenbsd() && !IsNetbsd()) { + return lt; + } else if (IsXnu()) { COPY_TERMIOS(&t->xnu, lt); return &t->xnu; - } else if (IsFreebsd() || IsOpenbsd()) { + } else { COPY_TERMIOS(&t->bsd, lt); return &t->bsd; - } else { - return lt; } } diff --git a/libc/calls/termios2linux.c b/libc/calls/termios2linux.c index e5fee21c2..ab775d69c 100644 --- a/libc/calls/termios2linux.c +++ b/libc/calls/termios2linux.c @@ -22,10 +22,10 @@ #include "libc/calls/termios.internal.h" #include "libc/dce.h" -void termios2linux(struct termios *lt, const union metatermios *t) { +void __termios2linux(struct termios *lt, const union metatermios *t) { if (IsXnu()) { COPY_TERMIOS(lt, &t->xnu); - } else if (IsFreebsd() || IsOpenbsd()) { + } else if (IsFreebsd() || IsOpenbsd() || IsNetbsd()) { COPY_TERMIOS(lt, &t->bsd); } else { memcpy(lt, &t->linux, sizeof(*lt)); diff --git a/libc/calls/thunks/ftruncate-sysv.S b/libc/calls/thunks/ftruncate-sysv.S deleted file mode 100644 index dc1875c62..000000000 --- a/libc/calls/thunks/ftruncate-sysv.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ - -/ Directly calls ftruncate() impl on host o/s if available. -sys_ftruncate: - mov %rsi,%rdx # netbsd+openbsd:pad - jmp __sys_ftruncate - .endfn sys_ftruncate,globl,hidden diff --git a/libc/calls/thunks/onntconsoleevent.S b/libc/calls/thunks/onntconsoleevent.S deleted file mode 100644 index 264158940..000000000 --- a/libc/calls/thunks/onntconsoleevent.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.text.windows -.source __FILE__ - -__onntconsoleevent_nt: - ezlea __onntconsoleevent,ax - jmp __nt2sysv - .endfn __onntconsoleevent_nt,globl,hidden diff --git a/libc/calls/thunks/preadv-sysv.S b/libc/calls/thunks/preadv-sysv.S deleted file mode 100644 index 6ee8ecc5a..000000000 --- a/libc/calls/thunks/preadv-sysv.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ - -/ Directly calls preadv() impl on host o/s if available. -sys_preadv: - mov %rcx,%r8 # netbsd+openbsd:pad - jmp __sys_preadv - .endfn sys_preadv,globl,hidden diff --git a/libc/calls/thunks/pwrite-sysv.S b/libc/calls/thunks/pwrite-sysv.S deleted file mode 100644 index b13ecebf3..000000000 --- a/libc/calls/thunks/pwrite-sysv.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ - -/ Directly calls pwrite() impl on host o/s if available. -sys_pwrite: - mov %rcx,%r8 # netbsd+openbsd:pad - jmp __sys_pwrite - .endfn sys_pwrite,globl,hidden diff --git a/libc/calls/thunks/pwritev-sysv.S b/libc/calls/thunks/pwritev-sysv.S deleted file mode 100644 index 0a34eaf41..000000000 --- a/libc/calls/thunks/pwritev-sysv.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ - -/ Directly calls pwritev() impl on host o/s if available. -sys_pwritev: - mov %rcx,%r8 # netbsd+openbsd:pad - jmp __sys_pwritev - .endfn sys_pwritev,globl,hidden diff --git a/libc/calls/thunks/sigprocmask-sysv.S b/libc/calls/thunks/sigprocmask-sysv.S deleted file mode 100644 index a2c54ab70..000000000 --- a/libc/calls/thunks/sigprocmask-sysv.S +++ /dev/null @@ -1,46 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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/dce.h" -#include "libc/macros.h" - -/ Sets System Five process signal mask w/ standard ABI. -sys_sigprocmask: - push %rbp - mov %rsp,%rbp -#if SupportsOpenbsd() - testb IsOpenbsd() - jz 4f - test %rsi,%rsi - jnz 1f - mov $1,%edi # SIG_BLOCK on BSDs - jmp 2f -1: mov (%rsi),%esi # openbsd:byvalue -2: call __sys_sigprocmask - cmp $-1,%eax - je 5f - test %rdx,%rdx # original param not a result - jz 3f - mov %eax,(%rdx) # openbsd:byvalue -3: xor %eax,%eax - jmp 5f -#endif -4: call __sys_sigprocmask -5: pop %rbp - ret - .endfn sys_sigprocmask,globl diff --git a/libc/calls/thunks/truncate-sysv.S b/libc/calls/thunks/truncate-sysv.S deleted file mode 100644 index bc6453ad9..000000000 --- a/libc/calls/thunks/truncate-sysv.S +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -.source __FILE__ - -/ Directly calls truncate() impl on host o/s if available. -sys_truncate: - mov %rsi,%rdx # netbsd+openbsd:pad - jmp __sys_truncate - .endfn sys_truncate,globl,hidden diff --git a/libc/calls/truncate.c b/libc/calls/truncate.c index bc4f8c295..a8c3f75f1 100644 --- a/libc/calls/truncate.c +++ b/libc/calls/truncate.c @@ -32,9 +32,8 @@ * @error ENOENT */ int truncate(const char *path, uint64_t length) { - if (!path) return efault(); if (!IsWindows()) { - return sys_truncate(path, length); + return sys_truncate(path, length, length); } else { return sys_truncate_nt(path, length); } diff --git a/libc/runtime/unsetenv.c b/libc/calls/unsetenv.c similarity index 80% rename from libc/runtime/unsetenv.c rename to libc/calls/unsetenv.c index a69d81098..b38abc406 100644 --- a/libc/runtime/unsetenv.c +++ b/libc/calls/unsetenv.c @@ -16,27 +16,32 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/safemacros.h" #include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/errfuns.h" /** * Removes environment variable. */ -int unsetenv(const char *name) { - if (isempty(name) || strchr(name, '=')) return einval(); - if (environ) { - char **ep = environ; - size_t removed = 0; - size_t namelen = strlen(name); - do { - if (*ep && strncmp(*ep, name, namelen) == 0 && (*ep)[namelen] == '=') { - --removed; - } else if (removed) { - ep[removed] = *ep; +int unsetenv(const char *s) { + char **p; + size_t i, j, k; + if (s && (p = environ)) { + for (i = 0; p[i]; ++i) { + for (j = 0;; ++j) { + if (!s[j]) { + if (p[i][j] == '=') { + k = i + 1; + do { + p[k - 1] = p[k]; + } while (p[k++]); + return 0; + } + break; + } + if (s[j] != p[i][j]) { + break; + } } - } while (*ep++); + } } return 0; } diff --git a/libc/calls/thunks/winalarm.S b/libc/calls/winalarm.S similarity index 100% rename from libc/calls/thunks/winalarm.S rename to libc/calls/winalarm.S diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index c508a5725..3a3655aed 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -25,7 +25,7 @@ #include "libc/nt/struct/overlapped.h" #include "libc/sysv/errfuns.h" -static size_t SumIovecLen(const struct iovec *v, size_t n) { +static textwindows size_t SumIovecLen(const struct iovec *v, size_t n) { size_t i, sum; for (sum = i = 0; i < n; ++i) { sum += v[i].iov_len; @@ -34,16 +34,32 @@ static size_t SumIovecLen(const struct iovec *v, size_t n) { } textwindows ssize_t sys_write_nt(struct Fd *fd, const struct iovec *iov, - size_t iovlen, ssize_t opt_offset) { - uint32_t wrote; + size_t iovlen, ssize_t opt_offset) { + size_t i, total; + uint32_t size, wrote; struct NtOverlapped overlap; while (iovlen && !iov[0].iov_len) iov++, iovlen--; - if (WriteFile(fd->handle, iovlen ? iov[0].iov_base : NULL, - iovlen ? clampio(iov[0].iov_len) : 0, &wrote, - offset2overlap(opt_offset, &overlap))) { - if (!wrote) assert(!SumIovecLen(iov, iovlen)); - return wrote; + if (iovlen) { + for (total = i = 0; i < iovlen; ++i) { + if (!iov[i].iov_len) continue; + size = clampio(iov[0].iov_len); + if (WriteFile(fd->handle, iov[i].iov_base, size, &wrote, + offset2overlap(opt_offset, &overlap))) { + total += wrote; + if (opt_offset != -1) opt_offset += wrote; + if (wrote < iov[i].iov_len) break; + } else { + return __winerr(); + } + } + if (!total) assert(!SumIovecLen(iov, iovlen)); + return total; } else { - return __winerr(); + if (WriteFile(fd->handle, NULL, 0, &wrote, + offset2overlap(opt_offset, &overlap))) { + return 0; + } else { + return __winerr(); + } } } diff --git a/libc/dce.h b/libc/dce.h index b58bbec89..831a94bb1 100644 --- a/libc/dce.h +++ b/libc/dce.h @@ -51,12 +51,6 @@ #define UseSecurityBlankets() 0 #endif -#ifdef __MGENERAL_REGS_ONLY__ -#define UseGeneralRegsOnly() 1 -#else -#define UseGeneralRegsOnly() 0 -#endif - #ifdef TINY #define IsTiny() 1 #else @@ -87,15 +81,14 @@ ((SUPPORT_VECTOR & (LINUX | METAL | XNU | OPENBSD | FREEBSD | NETBSD)) != 0) #ifndef __ASSEMBLER__ -#define __HOSTOS (__hostos & SUPPORT_VECTOR) -#define IsLinux() ((__HOSTOS & LINUX) == LINUX) -#define IsMetal() ((__HOSTOS & METAL) == METAL) -#define IsWindows() ((__HOSTOS & WINDOWS) == WINDOWS) -#define IsBsd() ((__HOSTOS & (XNU | FREEBSD | OPENBSD | NETBSD)) != 0) -#define IsXnu() ((__HOSTOS & XNU) == XNU) -#define IsFreebsd() ((__HOSTOS & FREEBSD) == FREEBSD) -#define IsOpenbsd() ((__HOSTOS & OPENBSD) == OPENBSD) -#define IsNetbsd() ((__HOSTOS & NETBSD) == NETBSD) +#define IsLinux() (SupportsLinux() && (__hostos & LINUX)) +#define IsMetal() (SupportsMetal() && (__hostos & METAL)) +#define IsWindows() (SupportsWindows() && (__hostos & WINDOWS)) +#define IsXnu() (SupportsXnu() && (__hostos & XNU)) +#define IsFreebsd() (SupportsFreebsd() && (__hostos & FREEBSD)) +#define IsOpenbsd() (SupportsOpenbsd() && (__hostos & OPENBSD)) +#define IsNetbsd() (SupportsNetbsd() && (__hostos & NETBSD)) +#define IsBsd() (IsXnu() || IsFreebsd() || IsOpenbsd() || IsNetbsd()) #else /* clang-format off */ #define IsLinux() $LINUX,__hostos(%rip) diff --git a/libc/fmt/dirname.c b/libc/fmt/dirname.c index 0490c2faf..4101daec8 100644 --- a/libc/fmt/dirname.c +++ b/libc/fmt/dirname.c @@ -19,7 +19,8 @@ #include "libc/fmt/conv.h" #include "libc/str/str.h" -#define ISDELIM(c) (c == '/' || c == '\\' || c == '.') +#define ISSLASH(c) (c == '/' || c == '\\') +#define ISDELIM(c) (ISSLASH(c) || c == '.') /** * Returns directory portion of path. @@ -30,7 +31,7 @@ char *dirname(char *s) { if (!(n = strlen(s))) return s; while (n && ISDELIM(s[n - 1])) --n; if (n) { - while (n && !ISDELIM(s[n - 1])) --n; + while (n && !ISSLASH(s[n - 1])) --n; if (n) { while (n && ISDELIM(s[n - 1])) --n; if (!n) ++n; diff --git a/libc/fmt/palandftoa.c b/libc/fmt/palandftoa.c index 7d109f98d..fa3bbff91 100644 --- a/libc/fmt/palandftoa.c +++ b/libc/fmt/palandftoa.c @@ -31,7 +31,7 @@ │ be thread safe). │ └─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/paland.inc" -#include "libc/fmt/palandprintf.internal.h" +#include "libc/fmt/palandprintf.h" #include "libc/math.h" /** diff --git a/libc/fmt/palandntoa.c b/libc/fmt/palandntoa.c index ee4c8fee0..3404d7f5c 100644 --- a/libc/fmt/palandntoa.c +++ b/libc/fmt/palandntoa.c @@ -27,7 +27,7 @@ #include "libc/assert.h" #include "libc/fmt/conv.h" #include "libc/fmt/paland.inc" -#include "libc/fmt/palandprintf.internal.h" +#include "libc/fmt/palandprintf.h" uintmax_t __udivmodti4(uintmax_t, uintmax_t, uintmax_t *); diff --git a/libc/fmt/palandprintf.c b/libc/fmt/palandprintf.c index 5531641f0..2a5383a0d 100644 --- a/libc/fmt/palandprintf.c +++ b/libc/fmt/palandprintf.c @@ -41,7 +41,7 @@ #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" #include "libc/fmt/paland.inc" -#include "libc/fmt/palandprintf.internal.h" +#include "libc/fmt/palandprintf.h" #include "libc/mem/mem.h" #include "libc/runtime/internal.h" #include "libc/str/str.h" diff --git a/libc/fmt/palandprintf.internal.h b/libc/fmt/palandprintf.h similarity index 100% rename from libc/fmt/palandprintf.internal.h rename to libc/fmt/palandprintf.h diff --git a/libc/fmt/pflink.h b/libc/fmt/pflink.h index 434289042..24bf35216 100644 --- a/libc/fmt/pflink.h +++ b/libc/fmt/pflink.h @@ -1,6 +1,10 @@ #ifndef COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #define COSMOPOLITAN_LIBC_FMT_PFLINK_H_ #include "libc/dce.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/unicode/unicode.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) #ifndef __STRICT_ANSI__ @@ -79,11 +83,6 @@ __asm__(".section .yoink\n\t" "nopl\t__grow(%rip)\n\t" ".previous"); #else -#include "libc/fmt/palandprintf.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/unicode/unicode.h" static long __pflink(long x) { x |= kCp437[0]; x |= ntoa(0, 0, 0, 0, 0, 0, 0, 0, 0); diff --git a/libc/fmt/spacepad.c b/libc/fmt/spacepad.c index 7cab0bdf0..61c5dcb85 100644 --- a/libc/fmt/spacepad.c +++ b/libc/fmt/spacepad.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/palandprintf.internal.h" +#include "libc/fmt/palandprintf.h" int spacepad(int out(long, void *), void *arg, unsigned long n) { int i, rc; diff --git a/libc/fmt/stoa.c b/libc/fmt/stoa.c index 423cd447d..cdbc3b59c 100644 --- a/libc/fmt/stoa.c +++ b/libc/fmt/stoa.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" #include "libc/fmt/paland.inc" -#include "libc/fmt/palandprintf.internal.h" +#include "libc/fmt/palandprintf.h" #include "libc/nexgen32e/tinystrlen.internal.h" #include "libc/str/str.h" #include "libc/str/thompike.h" diff --git a/libc/mem/putenv.c b/libc/mem/putenv.c index 8f6d5a2a3..53e7a9612 100644 --- a/libc/mem/putenv.c +++ b/libc/mem/putenv.c @@ -32,7 +32,7 @@ int PutEnvImpl(char *s, bool overwrite) { if (!p) goto fail; namelen = p + 1 - s; for (i = 0; environ[i]; ++i) { - if (strncmp(environ[i], s, namelen) == 0) { + if (!strncmp(environ[i], s, namelen)) { if (!overwrite) { free(s); return 0; diff --git a/libc/runtime/directmap.c b/libc/runtime/directmap.c index 53be7795c..bc521e05a 100644 --- a/libc/runtime/directmap.c +++ b/libc/runtime/directmap.c @@ -31,7 +31,7 @@ noasan struct DirectMap __mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { if (!IsWindows()) { - return (struct DirectMap){sys_mmap(addr, size, prot, flags, fd, off), + return (struct DirectMap){sys_mmap(addr, size, prot, flags, fd, off, off), kNtInvalidHandleValue}; } else { return sys_mmap_nt(addr, size, prot, flags, diff --git a/libc/runtime/fork.c b/libc/runtime/fork.c index 3199c8469..8f274f015 100644 --- a/libc/runtime/fork.c +++ b/libc/runtime/fork.c @@ -28,14 +28,22 @@ * @asyncsignalsafe */ int fork(void) { - int rc; + axdx_t ad; + int ax, dx; if (!IsWindows()) { - rc = sys_fork(); + 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; + } } else { - rc = sys_fork_nt(); + ax = sys_fork_nt(); } - if (rc == 0) { + if (!ax) { __onfork(); } - return rc; + return ax; } diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk index fa208100e..4b04a50a3 100644 --- a/libc/runtime/runtime.mk +++ b/libc/runtime/runtime.mk @@ -76,6 +76,10 @@ o/$(MODE)/libc/runtime/winmain.greg.o: \ OVERRIDE_CFLAGS += \ $(NO_MAGIC) +o/$(MODE)/libc/runtime/ftrace.greg.o: \ + OVERRIDE_CFLAGS += \ + -mgeneral-regs-only + LIBC_RUNTIME_LIBS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x))) LIBC_RUNTIME_SRCS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_SRCS)) LIBC_RUNTIME_HDRS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/sock/sendfile.c b/libc/sock/sendfile.c index 8bdb3ab3a..fde33bad3 100644 --- a/libc/sock/sendfile.c +++ b/libc/sock/sendfile.c @@ -59,7 +59,7 @@ static ssize_t sendfile_linux2netflix(int outfd, int infd, int64_t offset, sbytes; if (inout_opt_inoffset) { offset = *inout_opt_inoffset; - } else if ((offset = sys_lseek(infd, 0, SEEK_CUR)) == -1) { + } else if ((offset = lseek(infd, 0, SEEK_CUR)) == -1) { return -1; } if ((rc = sys_sendfile_netflix(infd, outfd, offset, uptobytes, NULL, &sbytes, diff --git a/libc/str/memmem.c b/libc/str/memmem.c index c20622e4c..fd307ab21 100644 --- a/libc/str/memmem.c +++ b/libc/str/memmem.c @@ -16,42 +16,8 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.h" -#include "libc/mem/alloca.h" #include "libc/str/str.h" -static void KnuthMorrisPrattInit(ssize_t m, ssize_t *T, const char *W) { - ssize_t i = 2; - ssize_t j = 0; - T[0] = -1; - T[1] = 0; - while (i < m) { - if (W[i - 1] == W[j]) { - T[i++] = j++ + 1; - } else if (j > 0) { - j = T[j]; - } else { - T[i++] = 0; - } - } - T[m] = 0; -} - -static size_t KnuthMorrisPratt(long m, const long *T, const char *W, long n, - const char *S) { - long i = 0, j = 0; - while (i + j < n) { - if (W[i] == S[i + j]) { - i++; - if (i == m) break; - } else { - j = j + i - T[i]; - if (i > 0) i = T[i]; - } - } - return j; -} - /** * Searches for fixed-length substring in memory region. * @@ -61,24 +27,16 @@ static size_t KnuthMorrisPratt(long m, const long *T, const char *W, long n, * @param needlelen is its character count * @return pointer to first result or NULL if not found */ -void *memmem(const void *haystackp, size_t haystacklen, const void *needlep, +void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { - long *T; - size_t i; - const char *haystack, *needle, *h; - needle = needlep; - haystack = haystackp; - if (needlelen > haystacklen) return NULL; + size_t i, j; if (!needlelen) return haystack; - h = memchr(haystack, *needle, haystacklen); - if (!h || needlelen == 1) return h; - haystacklen -= h - haystack; - if (needlelen < haystacklen && memcmp(h, needle, needlelen) == 0) { - return h; - } else { - T = alloca((needlelen + 1) * sizeof(long)); - KnuthMorrisPrattInit(needlelen, T, needle); - i = KnuthMorrisPratt(needlelen, T, needle, haystacklen, h); - return i < haystacklen ? h + i : NULL; + for (i = 0; i < haystacklen; ++i) { + for (j = 0;; ++j) { + if (j == needlelen) return (/*unconst*/ char *)haystack + i; + if (i + j == haystacklen) break; + if (((char *)needle)[j] != ((char *)haystack)[i + j]) break; + } } + return NULL; } diff --git a/libc/str/strstr.c b/libc/str/strstr.c index cef3d9374..70129c56a 100644 --- a/libc/str/strstr.c +++ b/libc/str/strstr.c @@ -28,5 +28,15 @@ * @see memmem() */ char *strstr(const char *haystack, const char *needle) { - return memmem(haystack, strlen(haystack), needle, strlen(needle)); + size_t i; + for (;;) { + for (i = 0;;) { + if (!needle[i]) return (/*unconst*/ char *)haystack; + if (!haystack[i]) break; + if (needle[i] != haystack[i]) break; + ++i; + } + if (!*haystack++) break; + } + return NULL; } diff --git a/libc/sysv/calls/__sys_fork.s b/libc/sysv/calls/__sys_fork.s deleted file mode 100644 index e9519041f..000000000 --- a/libc/sysv/calls/__sys_fork.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_fork 0x0020020022002039 globl hidden diff --git a/libc/sysv/calls/__sys_ftruncate.s b/libc/sysv/calls/__sys_ftruncate.s deleted file mode 100644 index 97c57b914..000000000 --- a/libc/sysv/calls/__sys_ftruncate.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_ftruncate 0x0c90c91e020c904d globl hidden diff --git a/libc/sysv/calls/__sys_gettimeofday.s b/libc/sysv/calls/__sys_gettimeofday.s deleted file mode 100644 index e8dac45c1..000000000 --- a/libc/sysv/calls/__sys_gettimeofday.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_gettimeofday 0x1a20430742074060 globl hidden diff --git a/libc/sysv/calls/__sys_lseek.s b/libc/sysv/calls/__sys_lseek.s deleted file mode 100644 index e7798e7a1..000000000 --- a/libc/sysv/calls/__sys_lseek.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_lseek 0x0c70c71de20c7008 globl hidden diff --git a/libc/sysv/calls/__sys_mmap.s b/libc/sysv/calls/__sys_mmap.s deleted file mode 100644 index c331e2e0b..000000000 --- a/libc/sysv/calls/__sys_mmap.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_mmap 0x0c50c51dd20c5009 globl hidden diff --git a/libc/sysv/calls/__sys_pread.s b/libc/sysv/calls/__sys_pread.s deleted file mode 100644 index 3b5b5d277..000000000 --- a/libc/sysv/calls/__sys_pread.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_pread 0x0ad0ad1db2099011 globl hidden diff --git a/libc/sysv/calls/__sys_preadv.s b/libc/sysv/calls/__sys_preadv.s deleted file mode 100644 index caeef7a1f..000000000 --- a/libc/sysv/calls/__sys_preadv.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_preadv 0x12110b121ffff127 globl hidden diff --git a/libc/sysv/calls/__sys_pwrite.s b/libc/sysv/calls/__sys_pwrite.s deleted file mode 100644 index 20ce64e75..000000000 --- a/libc/sysv/calls/__sys_pwrite.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_pwrite 0x0ae0ae1dc209a012 globl hidden diff --git a/libc/sysv/calls/__sys_pwritev.s b/libc/sysv/calls/__sys_pwritev.s deleted file mode 100644 index dd1d551f5..000000000 --- a/libc/sysv/calls/__sys_pwritev.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_pwritev 0x12210c122ffff128 globl hidden diff --git a/libc/sysv/calls/__sys_sigprocmask.s b/libc/sysv/calls/__sys_sigprocmask.s deleted file mode 100644 index ac952a20b..000000000 --- a/libc/sysv/calls/__sys_sigprocmask.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_sigprocmask 0x125030154203000e globl hidden diff --git a/libc/sysv/calls/__sys_sigsuspend.s b/libc/sysv/calls/__sys_sigsuspend.s deleted file mode 100644 index 8ff36b816..000000000 --- a/libc/sysv/calls/__sys_sigsuspend.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_sigsuspend 0x12606f155206f082 globl hidden diff --git a/libc/sysv/calls/__sys_truncate.s b/libc/sysv/calls/__sys_truncate.s deleted file mode 100644 index 56699c92a..000000000 --- a/libc/sysv/calls/__sys_truncate.s +++ /dev/null @@ -1,2 +0,0 @@ -.include "o/libc/sysv/macros.internal.inc" -.scall __sys_truncate 0x0c80c81df20c804c globl hidden diff --git a/libc/sysv/calls/sys_fork.s b/libc/sysv/calls/sys_fork.s new file mode 100644 index 000000000..009440fc7 --- /dev/null +++ b/libc/sysv/calls/sys_fork.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_fork 0x0020020022002039 globl hidden diff --git a/libc/sysv/calls/sys_ftruncate.s b/libc/sysv/calls/sys_ftruncate.s new file mode 100644 index 000000000..952b434c9 --- /dev/null +++ b/libc/sysv/calls/sys_ftruncate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_ftruncate 0x0c90c91e020c904d globl hidden diff --git a/libc/sysv/calls/sys_gettimeofday.s b/libc/sysv/calls/sys_gettimeofday.s new file mode 100644 index 000000000..d52cbf2fd --- /dev/null +++ b/libc/sysv/calls/sys_gettimeofday.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_gettimeofday 0x1a20430742074060 globl hidden diff --git a/libc/sysv/calls/sys_lseek.s b/libc/sysv/calls/sys_lseek.s new file mode 100644 index 000000000..bcaba4800 --- /dev/null +++ b/libc/sysv/calls/sys_lseek.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_lseek 0x0c70c71de20c7008 globl hidden diff --git a/libc/sysv/calls/sys_mmap.s b/libc/sysv/calls/sys_mmap.s new file mode 100644 index 000000000..c0eea39ac --- /dev/null +++ b/libc/sysv/calls/sys_mmap.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_mmap 0x0c50c51dd20c5009 globl hidden diff --git a/libc/sysv/calls/sys_pread.s b/libc/sysv/calls/sys_pread.s new file mode 100644 index 000000000..597ff1351 --- /dev/null +++ b/libc/sysv/calls/sys_pread.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_pread 0x0ad0ad1db2099011 globl hidden diff --git a/libc/sysv/calls/sys_preadv.s b/libc/sysv/calls/sys_preadv.s new file mode 100644 index 000000000..3a5d2aedd --- /dev/null +++ b/libc/sysv/calls/sys_preadv.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_preadv 0x12110b121ffff127 globl hidden diff --git a/libc/sysv/calls/sys_pwrite.s b/libc/sysv/calls/sys_pwrite.s new file mode 100644 index 000000000..f0dacf330 --- /dev/null +++ b/libc/sysv/calls/sys_pwrite.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_pwrite 0x0ae0ae1dc209a012 globl hidden diff --git a/libc/sysv/calls/sys_pwritev.s b/libc/sysv/calls/sys_pwritev.s new file mode 100644 index 000000000..4092be6ef --- /dev/null +++ b/libc/sysv/calls/sys_pwritev.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_pwritev 0x12210c122ffff128 globl hidden diff --git a/libc/sysv/calls/sys_sigprocmask.s b/libc/sysv/calls/sys_sigprocmask.s new file mode 100644 index 000000000..4603afba1 --- /dev/null +++ b/libc/sysv/calls/sys_sigprocmask.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_sigprocmask 0x125030154203000e globl hidden diff --git a/libc/sysv/calls/sys_sigsuspend.s b/libc/sysv/calls/sys_sigsuspend.s new file mode 100644 index 000000000..a0750958f --- /dev/null +++ b/libc/sysv/calls/sys_sigsuspend.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_sigsuspend 0x12606f155206f082 globl hidden diff --git a/libc/sysv/calls/sys_truncate.s b/libc/sysv/calls/sys_truncate.s new file mode 100644 index 000000000..2822db5bc --- /dev/null +++ b/libc/sysv/calls/sys_truncate.s @@ -0,0 +1,2 @@ +.include "o/libc/sysv/macros.internal.inc" +.scall sys_truncate 0x0c80c81df20c804c globl hidden diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index b0421c40e..ef04ee575 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -43,16 +43,16 @@ scall __sys_fstat 0x1b80352272153005 globl hidden # needs __stat2linux() scall __sys_lstat 0x1b90280282154006 globl hidden # needs __stat2linux(); blocked on Android scall sys_poll 0x0d10fc0d120e6007 globl hidden scall sys_ppoll 0xfff06d221ffff10f globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c -scall __sys_lseek 0x0c70c71de20c7008 globl hidden # netbsd+openbsd:evilpad -scall __sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad +scall sys_lseek 0x0c70c71de20c7008 globl hidden # netbsd+openbsd:evilpad +scall sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad scall sys_msync 0x115100041204101a globl hidden scall sys_mprotect 0x04a04a04a204a00a globl hidden scall sys_munmap 0x049049049204900b globl hidden scall sys_sigaction 0x15402e1a0202e00d globl hidden # rt_sigaction on Lunix; it's complicated on NetBSD -scall __sys_sigprocmask 0x125030154203000e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue +scall sys_sigprocmask 0x125030154203000e globl hidden # a.k.a. rt_sigprocmask, openbsd:byvalue scall sys_ioctl 0x0360360362036010 globl hidden -scall __sys_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; netbsd+openbsd:pad -scall __sys_pwrite 0x0ae0ae1dc209a012 globl hidden # a.k.a. pwrite64; netbsd+openbsd:pad +scall sys_pread 0x0ad0ad1db2099011 globl hidden # a.k.a. pread64; netbsd+openbsd:pad +scall sys_pwrite 0x0ae0ae1dc209a012 globl hidden # a.k.a. pwrite64; netbsd+openbsd:pad scall sys_readv 0x0780780782078013 globl hidden scall sys_writev 0x0790790792079014 globl hidden scall sys_access 0x0210210212021015 globl hidden @@ -91,7 +91,7 @@ scall __sys_getpeername 0x01f01f08d201f034 globl hidden scall sys_socketpair 0x0870870872087035 globl hidden scall sys_setsockopt 0x0690690692069036 globl hidden scall sys_getsockopt 0x0760760762076037 globl hidden -scall __sys_fork 0x0020020022002039 globl hidden # xnu needs eax=~-edx b/c eax always holds pid and edx is 0 for parent and 1 for child +scall sys_fork 0x0020020022002039 globl hidden # xnu needs eax&=~-edx bc eax always holds pid and edx is 0 for parent and 1 for child #scall vfork 0x042042042204203a globl # this syscall is from the moon so we implement it by hand in libc/calls/hefty/vfork.S scall sys_posix_spawn 0xfffffffff20f4fff globl hidden # good luck figuring out how xnu defines this scall __sys_execve 0x03b03b03b203b03b globl hidden @@ -116,8 +116,8 @@ scall sys_fcntl 0x05c05c05c205c048 globl hidden scall sys_flock 0x0830830832083049 globl hidden scall sys_fsync 0x05f05f05f205f04a globl hidden scall sys_fdatasync 0x0f105f22620bb04b globl hidden # fsync() on openbsd -scall __sys_truncate 0x0c80c81df20c804c globl hidden # netbsd+openbsd:pad -scall __sys_ftruncate 0x0c90c91e020c904d globl hidden # netbsd+openbsd:pad +scall sys_truncate 0x0c80c81df20c804c globl hidden # netbsd+openbsd:pad +scall sys_ftruncate 0x0c90c91e020c904d globl hidden # netbsd+openbsd:pad scall sys_getcwd 0x128130146ffff04f globl hidden scall sys_chdir 0x00c00c00c200c050 globl hidden scall sys_fchdir 0x00d00d00d200d051 globl hidden @@ -135,7 +135,7 @@ scall sys_chown 0x010010010201005c globl hidden # impl. w/ fchownat() @asyncsig scall sys_fchown 0x07b07b07b207b05d globl hidden # @asyncsignalsafe scall sys_lchown 0x1130fe0fe216c05e globl hidden # impl. w/ fchownat() scall umask 0x03c03c03c203c05f globl -scall __sys_gettimeofday 0x1a20430742074060 globl hidden # xnu esi/edx=0 +scall sys_gettimeofday 0x1a20430742074060 globl hidden # xnu esi/edx=0 scall sys_getrlimit 0x0c20c20c220c2061 globl hidden scall sys_getrusage 0x1bd0130752075062 globl hidden scall sys_sysinfo 0xfffffffffffff063 globl hidden @@ -163,7 +163,7 @@ scall sys_setresgid 0xfff11c138ffff077 globl hidden # polyfilled for xnu scall getresuid 0xfff119168ffff076 globl # semantics aren't well-defined scall getresgid 0xfff11b169ffff078 globl # semantics aren't well-defined scall sigpending 0x124034034203407f globl -scall __sys_sigsuspend 0x12606f155206f082 globl hidden # openbsd:byvalue +scall sys_sigsuspend 0x12606f155206f082 globl hidden # openbsd:byvalue scall sigaltstack 0x1191200352035083 globl scall sys_mknod 0x1c200e00e200e085 globl hidden scall mknodat 0x1cc14022fffff103 globl # FreeBSD 12+ @@ -302,8 +302,8 @@ scall sys_vmsplice 0xfffffffffffff116 globl hidden scall migrate_pages 0xfffffffffffff100 globl # numa numa yay scall move_pages 0xfffffffffffff117 globl # NOTE: We view Red Hat versions as "epochs" for all distros. #──────────────────────RHEL 5.0 LIMIT──────────────────────── # ←┬─ last distro with gplv2 licensed compiler c. 2007 -scall __sys_preadv 0x12110b121ffff127 globl hidden # ├─ last distro with system v shell script init -scall __sys_pwritev 0x12210c122ffff128 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits +scall sys_preadv 0x12110b121ffff127 globl hidden # ├─ last distro with system v shell script init +scall sys_pwritev 0x12210c122ffff128 globl hidden # ├─ rob landley unleashes busybox gpl lawsuits scall __sys_utimensat 0x1d3054223ffff118 globl hidden # ├─ python modules need this due to pep513 scall sys_fallocate 0xfffffffffffff11d globl hidden # ├─ end of life 2020-11-30 (extended) scall sys_posix_fallocate 0xffffff212fffffff globl hidden # └─ cosmopolitan supports rhel5+ diff --git a/libc/testlib/ezbench.h b/libc/testlib/ezbench.h index 0ec61010f..428b5b746 100644 --- a/libc/testlib/ezbench.h +++ b/libc/testlib/ezbench.h @@ -6,6 +6,8 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) #define EZBENCH(INIT, EXPR) EZBENCH2(#EXPR, INIT, EXPR) + +#ifndef __STRICT_ANSI__ #define EZBENCH2(NAME, INIT, EXPR) \ do { \ uint64_t Control, Speculative, MemoryStrict; \ @@ -22,6 +24,11 @@ __testlib_ezbenchreport(NAME, Speculative - Control, \ MemoryStrict - Control); \ } while (0) +#else +#define EZBENCH2(NAME, INIT, EXPR) \ + do { \ + } while (0) +#endif void __testlib_ezbenchreport(const char *, uint64_t, uint64_t); uint64_t __testlib_ezbenchcontrol(void); diff --git a/libc/testlib/formatint.c b/libc/testlib/formatint.c index ae9350e3a..8967de565 100644 --- a/libc/testlib/formatint.c +++ b/libc/testlib/formatint.c @@ -25,10 +25,10 @@ static size_t sbufi_; static char sbufs_[2][256]; -nodiscard testonly char *testlib_formatint(intmax_t x) { +nodiscard testonly char *testlib_formatint(intptr_t x) { char *str = sbufi_ < ARRAYLEN(sbufs_) ? sbufs_[sbufi_++] : malloc(256); char *p = str; - p += sprintf(p, "%jd\t(or %#jx", x, x); + p += sprintf(p, "%ld\t(or %#lx", x, x); if (0 <= x && x < 256) { p += sprintf(p, " or %#`c", (unsigned char)x); } diff --git a/libc/testlib/formatrange.c b/libc/testlib/formatrange.c index 852db058f..479bfa170 100644 --- a/libc/testlib/formatrange.c +++ b/libc/testlib/formatrange.c @@ -19,6 +19,6 @@ #include "libc/testlib/testlib.h" #include "libc/x/x.h" -nodiscard testonly char *testlib_formatrange(intmax_t beg, intmax_t end) { - return xasprintf("[%#jx,%#jx]", beg, end); +nodiscard testonly char *testlib_formatrange(intptr_t beg, intptr_t end) { + return xasprintf("[%#ld,%#ld]", beg, end); } diff --git a/libc/testlib/testlib.h b/libc/testlib/testlib.h index 6aa48e22f..48ef24e64 100644 --- a/libc/testlib/testlib.h +++ b/libc/testlib/testlib.h @@ -15,7 +15,9 @@ COSMOPOLITAN_C_START_ * Test cases are guaranteed by the linker to be run in order, sorted by * the (SUITE, NAME) tuple passed here. */ -#define TEST(SUITE, NAME) __TEST_PROTOTYPE(SUITE, NAME, __TEST_ARRAY, ) +#define TEST(SUITE, NAME) \ + STATIC_YOINK("__testcase_start"); \ + __TEST_PROTOTYPE(SUITE, NAME, __TEST_ARRAY, ) /** * Declares function that globally modifies program state. @@ -26,7 +28,9 @@ COSMOPOLITAN_C_START_ * temorarilly by the runtime while calling fixture functions. Fixtures * are also guaranteed by the linker to be run in sorted order. */ -#define FIXTURE(SUITE, NAME) __FIXTURE("fixture", SUITE, NAME) +#define FIXTURE(SUITE, NAME) \ + STATIC_YOINK("__fixture_start"); \ + __FIXTURE("fixture", SUITE, NAME) /** * Registers explosive fixture with linker. @@ -35,7 +39,9 @@ COSMOPOLITAN_C_START_ * Cartesian product of groups. That makes this similar to fixture, but * more appropriate for testing pure code (i.e. no syscalls) like math. */ -#define COMBO(GROUP, ENTRY) __FIXTURE("combo", GROUP, ENTRY) +#define COMBO(GROUP, ENTRY) \ + STATIC_YOINK("__combo_start"); \ + __FIXTURE("combo", GROUP, ENTRY) /** * Declares benchmark function. @@ -109,9 +115,8 @@ void TearDown(void); __TEST_NE(expect, __FILE__, __LINE__, __FUNCTION__, #WANT, #GOT, WANT, GOT, \ __VA_ARGS__) -#define ASSERT_BETWEEN(BEG, END, GOT) \ - assertBetween(FILIFU _I(BEG), _I(END), _I(GOT), \ - #BEG " <= " #GOT " <= " #END, true) +#define ASSERT_BETWEEN(BEG, END, GOT) \ + assertBetween(FILIFU BEG, END, GOT, #BEG " <= " #GOT " <= " #END, true) #define ASSERT_STREQ(WANT, GOT) \ assertStringEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, true) #define ASSERT_STRNE(NOPE, GOT) \ @@ -167,9 +172,8 @@ void TearDown(void); │ cosmopolitan § testing library » assert or log ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ -#define EXPECT_BETWEEN(BEG, END, GOT) \ - assertBetween(FILIFU _I(BEG), _I(END), _I(GOT), \ - #BEG " <= " #GOT " <= " #END, false) +#define EXPECT_BETWEEN(BEG, END, GOT) \ + assertBetween(FILIFU BEG, END, GOT, #BEG " <= " #GOT " <= " #END, false) #define EXPECT_STREQ(WANT, GOT) \ assertStringEquals(FILIFU sizeof(*(WANT)), WANT, GOT, #GOT, false) #define EXPECT_STRNE(NOPE, GOT) \ @@ -233,46 +237,43 @@ void TearDown(void); const char *file; \ int line -#define TESTLIB_ONFAIL(FILE, FUNC) \ - if (g_testlib_shoulddebugbreak) DebugBreak(); \ - testlib_showerror_file = FILE; \ - testlib_showerror_func = FUNC - -#define TESTLIB_SHOWERROR(THUNK, ...) \ - (((typeof(&testlib_showerror_))strongaddr(#THUNK)))(__VA_ARGS__) - #define __TEST_EQ(KIND, FILE, LINE, FUNC, WANTCODE, GOTCODE, WANT, GOT, ...) \ - ({ \ - autotype(GOT) Got = _I(GOT); \ - typeof(Got) Want = _I(WANT); \ - testlib_ontest(); \ + do { \ + intptr_t Got, Want; \ + ++g_testlib_ran; \ + Got = (intptr_t)(GOT); \ + Want = (intptr_t)(WANT); \ if (Want != Got) { \ - TESTLIB_ONFAIL(FILE, FUNC); \ - TESTLIB_SHOWERROR(testlib_showerror_##KIND##_eq, LINE, WANTCODE, \ - GOTCODE, testlib_formatint(_I(Want)), \ - testlib_formatint(_I(Got)), "" __VA_ARGS__); \ + if (g_testlib_shoulddebugbreak) DebugBreak(); \ + testlib_showerror_file = FILE; \ + testlib_showerror_func = FUNC; \ + testlib_showerror_##KIND##_eq(LINE, WANTCODE, GOTCODE, \ + testlib_formatint(Want), \ + testlib_formatint(Got), "" __VA_ARGS__); \ } \ (void)0; \ - }) + } while (0) #define __TEST_NE(KIND, FILE, LINE, FUNC, WANTCODE, GOTCODE, WANT, GOT, ...) \ - ({ \ - autotype(GOT) Got = (GOT); \ - typeof(Got) Want = (WANT); \ - testlib_ontest(); \ + do { \ + intptr_t Got, Want; \ + ++g_testlib_ran; \ + Got = (intptr_t)(GOT); \ + Want = (intptr_t)(WANT); \ if (Want == Got) { \ - TESTLIB_ONFAIL(FILE, FUNC); \ - TESTLIB_SHOWERROR(testlib_showerror_##KIND##_ne, LINE, WANTCODE, \ - GOTCODE, testlib_formatint(_I(Want)), \ - testlib_formatint(_I(Got)), "" __VA_ARGS__); \ + if (g_testlib_shoulddebugbreak) DebugBreak(); \ + testlib_showerror_file = FILE; \ + testlib_showerror_func = FUNC; \ + testlib_showerror_##KIND##_ne(LINE, WANTCODE, GOTCODE, \ + testlib_formatint(Want), \ + testlib_formatint(Got), "" __VA_ARGS__); \ } \ - (void)0; \ - }) + } while (0) #define _TEST2(NAME, WANT, OP, GOT, WANTCODE, OPSTR, GOTCODE, ISFATAL) \ do { \ - autotype(WANT) Want = (WANT); \ - autotype(GOT) Got = (GOT); \ + intptr_t Want = (intptr_t)(WANT); \ + intptr_t Got = (intptr_t)(GOT); \ if (!(Want OP Got)) { \ testlib_showerror(FILIFU NAME, OPSTR, WANTCODE OPSTR GOTCODE, \ testlib_formatint(Want), testlib_formatint(Got)); \ @@ -300,13 +301,25 @@ extern const testfn_t __testcase_start[], __testcase_end[]; extern const struct TestFixture __fixture_start[], __fixture_end[]; extern const struct TestFixture __combo_start[], __combo_end[]; -void testlib_showerror_(int line, const char *wantcode, const char *gotcode, - char *FREED_want, char *FREED_got, const char *fmt, - ...) relegated; +void testlib_showerror_assert_eq(int, const char *, const char *, char *, + char *, const char *, ...) wontreturn; +void testlib_showerror_assert_false(int, const char *, const char *, char *, + char *, const char *, ...) wontreturn; +void testlib_showerror_assert_ne(int, const char *, const char *, char *, + char *, const char *, ...) wontreturn; +void testlib_showerror_assert_true(int, const char *, const char *, char *, + char *, const char *, ...) wontreturn; +void testlib_showerror_expect_eq(int, const char *, const char *, char *, + char *, const char *, ...); +void testlib_showerror_expect_false(int, const char *, const char *, char *, + char *, const char *, ...); +void testlib_showerror_expect_ne(int, const char *, const char *, char *, + char *, const char *, ...); +void testlib_showerror_expect_true(int, const char *, const char *, char *, + char *, const char *, ...); -void testlib_showerror(const char *file, int line, const char *func, - const char *method, const char *symbol, const char *code, - char *v1, char *v2); +void testlib_showerror(const char *, int, const char *, const char *, + const char *, const char *, char *, char *); void thrashcodecache(void); @@ -333,9 +346,9 @@ bool testlib_hexequals(const char *, const void *, size_t) nosideeffect; bool testlib_startswith(size_t, const void *, const void *) nosideeffect; bool testlib_endswith(size_t, const void *, const void *) nosideeffect; bool testlib_contains(size_t, const void *, const void *) nosideeffect; -char *testlib_formatrange(intmax_t, intmax_t) mallocesque; +char *testlib_formatrange(intptr_t, intptr_t) mallocesque; char *testlib_formatstr(size_t, const void *, int) mallocesque; -char *testlib_formatint(intmax_t) mallocesque; +char *testlib_formatint(intptr_t) mallocesque; char *testlib_formatbool(bool); char *testlib_formatfloat(long double) mallocesque; void testlib_formatbinaryashex(const char *, const void *, size_t, char **, @@ -347,9 +360,6 @@ void testlib_incrementfailed(void); void testlib_clearxmmregisters(void); forceinline void testlib_ontest() { - YOINK(__testcase_start); - YOINK(__fixture_start); - YOINK(__combo_start); ++g_testlib_ran; } @@ -358,7 +368,7 @@ forceinline void testlib_onfail2(bool isfatal) { if (isfatal) testlib_abort(); } -forceinline void assertNotEquals(FILIFU_ARGS intmax_t donotwant, intmax_t got, +forceinline void assertNotEquals(FILIFU_ARGS intptr_t donotwant, intptr_t got, const char *gotcode, bool isfatal) { ++g_testlib_ran; if (got != donotwant) return; @@ -369,7 +379,7 @@ forceinline void assertNotEquals(FILIFU_ARGS intmax_t donotwant, intmax_t got, } #define assertLongDoubleGreaterThan(a, b, code, isfatal) \ - ({ \ + do { \ autotype(a) a_ = (a); \ autotype(b) b_ = (b); \ if (a_ <= b_) { \ @@ -378,10 +388,10 @@ forceinline void assertNotEquals(FILIFU_ARGS intmax_t donotwant, intmax_t got, testlib_onfail2(isfatal); \ } \ (void)0; \ - }) + } while (0) #define assertLongDoubleLessThan(a, b, code, isfatal) \ - ({ \ + do { \ autotype(a) a_ = (a); \ autotype(b) b_ = (b); \ if (a_ >= b_) { \ @@ -390,10 +400,10 @@ forceinline void assertNotEquals(FILIFU_ARGS intmax_t donotwant, intmax_t got, testlib_onfail2(isfatal); \ } \ (void)0; \ - }) + } while (0) -forceinline void assertBetween(FILIFU_ARGS intmax_t beg, intmax_t end, - intmax_t got, const char *gotcode, +forceinline void assertBetween(FILIFU_ARGS intptr_t beg, intptr_t end, + intptr_t got, const char *gotcode, bool isfatal) { ++g_testlib_ran; if (beg <= got && got <= end) return; diff --git a/libc/testlib/ugly.h b/libc/testlib/ugly.h index 1f7ed9f08..2a2511bd0 100644 --- a/libc/testlib/ugly.h +++ b/libc/testlib/ugly.h @@ -3,20 +3,15 @@ #include "libc/macros.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) -#if defined(__GNUC__) || defined(__llvm__) -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" /* j.f.c. */ -#endif -#define _I(x) (TYPE_SIGNED(typeof(x)) ? (intmax_t)(x) : (uintmax_t)(x)) - #define __TEST_ARRAY(S) \ _Section(".piro.relo.sort.testcase.2." #S ",\"aw\",@init_array #") #define __BENCH_ARRAY(S) \ _Section(".piro.relo.sort.bench.2." #S ",\"aw\",@init_array #") -#define __TEST_PROTOTYPE(S, N, A, K) \ - testonly void S##_##N(void); \ - _Alignas(long) const void *const S##_##N##_ptr[] A(S) = {S##_##N}; \ +#define __TEST_PROTOTYPE(S, N, A, K) \ + void S##_##N(void); \ + const void *const S##_##N##_ptr[] A(S) = {S##_##N}; \ testonly K void S##_##N(void) #define __TEST_SECTION(NAME, CONTENT) \ diff --git a/test/libc/calls/fork_test.c b/test/libc/calls/fork_test.c index 5d737c93b..470e5b31b 100644 --- a/test/libc/calls/fork_test.c +++ b/test/libc/calls/fork_test.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/macros.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" diff --git a/libc/calls/thunks/mmap-sysv.S b/test/libc/calls/getenv_test.c similarity index 79% rename from libc/calls/thunks/mmap-sysv.S rename to test/libc/calls/getenv_test.c index a739c766c..d7cf3abca 100644 --- a/libc/calls/thunks/mmap-sysv.S +++ b/test/libc/calls/getenv_test.c @@ -1,7 +1,7 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ Copyright 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/macros.h" -.source __FILE__ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" -/ Directly calls mmap() on system five host o/s. -sys_mmap: - push %rbp - mov %rsp,%rbp - push %r9 # netbsd+openbsd:pad - call __sys_mmap - leave - ret - .endfn sys_mmap,globl,hidden +TEST(getenv, test) { + putenv("x=y"); + EXPECT_STREQ("y", getenv("x")); + unsetenv("x"); + EXPECT_EQ(NULL, getenv("x")); +} diff --git a/test/libc/fmt/dirname_test.c b/test/libc/fmt/dirname_test.c index 8e39bd175..6128a4cea 100644 --- a/test/libc/fmt/dirname_test.c +++ b/test/libc/fmt/dirname_test.c @@ -23,6 +23,8 @@ #include "libc/testlib/testlib.h" TEST(dirname, test) { + EXPECT_STREQ("/usr/lib", dirname(gc(strdup("/usr/lib/foo.bar")))); + EXPECT_STREQ("/usr", dirname(gc(strdup("/usr/lib")))); EXPECT_STREQ("/usr", dirname(gc(strdup("/usr/lib")))); EXPECT_STREQ("usr", dirname(gc(strdup("usr/lib")))); EXPECT_STREQ("/", dirname(gc(strdup("/usr/")))); diff --git a/test/libc/release/smoke.c b/test/libc/release/smoke.c index 20ce3a98c..d1e1fa5f0 100644 --- a/test/libc/release/smoke.c +++ b/test/libc/release/smoke.c @@ -1,11 +1,14 @@ int main(int argc, char *argv[]) { int rc; + char *s; FILE *f; + s = strdup(argv[0]); f = fopen("/dev/null", "w"); - fprintf(f, "hello world %d\n", argc); + fprintf(f, "hello world %d %s\n", argc, s); fclose(f); rc = system("exit 42"); CHECK_NE(-1, rc); CHECK_EQ(42, WEXITSTATUS(rc)); + free(s); return 0; } diff --git a/test/libc/release/test.mk b/test/libc/release/test.mk index 3a27dcdca..6631b2160 100644 --- a/test/libc/release/test.mk +++ b/test/libc/release/test.mk @@ -20,7 +20,7 @@ o/$(MODE)/test/libc/release/smoke.com.dbg: \ o/$(MODE)/libc/crt/crt.o \ o/$(MODE)/ape/ape.o \ o/$(MODE)/cosmopolitan.a - @ACTION=CC build/compile $(CC) \ + @ACTION=CC $(COMPILE) $(CC) \ -o $@ \ -Os \ -static \ @@ -49,7 +49,7 @@ o/$(MODE)/test/libc/release/smokecxx.com.dbg: \ o/$(MODE)/libc/crt/crt.o \ o/$(MODE)/ape/ape.o \ o/$(MODE)/cosmopolitan.a - @ACTION=CXX build/compile $(CXX) \ + @ACTION=CXX $(COMPILE) $(CXX) \ -o $@ \ -Os \ -static \ @@ -74,7 +74,7 @@ o/$(MODE)/test/libc/release/smokeansi.com.dbg: \ o/$(MODE)/libc/crt/crt.o \ o/$(MODE)/ape/ape.o \ o/$(MODE)/cosmopolitan.a - @ACTION=ANSI build/compile $(CC) \ + @ACTION=ANSI $(COMPILE) $(CC) \ -o $@ \ -Os \ -ansi \ @@ -100,7 +100,7 @@ o/$(MODE)/test/libc/release/smokeclang.com.dbg: \ o/$(MODE)/libc/crt/crt.o \ o/$(MODE)/ape/ape.o \ o/$(MODE)/cosmopolitan.a - @ACTION=CLANG build/compile clang \ + @ACTION=CLANG $(COMPILE) clang \ -o $@ \ -Os \ -static \ @@ -125,4 +125,6 @@ o/$(MODE)/test/libc/release: \ o/$(MODE)/test/libc/release/smokecxx.com \ o/$(MODE)/test/libc/release/smokecxx.com.runs \ o/$(MODE)/test/libc/release/smokeansi.com \ - o/$(MODE)/test/libc/release/smokeansi.com.runs + o/$(MODE)/test/libc/release/smokeansi.com.runs \ + o/$(MODE)/test/libc/release/smokeclang.com \ + o/$(MODE)/test/libc/release/smokeclang.com.runs diff --git a/test/libc/sock/inet_pton_test.c b/test/libc/sock/inet_pton_test.c index b3d0f2a2d..8229b5fde 100644 --- a/test/libc/sock/inet_pton_test.c +++ b/test/libc/sock/inet_pton_test.c @@ -16,7 +16,6 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/progn.internal.h" #include "libc/bits/safemacros.h" #include "libc/sock/sock.h" #include "libc/sysv/consts/af.h" @@ -25,8 +24,8 @@ TEST(inet_pton, testLocalhost) { uint32_t addr; - EXPECT_EQ(htonl(INADDR_LOOPBACK), - PROGN(ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &addr)), addr)); + ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &addr)); + EXPECT_EQ(htonl(INADDR_LOOPBACK), addr); } TEST(inet_pton, testBadAddresses) { diff --git a/test/libc/str/memcpy_test.c b/test/libc/str/memcpy_test.c index ff3e6f25d..8a6acb849 100644 --- a/test/libc/str/memcpy_test.c +++ b/test/libc/str/memcpy_test.c @@ -172,12 +172,12 @@ void *MemCpy(void *, const void *, size_t); free(s); \ } while (0) -#define BB(N) \ - do { \ - B(memmove_pure, N); \ - B(memcpy, N); \ - B(MemCpy, N); \ - fprintf(stderr, "\n"); \ +#define BB(N) \ + do { \ + B(memmove_pure, N); \ + B(memcpy, N); \ + B(MemCpy, N); \ + (fprintf)(stderr, "\n"); \ } while (0) BENCH(memcpy, bench) { diff --git a/test/libc/str/memmem_test.c b/test/libc/str/memmem_test.c index 21478b10c..4b2695df0 100644 --- a/test/libc/str/memmem_test.c +++ b/test/libc/str/memmem_test.c @@ -23,20 +23,15 @@ #include "libc/str/str.h" #include "libc/testlib/testlib.h" -void *(*memmemi)(const void *, size_t, const void *, size_t) = memmem; -FIXTURE(memmem, tiny) { - memmemi = tinymemmem; -} - #define MakeMemory(SL) memcpy(malloc(sizeof(SL) - 1), SL, sizeof(SL) - 1) TEST(memmem, test) { char *needle = MakeMemory("abcdefgh"); char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); - EXPECT_BINEQ(u"abcdefghdddddddd", memmemi(haystk, 32, needle, 8)); + EXPECT_BINEQ(u"abcdefghdddddddd", memmem(haystk, 32, needle, 8)); memcpy(needle, "aaaaaaaa", 8); memcpy(haystk, "acccccccbbbbbbbbaaaaaaaadddddddd", 32); - EXPECT_BINEQ(u"aaaaaaaadddddddd", memmemi(haystk, 32, needle, 8)); + EXPECT_BINEQ(u"aaaaaaaadddddddd", memmem(haystk, 32, needle, 8)); free(haystk); free(needle); } @@ -44,7 +39,7 @@ TEST(memmem, test) { TEST(memmem, testNoMatch) { char *needle = MakeMemory("abcdefzh"); char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); - EXPECT_EQ(NULL, memmemi(haystk, 32, needle, 8)); + EXPECT_EQ(NULL, memmem(haystk, 32, needle, 8)); free(haystk); free(needle); } @@ -52,7 +47,7 @@ TEST(memmem, testNoMatch) { TEST(memmem, testStartOfMemory) { char *needle = MakeMemory("acccc"); char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd"); - EXPECT_EQ(&haystk[0], memmemi(haystk, 32, needle, 5)); + EXPECT_EQ(&haystk[0], memmem(haystk, 32, needle, 5)); free(haystk); free(needle); } @@ -60,7 +55,7 @@ TEST(memmem, testStartOfMemory) { TEST(memmem, testEndOfMemory) { char *needle = MakeMemory("123"); char *haystk = MakeMemory("abc123"); - EXPECT_EQ(&haystk[3], memmemi(haystk, 6, needle, 3)); + EXPECT_EQ(&haystk[3], memmem(haystk, 6, needle, 3)); free(haystk); free(needle); } @@ -68,7 +63,7 @@ TEST(memmem, testEndOfMemory) { TEST(memmem, testCrossesSseRegister) { char *needle = MakeMemory("eeeeeeeeeeeeefffffffffffff"); char *haystk = MakeMemory("eeeeeeeeeeeeeeeeffffffffffffffffrrrrrrrrrrrrrrrr"); - EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26)); + EXPECT_EQ(&haystk[3], memmem(haystk, 16 * 3, needle, 26)); free(haystk); free(needle); } @@ -77,7 +72,7 @@ TEST(memmem, testHasNulCharacters) { char *needle = MakeMemory("eeeeeeeeeeeee\0ffffffffffff"); char *haystk = MakeMemory("eeeeeeeeeeeeeeee\0fffffffffffffffrrrrrrrrrrrrrrrr"); - EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26)); + EXPECT_EQ(&haystk[3], memmem(haystk, 16 * 3, needle, 26)); free(haystk); free(needle); } @@ -85,7 +80,7 @@ TEST(memmem, testHasNulCharacters) { TEST(memmem, testWeird) { char *needle = MakeMemory("-*-+-+-+-+-+-+-+"); char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+"); - EXPECT_EQ(14, (intptr_t)memmemi(haystk, 32, needle, 16) - (intptr_t)haystk); + EXPECT_EQ(14, (intptr_t)memmem(haystk, 32, needle, 16) - (intptr_t)haystk); free(haystk); free(needle); } @@ -93,7 +88,7 @@ TEST(memmem, testWeird) { TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) { char *needle = malloc(0); char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+"); - EXPECT_EQ(0, (intptr_t)memmemi(haystk, 32, needle, 0) - (intptr_t)haystk); + EXPECT_EQ(0, (intptr_t)memmem(haystk, 32, needle, 0) - (intptr_t)haystk); free(haystk); free(needle); } @@ -101,8 +96,8 @@ TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) { TEST(memmem, testEmptyHaystack_alwaysReturnsNull) { char *needle = MakeMemory("-*-+-+-+-+-+-+-+"); char *haystk = malloc(0); - EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 16)); - EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 1)); + EXPECT_EQ(NULL, memmem(haystk, 0, needle, 16)); + EXPECT_EQ(NULL, memmem(haystk, 0, needle, 1)); free(haystk); free(needle); } @@ -110,7 +105,11 @@ TEST(memmem, testEmptyHaystack_alwaysReturnsNull) { TEST(memmem, testEmptyHaystackAndNeedle_returnsHaystack) { char *needle = malloc(0); char *haystk = malloc(0); - EXPECT_EQ(haystk, memmemi(haystk, 0, needle, 0)); + EXPECT_EQ(haystk, memmem(haystk, 0, needle, 0)); free(haystk); free(needle); } + +TEST(memmem, testWut) { + ASSERT_STREQ("x", memmem("x", 1, "x", 1)); +} diff --git a/test/libc/str/strstr_test.c b/test/libc/str/strstr_test.c index 82a8f1527..1a4262188 100644 --- a/test/libc/str/strstr_test.c +++ b/test/libc/str/strstr_test.c @@ -32,52 +32,46 @@ char *strstr_kmp(const char *haystak, const char *needle) { return memmem(haystak, strlen(haystak), needle, strlen(needle)); } -char *(*strstri)(const char *, const char *) = strstr_kmp; - -FIXTURE(strstr, sse42_) { - if (X86_HAVE(SSE4_2)) { - strstri = strstr_sse42; - } -} - TEST(strstr, test_emptyString_isFoundAtBeginning) { MAKESTRING(haystack, "abc123def"); - ASSERT_STREQ(&haystack[0], strstri(haystack, gc(strdup("")))); ASSERT_STREQ(&haystack[0], strstr(haystack, gc(strdup("")))); free(haystack); } TEST(strstr, test_notFound) { MAKESTRING(haystack, "abc123def"); - ASSERT_EQ(NULL, strstri(haystack, gc(strdup("xyz")))); ASSERT_EQ(NULL, strstr(haystack, gc(strdup("xyz")))); free(haystack); } TEST(strstr, test_middleOfString) { MAKESTRING(haystack, "abc123def"); - ASSERT_STREQ(&haystack[3], strstri(haystack, gc(strdup("123")))); ASSERT_STREQ(&haystack[3], strstr(haystack, gc(strdup("123")))); free(haystack); } TEST(strstr, test_endOfString) { MAKESTRING(haystack, "abc123def"); - ASSERT_STREQ(&haystack[8], strstri(haystack, gc(strdup("f")))); ASSERT_STREQ(&haystack[8], strstr(haystack, gc(strdup("f")))); free(haystack); } TEST(strstr, test_secondXmmWord) { MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbb123"); - ASSERT_STREQ(&haystack[27], strstri(haystack, gc(strdup("123")))); ASSERT_STREQ(&haystack[27], strstr(haystack, gc(strdup("123")))); free(haystack); } TEST(strstr, test_overlapsXmmWords) { MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbbbbbb"); - ASSERT_STREQ(&haystack[15], strstri(haystack, gc(strdup("eb")))); ASSERT_STREQ(&haystack[15], strstr(haystack, gc(strdup("eb")))); free(haystack); } + +TEST(strstr, test) { + ASSERT_EQ(NULL, strstr("x86_64-linux-musl-gcc", "clang")); + ASSERT_STREQ("gcc", strstr("x86_64-linux-musl-gcc", "gcc")); + ASSERT_EQ(NULL, strstr("-Wl,--gc-sections", "stack-protector")); + ASSERT_EQ(NULL, strstr("-Wl,--gc-sections", "sanitize")); + ASSERT_STREQ("x", strstr("x", "x")); +} diff --git a/test/libc/str/tpdecode_test.c b/test/libc/str/tpdecode_test.c deleted file mode 100644 index 411951510..000000000 --- a/test/libc/str/tpdecode_test.c +++ /dev/null @@ -1,86 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/bits/progn.internal.h" -#include "libc/bits/safemacros.h" -#include "libc/errno.h" -#include "libc/fmt/bing.internal.h" -#include "libc/limits.h" -#include "libc/runtime/gc.h" -#include "libc/str/str.h" -#include "libc/str/tpdecode.internal.h" -#include "libc/testlib/testlib.h" - -wint_t wc; - -TEST(tpdecode, testEmptyString_consumesNulTerminator) { - wc = 123; - EXPECT_EQ(1, tpdecode("", &wc)); - EXPECT_EQ(0, wc); -} - -TEST(tpdecode, testGlyph) { - EXPECT_EQ(u'→', PROGN(ASSERT_EQ(3, tpdecode("→", &wc)), wc)); - EXPECT_EQ(L'𐌰', PROGN(ASSERT_EQ(4, tpdecode("𐌰𐌱𐌲𐌳", &wc)), wc)); - EXPECT_EQ(u'ち', PROGN(ASSERT_EQ(3, tpdecode("ち", &wc)), wc)); - EXPECT_EQ(u'‱', PROGN(ASSERT_EQ(3, tpdecode("‱", &wc)), wc)); -} - -TEST(tpdecode, testNul_canonicalizesWithFiniteOverlongConsumption) { - EXPECT_EQ('\0', PROGN(ASSERT_EQ(1, tpdecode("\0\0\0\0", &wc)), wc)); - EXPECT_EQ('\0', - PROGN(ASSERT_EQ(2, tpdecode(gc(unbingstr(u"└ÇÇÇÇÇ")), &wc)), wc)); - EXPECT_EQ('\0', - PROGN(ASSERT_EQ(3, tpdecode(gc(unbingstr(u"αÇÇÇÇÇ")), &wc)), wc)); - EXPECT_EQ('\0', - PROGN(ASSERT_EQ(4, tpdecode(gc(unbingstr(u"≡ÇÇÇÇÇ")), &wc)), wc)); - EXPECT_EQ('\0', - PROGN(ASSERT_EQ(5, tpdecode(gc(unbingstr(u"°ÇÇÇÇÇ")), &wc)), wc)); - EXPECT_EQ('\0', - PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"ⁿÇÇÇÇÇ")), &wc)), wc)); -} - -TEST(tpdecode, testSynchronization_skipsLeadingContinuations) { - EXPECT_EQ('a', - PROGN(EXPECT_EQ(7, tpdecode(gc(unbingstr(u"Ç╗╝╜╛┐a")), &wc)), wc)); -} - -TEST(tpdecode, testSpace) { - EXPECT_EQ(0x20, PROGN(ASSERT_EQ(1, tpdecode(" ", &wc)), wc)); -} - -TEST(tpdecode, testNegativeNumbers) { - EXPECT_EQ(-1, PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"λ┐┐┐┐┐")), &wc)), - (wchar_t)wc)); - EXPECT_EQ(INT_MIN, - PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"■ÇÇÇÇÇ")), &wc)), - (wchar_t)wc)); - EXPECT_EQ(0x80000000u, - PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"■ÇÇÇÇÇ")), &wc)), wc)); - EXPECT_EQ(0xC0000000u, - PROGN(ASSERT_EQ(6, tpdecode(gc(unbingstr(u"λÇÇÇÇÇ")), &wc)), wc)); -} - -TEST(tpdecode, testInvalidEncoding_endOfString) { - EXPECT_EQ(u'�', PROGN(EXPECT_EQ(-1, tpdecode(gc(unbingstr(u"≡")), &wc)), wc)); -} - -TEST(tpdecode, testInvalidEncoding_tooFewContinuations) { - EXPECT_EQ(u'�', PROGN(EXPECT_EQ(-1, tpdecode(gc(unbingstr(u"≡")), &wc)), wc)); -} diff --git a/test/libc/str/tpencode_test.c b/test/libc/str/tpencode_test.c deleted file mode 100644 index 2323380a3..000000000 --- a/test/libc/str/tpencode_test.c +++ /dev/null @@ -1,66 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/bits/progn.internal.h" -#include "libc/bits/safemacros.h" -#include "libc/str/str.h" -#include "libc/str/tpencode.internal.h" -#include "libc/testlib/testlib.h" - -char buf[8]; - -TEST(tpencode, testNul) { - ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, tpencode(buf, 8, 0, false)), buf)); - ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, (tpencode)(buf, 8, 0, false)), buf)); -} - -TEST(tpencode, testSpace) { - ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, tpencode(buf, 8, 0x20, false)), buf)); - ASSERT_BINEQ(u" ", PROGN(ASSERT_EQ(1, (tpencode)(buf, 8, 0x20, false)), buf)); -} - -TEST(tpencode, testGlyph) { - ASSERT_EQ(3, tpencode(buf, 8, u'→', false)); - ASSERT_BINEQ(u"ΓåÆ", buf); - ASSERT_EQ(3, (tpencode)(buf, 8, u'→', false)); - ASSERT_BINEQ(u"ΓåÆ", buf); -} - -TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_negativeOne) { - ASSERT_BINEQ(u"λ┐┐┐┐┐", - PROGN(ASSERT_EQ(6, tpencode(buf, 8, -1, false)), buf)); - ASSERT_BINEQ(u"λ┐┐┐┐┐", - PROGN(ASSERT_EQ(6, (tpencode)(buf, 8, -1, false)), buf)); -} - -TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_twosComplementBane) { - ASSERT_BINEQ(u"■ÇÇÇÇÇ", - PROGN(ASSERT_EQ(6, tpencode(buf, 8, 0x80000000, false)), buf)); - ASSERT_BINEQ(u"■ÇÇÇÇÇ", - PROGN(ASSERT_EQ(6, (tpencode)(buf, 8, 0x80000000, false)), buf)); -} - -TEST(tpencode, testMathematicalNotMuhPolicyDrivenBehavior_nonCanonicalNul) { - ASSERT_BINEQ(u"└Ç", PROGN(ASSERT_EQ(2, tpencode(buf, 8, 0, true)), buf)); - ASSERT_BINEQ(u"└Ç", PROGN(ASSERT_EQ(2, (tpencode)(buf, 8, 0, true)), buf)); -} - -TEST(tpencode, testC1Csi) { - ASSERT_BINEQ(u"┬¢", PROGN(ASSERT_EQ(2, tpencode(buf, 8, 0x9B, false)), buf)); -} diff --git a/third_party/chibicc/test/test.h b/third_party/chibicc/test/test.h index 201b2e902..7d1a35376 100644 --- a/third_party/chibicc/test/test.h +++ b/third_party/chibicc/test/test.h @@ -3,6 +3,9 @@ #include "libc/stdio/stdio.h" #include "libc/str/str.h" +STATIC_YOINK("__mmap"); /* asan needs it */ +STATIC_YOINK("TrackMemoryInterval"); /* asan needs it */ + #define ASSERT(x, y) Assert2(x, y, #y, __FILE__, __LINE__) #define ASSERT128(x, y) Assert128(x, y, #y, __FILE__, __LINE__) diff --git a/third_party/chibicc/test/test.mk b/third_party/chibicc/test/test.mk index 142846f09..13c14ad46 100644 --- a/third_party/chibicc/test/test.mk +++ b/third_party/chibicc/test/test.mk @@ -90,6 +90,9 @@ o/$(MODE)/third_party/chibicc/test/%2.com.dbg: \ $(APE) @$(APELINK) +.PRECIOUS: $(THIRD_PARTY_CHIBICC_TEST_OBJS) +.PRECIOUS: $(THIRD_PARTY_CHIBICC_TEST2_OBJS) + .PHONY: o/$(MODE)/third_party/chibicc/test o/$(MODE)/third_party/chibicc/test: \ $(THIRD_PARTY_CHIBICC_TEST_BINS) \ diff --git a/tool/build/ar.c b/tool/build/ar.c index 8c9652fa2..835ba1380 100644 --- a/tool/build/ar.c +++ b/tool/build/ar.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/alg/arraylist2.internal.h" #include "libc/bits/bits.h" +#include "libc/bits/safemacros.h" #include "libc/calls/calls.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/stat.h" @@ -53,6 +54,11 @@ * directory be a .a prerequisite so archives rebuild on file deletion. */ +struct Args { + size_t n; + char **p; +}; + struct String { size_t i, n; char *p; @@ -95,14 +101,18 @@ static void MakeHeader(struct Header *h, const char *name, int ref, int mode, } int main(int argc, char *argv[]) { + FILE *f; void *elf; + char *line; char *strs; ssize_t rc; + size_t wrote; + size_t remain; struct stat *st; uint32_t outpos; Elf64_Sym *syms; + struct Args args; uint64_t outsize; - char **objectargs; uint8_t *tablebuf; struct iovec iov[7]; const char *symname; @@ -112,7 +122,6 @@ int main(int argc, char *argv[]) { struct String symbols; struct String filenames; struct Header *header1, *header2; - size_t wrote, remain, objectargcount; int *offsets, *modes, *sizes, *names; int i, j, fd, err, name, outfd, tablebufsize; @@ -121,6 +130,25 @@ int main(int argc, char *argv[]) { return 1; } + memset(&args, 0, sizeof(args)); + for (i = 3; i < argc; ++i) { + if (argv[i][0] != '@') { + args.p = realloc(args.p, ++args.n * sizeof(*args.p)); + args.p[args.n - 1] = strdup(argv[i]); + } else { + CHECK_NOTNULL((f = fopen(argv[i] + 1, "r"))); + while ((line = chomp(xgetline(f)))) { + if (!isempty(line)) { + args.p = realloc(args.p, ++args.n * sizeof(*args.p)); + args.p[args.n - 1] = line; + } else { + free(line); + } + } + CHECK_NE(-1, fclose(f)); + } + } + st = xmalloc(sizeof(struct stat)); symbols.i = 0; symbols.n = 4096; @@ -133,32 +161,29 @@ int main(int argc, char *argv[]) { symnames.p = xmalloc(symnames.n * sizeof(int)); outpath = argv[2]; - objectargs = argv + 3; - objectargcount = argc - 3; - modes = xmalloc(sizeof(int) * objectargcount); - names = xmalloc(sizeof(int) * objectargcount); - sizes = xmalloc(sizeof(int) * objectargcount); + modes = xmalloc(sizeof(int) * args.n); + names = xmalloc(sizeof(int) * args.n); + sizes = xmalloc(sizeof(int) * args.n); // load global symbols and populate page cache - for (i = 0; i < objectargcount; ++i) { + for (i = 0; i < args.n; ++i) { TryAgain: - CHECK_NE(-1, (fd = open(objectargs[i], O_RDONLY))); + CHECK_NE(-1, (fd = open(args.p[i], O_RDONLY)), "%s", args.p[i]); CHECK_NE(-1, fstat(fd, st)); CHECK_LT(st->st_size, 0x7ffff000); - if (!st->st_size || S_ISDIR(st->st_mode) || - endswith(objectargs[i], ".pkg")) { + if (!st->st_size || S_ISDIR(st->st_mode) || endswith(args.p[i], ".pkg")) { close(fd); - for (j = i; j + 1 < objectargcount; ++j) { - objectargs[j] = objectargs[j + 1]; + for (j = i; j + 1 < args.n; ++j) { + args.p[j] = args.p[j + 1]; } - --objectargcount; + --args.n; goto TryAgain; } names[i] = filenames.i; sizes[i] = st->st_size; modes[i] = st->st_mode; - CONCAT(&filenames.p, &filenames.i, &filenames.n, basename(objectargs[i]), - strlen(basename(objectargs[i]))); + CONCAT(&filenames.p, &filenames.i, &filenames.n, basename(args.p[i]), + strlen(basename(args.p[i]))); CONCAT(&filenames.p, &filenames.i, &filenames.n, "/\n", 2); CHECK_NE(MAP_FAILED, (elf = mmap(NULL, st->st_size, PROT_READ, MAP_PRIVATE, fd, 0))); @@ -182,7 +207,7 @@ int main(int argc, char *argv[]) { outsize = 0; tablebufsize = 4 + symnames.i * 4; tablebuf = xmalloc(tablebufsize); - offsets = xmalloc(objectargcount * 4); + offsets = xmalloc(args.n * 4); header1 = xmalloc(sizeof(struct Header)); header2 = xmalloc(sizeof(struct Header)); iov[0].iov_base = "!\n"; @@ -199,7 +224,7 @@ int main(int argc, char *argv[]) { outsize += (iov[5].iov_len = 60); iov[6].iov_base = filenames.p; outsize += (iov[6].iov_len = filenames.i); - for (i = 0; i < objectargcount; ++i) { + for (i = 0; i < args.n; ++i) { outsize += outsize & 1; offsets[i] = outsize; outsize += 60; @@ -219,8 +244,8 @@ int main(int argc, char *argv[]) { CHECK_NE(-1, (outfd = open(outpath, O_WRONLY | O_TRUNC | O_CREAT, 0644))); ftruncate(outfd, outsize); if ((outsize = writev(outfd, iov, ARRAYLEN(iov))) == -1) goto fail; - for (i = 0; i < objectargcount; ++i) { - if ((fd = open(objectargs[i], O_RDONLY)) == -1) goto fail; + for (i = 0; i < args.n; ++i) { + if ((fd = open(args.p[i], O_RDONLY)) == -1) goto fail; iov[0].iov_base = "\n"; outsize += (iov[0].iov_len = outsize & 1); iov[1].iov_base = header1; @@ -233,6 +258,8 @@ int main(int argc, char *argv[]) { } close(outfd); + for (i = 0; i < args.n; ++i) free(args.p[i]); + free(args.p); free(header2); free(header1); free(offsets); diff --git a/tool/build/compile.c b/tool/build/compile.c new file mode 100644 index 000000000..519e72307 --- /dev/null +++ b/tool/build/compile.c @@ -0,0 +1,337 @@ +/*-*- 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/bits/safemacros.h" +#include "libc/calls/calls.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/struct/sigset.h" +#include "libc/errno.h" +#include "libc/fmt/conv.h" +#include "libc/log/log.h" +#include "libc/mem/mem.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/sig.h" +#include "libc/x/x.h" + +#define MANUAL \ + "\ +OVERVIEW\n\ +\n\ + GNU/LLVM Compiler Collection Frontend Frontend\n\ +\n\ +DESCRIPTION\n\ +\n\ + This launches gcc or clang while filtering out\n\ + flags they whine about.\n\ +\n\ +EXAMPLE\n\ +\n\ + compile.com gcc -o program program.c\n\ +\n" + +struct Flags { + size_t n; + char **p; +}; + +struct Command { + size_t n; + char *p; +}; + +bool iscc; +bool isclang; +bool isgcc; +bool wantasan; +bool wantfentry; +bool wantframe; +bool wantnop; +bool wantnopg; +bool wantpg; +bool wantrecord; +bool wantubsan; + +char *cc; +char *colorflag; +char *outdir; +char *outpath; +char ccpath[PATH_MAX]; +int ccversion; + +struct Flags flags; +struct Command command; + +void AddFlag(char *s) { + size_t n; + flags.p = realloc(flags.p, ++flags.n * sizeof(*flags.p)); + flags.p[flags.n - 1] = s; + if (s) { + n = strlen(s); + if (command.n) { + command.p = realloc(command.p, command.n + 1 + n); + command.p[command.n] = ' '; + memcpy(command.p + command.n + 1, s, n); + command.n += 1 + n; + } else { + command.p = realloc(command.p, command.n + n); + memcpy(command.p + command.n, s, n); + command.n += n; + } + } else { + command.p = realloc(command.p, command.n + 1); + command.p[command.n] = '\n'; + command.n += 1; + } +} + +int main(int argc, char *argv[]) { + int i, ws, pid; + sigset_t mask, savemask; + + if (argc == 1) { + write(2, MANUAL, sizeof(MANUAL) - 1); + exit(1); + } + + if (argc == 2 && !strcmp(argv[1], "--do-nothing")) { + exit(0); + } + + if (!isdirectory("o/third_party/gcc")) { + system("third_party/gcc/unbundle.sh"); + } + + cc = argv[1]; + if (!strchr(cc, '/')) { + if (!(cc = commandv(argv[1], ccpath))) exit(127); + } + + ccversion = atoi(firstnonnull(emptytonull(getenv("CCVERSION")), "4")); + isgcc = strstr(basename(cc), "gcc"); + isclang = strstr(basename(cc), "clang"); + iscc = isgcc | isclang; + + for (i = 1; i < argc; ++i) { + if (argv[i][0] != '-') { + AddFlag(argv[i]); + continue; + } + if (!strcmp(argv[i], "-o")) { + AddFlag(argv[i]); + AddFlag((outpath = argv[++i])); + continue; + } + if (iscc) { + AddFlag(argv[i]); + continue; + } + if (!strcmp(argv[i], "-w")) { + AddFlag(argv[i]); + AddFlag("-D__W__"); + } else if (!strcmp(argv[i], "-Oz")) { + if (isclang) { + AddFlag(argv[i]); + } else { + AddFlag("-Os"); + } + } else if (!strcmp(argv[i], "-pg")) { + wantpg = true; + } else if (!strcmp(argv[i], "-x-no-pg")) { + wantnopg = true; + } else if (!strcmp(argv[i], "-mfentry")) { + wantfentry = true; + } else if (!strcmp(argv[i], "-mnop-mcount")) { + wantnop = true; + } else if (!strcmp(argv[i], "-mrecord-mcount")) { + wantrecord = true; + } else if (!strcmp(argv[i], "-fno-omit-frame-pointer")) { + wantframe = true; + } else if (!strcmp(argv[i], "-fomit-frame-pointer")) { + wantframe = false; + } else if (!strcmp(argv[i], "-mno-vzeroupper")) { + if (isgcc) { + AddFlag("-Wa,-msse2avx"); + AddFlag("-D__MNO_VZEROUPPER__"); + } else if (isclang) { + AddFlag("-mllvm"); + AddFlag("-x86-use-vzeroupper=0"); + } + } else if (!strcmp(argv[i], "-msse2avx")) { + if (isgcc) { + AddFlag(argv[i]); + } else if (isclang) { + AddFlag("-Wa,-msse2avx"); + } + } else if (!strcmp(argv[i], "-fsanitize=address")) { + if (isgcc && ccversion >= 6) wantasan = true; + } else if (!strcmp(argv[i], "-fsanitize=undefined")) { + if (isgcc && ccversion >= 6) wantubsan = true; + } else if (!strcmp(argv[i], "-fno-sanitize=address")) { + wantasan = false; + } else if (!strcmp(argv[i], "-fno-sanitize=undefined")) { + wantubsan = false; + } else if (!strcmp(argv[i], "-fno-sanitize=all")) { + wantasan = false; + wantubsan = false; + } else if (startswith(argv[i], "-fsanitize=implicit") && + strstr(argv[i], "integer")) { + if (isgcc) AddFlag(argv[i]); + } else if (startswith(argv[i], "-fvect-cost") || + startswith(argv[i], "-mstringop") || + startswith(argv[i], "-gz") || + strstr(argv[i], "stack-protector") || + strstr(argv[i], "sanitize") || + startswith(argv[i], "-fvect-cost") || + startswith(argv[i], "-fvect-cost")) { + if (isgcc && ccversion >= 6) { + AddFlag(argv[i]); + } + } else if (startswith(argv[i], "-fdiagnostic-color=")) { + colorflag = argv[i]; + } else if (startswith(argv[i], "-R") || + !strcmp(argv[i], "-fsave-optimization-record")) { + if (isclang) AddFlag(argv[i]); + } else if (isclang && + (!strcmp(argv[i], "-gstabs") || !strcmp(argv[i], "-ftrapv") || + !strcmp(argv[i], "-fsignaling-nans") || + !strcmp(argv[i], "-fcx-limited-range") || + !strcmp(argv[i], "-fno-fp-int-builtin-inexact") || + !strcmp(argv[i], "-Wno-unused-but-set-variable") || + !strcmp(argv[i], "-Wunsafe-loop-optimizations") || + !strcmp(argv[i], "-mdispatch-scheduler") || + !strcmp(argv[i], "-ftracer") || + !strcmp(argv[i], "-frounding-math") || + !strcmp(argv[i], "-fmerge-constants") || + !strcmp(argv[i], "-fmodulo-sched") || + !strcmp(argv[i], "-fopt-info-vec") || + !strcmp(argv[i], "-fopt-info-vec-missed") || + !strcmp(argv[i], "-fmodulo-sched-allow-regmoves") || + !strcmp(argv[i], "-freschedule-modulo-scheduled-loops") || + !strcmp(argv[i], "-fipa-pta") || + !strcmp(argv[i], "-fsched2-use-superblocks") || + !strcmp(argv[i], "-fbranch-target-load-optimize") || + !strcmp(argv[i], "-fdelete-dead-exceptions") || + !strcmp(argv[i], "-funsafe-loop-optimizations") || + !strcmp(argv[i], "-mmitigate-rop") || + !strcmp(argv[i], "-fno-align-jumps") || + !strcmp(argv[i], "-fno-align-labels") || + !strcmp(argv[i], "-fno-align-loops") || + !strcmp(argv[i], "-fivopts") || + !strcmp(argv[i], "-fschedule-insns") || + !strcmp(argv[i], "-fno-semantic-interposition") || + !strcmp(argv[i], "-mno-fentry") || + !strcmp(argv[i], "-fversion-loops-for-strides") || + !strcmp(argv[i], "-femit-struct-debug-baseonly") || + !strcmp(argv[i], "-ftree-loop-vectorize") || + !strcmp(argv[i], "-gdescribe-dies") || + !strcmp(argv[i], "-flimit-function-alignment") || + !strcmp(argv[i], "-ftree-loop-im") || + !strcmp(argv[i], "-fno-instrument-functions") || + !strcmp(argv[i], "-fstack-clash-protection") || + !strcmp(argv[i], "-mfpmath=sse+387") || + !strcmp(argv[i], "-Wa,--noexecstack") || + !strcmp(argv[i], "-freg-struct-return") || + !strcmp(argv[i], "-mcall-ms2sysv-xlogues") || + startswith(argv[i], "-ffixed-") || + startswith(argv[i], "-fcall-saved") || + startswith(argv[i], "-fcall-used") || + startswith(argv[i], "-fgcse-") || + strstr(argv[i], "shrink-wrap") || + strstr(argv[i], "schedule-insns2") || + startswith(argv[i], "-fvect-cost-model=") || + startswith(argv[i], "-fsimd-cost-model=") || + startswith(argv[i], "-fopt-info") || + startswith(argv[i], "-mstringop-strategy=") || + startswith(argv[i], "-mpreferred-stack-boundary=") || + strstr(argv[i], "gnu-unique") || + startswith(argv[i], "-Wframe-larger-than=") || + strstr(argv[i], "whole-program") || + startswith(argv[i], "-Wa,--size-check=") || + startswith(argv[i], "-Wa,--listing"))) { + /* ignore flag so clang won't whine */ + } else { + AddFlag(argv[i]); + } + } + + if (iscc) { + if (isclang) { + AddFlag("-fno-integrated-as"); + AddFlag("-Wno-unused-command-line-argument"); + AddFlag("-Wno-incompatible-pointer-types-discards-qualifiers"); + } + AddFlag("-no-canonical-prefixes"); + if (!IsTerminalInarticulate()) { + AddFlag(firstnonnull(colorflag, "-fdiagnostics-color=always")); + } + if (wantpg && !wantnopg) { + AddFlag("-pg"); + AddFlag("-D__PG__"); + if (wantnop && !isclang) { + AddFlag("-mnop-mcount"); + AddFlag("-D__MNOP_MCOUNT__"); + } + if (wantrecord) { + AddFlag("-mrecord-mcount"); + AddFlag("-D__MRECORD_MCOUNT__"); + } + if (wantfentry) { + AddFlag("-mfentry"); + AddFlag("-D__MFENTRY__"); + } + } + if (wantasan) { + AddFlag("-fsanitize=address"); + AddFlag("-D__FSANITIZE_ADDRESS__"); + } + if (wantubsan) { + AddFlag("-fsanitize=undefined"); + AddFlag("-fno-data-sections"); + } + } + + AddFlag(NULL); + + if (outpath) { + outdir = xdirname(outpath); + if (!isdirectory(outdir)) { + makedirs(outdir, 0755); + } + } + + write(2, command.p, command.n); + + sigfillset(&mask); + sigprocmask(SIG_BLOCK, &mask, &savemask); + if ((pid = vfork()) == -1) exit(errno); + if (!pid) { + sigprocmask(SIG_SETMASK, &savemask, NULL); + execv(cc, flags.p); + _exit(127); + } + while (waitpid(pid, &ws, 0) == -1) { + if (errno != EINTR) exit(errno); + } + + if (WIFEXITED(ws)) { + return WEXITSTATUS(ws); + } else { + return 128 + WTERMSIG(ws); + } +} diff --git a/tool/emacs/cosmo-stuff.el b/tool/emacs/cosmo-stuff.el index eeb77c7cc..b8e8acd58 100644 --- a/tool/emacs/cosmo-stuff.el +++ b/tool/emacs/cosmo-stuff.el @@ -174,7 +174,7 @@ (runs (format "o/$m/%s.com.runs TESTARGS=-b" name)) (buns (format "o/$m/test/%s_test.com.runs TESTARGS=-b" name))) (cond ((not (member ext '("c" "cc" "s" "S" "rl" "f"))) - (format "m=%s; make -j8 -O MODE=$m SILENT=0 o/$m/%s" + (format "m=%s; make -j8 -O MODE=$m V=1 o/$m/%s" mode (directory-file-name (file-name-directory @@ -187,7 +187,7 @@ (file-exists-p (format "%s" buddy))) (format (cosmo-join " && " - '("m=%s; n=%s; make -j8 -O o/$m/$n%s.o MODE=$m SILENT=0" + '("m=%s; n=%s; make -j8 -O o/$m/$n%s.o MODE=$m V=1" ;; "bloat o/$m/%s.o | head" ;; "nm -C --size o/$m/%s.o | sort -r" "echo" @@ -199,7 +199,7 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s.com" - ,(concat "make -j8 -O $f MODE=$m SILENT=0") + ,(concat "make -j8 -O $f MODE=$m V=1") "./$f")) mode name)) ((and (file-regular-p this) @@ -210,7 +210,7 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s%s.o" - ,(concat "make -j8 -O $f MODE=$m SILENT=0") + ,(concat "make -j8 -O $f MODE=$m V=1") ;; "nm -C --size $f | sort -r" "echo" "size -A $f | grep '^[.T]' | grep -v 'debug\\|command.line\\|stack' | sort -rnk2" @@ -419,7 +419,7 @@ (error "don't know how to show assembly for non c/c++ source file")) (let* ((default-directory root) (compile-command - (format "make %s SILENT=0 -j8 -O MODE=%s %s %s" + (format "make %s V=1 -j8 -O MODE=%s %s %s" (or extra-make-flags "") mode asm-gcc asm-clang))) (save-buffer) (set-visited-file-modtime (current-time)) @@ -440,8 +440,8 @@ ;; -ffast-math -funsafe-math-optimizations -fsched2-use-superblocks -fjump-tables (cond ((not (eq 0 (logand 8 arg))) (cosmo--assembly (setq arg (logand (lognot 8))) - "SILENT=0 OVERRIDE_COPTS='-fverbose-asm -fsanitize=address'")) - (t (cosmo--assembly arg "SILENT=0 OVERRIDE_COPTS='' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'")))) + "V=1 OVERRIDE_COPTS='-fverbose-asm -fsanitize=address'")) + (t (cosmo--assembly arg "V=1 OVERRIDE_COPTS='' CPPFLAGS='-DSTACK_FRAME_UNLIMITED'")))) (defun cosmo-assembly-native (arg) (interactive "P") @@ -449,11 +449,11 @@ (cond ((not (eq 0 (logand 8 arg))) (cosmo--assembly (setq arg (logand (lognot 8))) - "SILENT=0 CCFLAGS=--verbose COPTS='$(IEEE_MATH)' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")) ;; znver2 + "V=1 CCFLAGS=--verbose COPTS='$(IEEE_MATH)' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")) ;; znver2 (t (cosmo--assembly arg - "SILENT=0 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")))) ;; znver2 + "V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=k8'")))) ;; znver2 (defun cosmo-assembly-icelake (arg) (interactive "P") @@ -461,15 +461,15 @@ (cond ((not (eq 0 (logand 8 arg))) (cosmo--assembly (setq arg (logand (lognot 8))) - "SILENT=0 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'")) + "V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'")) (t (cosmo--assembly arg - "SILENT=0 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'")))) + "V=1 CCFLAGS=--verbose COPTS='$(MATHEMATICAL) -O3' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' TARGET_ARCH='-march=icelake-client'")))) (defun cosmo-assembly-balanced (arg) (interactive "P") - (cosmo--assembly (or arg 5) "CFLAGS='-O2 -ftrapv' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' SILENT=0")) + (cosmo--assembly (or arg 5) "CFLAGS='-O2 -ftrapv' CPPFLAGS='-DSTACK_FRAME_UNLIMITED' V=1")) (defun cosmo-mca (arg) (interactive "P") diff --git a/tool/viz/bf.c b/tool/viz/bf.c new file mode 100644 index 000000000..5ead78f6d --- /dev/null +++ b/tool/viz/bf.c @@ -0,0 +1,104 @@ +/*-*- 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/calls.h" +#include "libc/fmt/itoa.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/str/tpenc.h" +#include "libc/sysv/consts/o.h" + +/** + * @fileoverview BingFold - A Hexdump Tool + */ + +#define W 64 +#define C 253 + +void bf(int fd) { + ssize_t rc; + uint64_t w; + int c, fg, fg2; + size_t i, n, o; + char ibuf[W], obuf[12 + 1 + W * 6 + 1 + W * (2 + 11) + 11 + 1]; + o = 0; + do { + if ((rc = read(fd, ibuf, W)) == -1) exit(2); + if (rc) { + n = 0; + n += uint64toarray_fixed16(o, obuf + n, 48); + o += rc; + obuf[n++] = ' '; + for (i = 0; i < rc; ++i) { + c = ibuf[i] & 0xff; + w = tpenc(kCp437[c]); + do { + obuf[n++] = w; + } while ((w >>= 8)); + } + for (i = 0; i < W - rc + 1; ++i) { + obuf[n++] = ' '; + } + for (fg = -1, i = 0; i < rc; ++i) { + c = ibuf[i] & 0xff; + if (c < 32) { + fg2 = 237 + c * ((C - 237) / 32.); + } else if (c >= 232) { + fg2 = C + (c - 232) * ((255 - C) / (256. - 232)); + } else { + fg2 = C; + } + if (fg2 != fg) { + fg = fg2; + obuf[n++] = '\e'; + obuf[n++] = '['; + obuf[n++] = '3'; + obuf[n++] = '8'; + obuf[n++] = ';'; + obuf[n++] = '5'; + obuf[n++] = ';'; + n += int64toarray_radix10(o, obuf + n); + obuf[n++] = 'm'; + } + obuf[n++] = "0123456789abcdef"[c >> 4]; + obuf[n++] = "0123456789abcdef"[c & 15]; + /* obuf[n++] = ' '; */ + } + obuf[n++] = '\e'; + obuf[n++] = '['; + obuf[n++] = '0'; + obuf[n++] = 'm'; + obuf[n++] = '\n'; + write(1, obuf, n); + } + } while (rc == W); +} + +int main(int argc, char *argv[]) { + int i, fd; + if (argc > 1) { + for (i = 1; i < argc; ++i) { + if (i > 1) write(1, "\n", 1); + if ((fd = open(argv[i], O_RDONLY)) == -1) exit(1); + bf(fd); + } + } else { + bf(0); + } + return 0; +} diff --git a/tool/viz/lib/formatstringtable-testlib.h b/tool/viz/lib/formatstringtable-testlib.h index 62ee4f445..8fccae854 100644 --- a/tool/viz/lib/formatstringtable-testlib.h +++ b/tool/viz/lib/formatstringtable-testlib.h @@ -46,21 +46,23 @@ EXPECT_MATRIXEQ_(__FILE__, __LINE__, __FUNCTION__, YN, XN, M, #M, WANT, \ StringifyMatrixShort, NULL, NULL, NULL) -#define EXPECT_MATRIXEQ_(FILE, LINE, FUNC, YN, XN, M, MC, WANT, F, ...) \ - do { \ - char *Got; \ - const char *Want; \ - Want = (WANT); \ - Got = F(YN, XN, M, FormatStringTableForAssertion, __VA_ARGS__); \ - if (testlib_strequals(sizeof(char), Want, Got)) { \ - testlib_free(Got); \ - } else { \ - TESTLIB_ONFAIL(FILE, FUNC); \ - TESTLIB_SHOWERROR(testlib_showerror_expect_matrixeq, LINE, "...", MC, \ - testlib_formatstr(sizeof(char), Want, -1), \ - testlib_formatstr(sizeof(char), Got, -1), ""); \ - } \ +#define EXPECT_MATRIXEQ_(FILE, LINE, FUNC, YN, XN, M, MC, WANT, F, ...) \ + do { \ + char *Got; \ + const char *Want; \ + Want = (WANT); \ + Got = F(YN, XN, M, FormatStringTableForAssertion, __VA_ARGS__); \ + if (testlib_strequals(sizeof(char), Want, Got)) { \ + testlib_free(Got); \ + } else { \ + testlib_showerror_expect_matrixeq( \ + LINE, "...", MC, testlib_formatstr(sizeof(char), Want, -1), \ + testlib_formatstr(sizeof(char), Got, -1), ""); \ + } \ } while (0) +void testlib_showerror_expect_matrixeq(int, const char *, const char *, char *, + char *, const char *, ...); + #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_TOOL_VIZ_LIB_FORMATSTRINGTABLE_TESTLIB_H_ */