Compare commits

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

No files matched your search

-1
View File
@@ -8,7 +8,6 @@ AlwaysBreakBeforeMultilineStrings: false
AllowShortFunctionsOnASingleLine: false
KeepEmptyLinesAtTheStartOfBlocks: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
IncludeBlocks: Merge
---
Language: Cpp
AllowShortFunctionsOnASingleLine: false
+19 -23
View File
@@ -60,8 +60,8 @@
# build/config.mk
SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win10
MAKEFLAGS += --no-builtin-rules
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win10 xnu
MAKEFLAGS += -j --no-builtin-rules
.SUFFIXES:
.DELETE_ON_ERROR:
@@ -92,7 +92,6 @@ o/$(MODE): \
.UNVEIL = \
libc/integral \
libc/disclaimer.inc \
rwc:/dev/shm \
rx:build/bootstrap \
rx:o/third_party/gcc \
/proc/stat \
@@ -121,7 +120,6 @@ include libc/tinymath/tinymath.mk # │ You can issue raw system calls
include third_party/compiler_rt/compiler_rt.mk # │
include libc/str/str.mk # │
include third_party/xed/xed.mk # │
include third_party/puff/puff.mk # │
include third_party/zlib/zlib.mk # │
include third_party/double-conversion/dc.mk # │
include libc/elf/elf.mk # │
@@ -129,17 +127,16 @@ include ape/ape.mk # │
include libc/fmt/fmt.mk # │
include libc/vga/vga.mk #─┘
include libc/calls/calls.mk #─┐
include third_party/getopt/getopt.mk # │
include libc/runtime/runtime.mk # ├──SYSTEMS RUNTIME
include libc/crt/crt.mk # │ You can issue system calls
include third_party/nsync/nsync.mk # │
include third_party/dlmalloc/dlmalloc.mk #─┘
include libc/mem/mem.mk #─┐
include third_party/gdtoa/gdtoa.mk # ├──DYNAMIC RUNTIME
include third_party/nsync/mem/mem.mk # │ You can now use stdio
include libc/thread/thread.mk # │ You can finally call malloc()
include libc/zipos/zipos.mk # │
include libc/time/time.mk # │
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
include libc/time/time.mk # │ You can finally call malloc()
include third_party/nsync/mem/mem.mk # │
include libc/thread/thread.mk # │
include libc/stdio/stdio.mk # │
include third_party/libcxx/libcxx.mk # │
include net/net.mk # │
@@ -153,6 +150,7 @@ include dsp/mpeg/mpeg.mk # │
include dsp/dsp.mk # │
include third_party/zlib/gz/gz.mk # │
include third_party/musl/musl.mk # │
include third_party/getopt/getopt.mk # │
include libc/libc.mk #─┘
include libc/sock/sock.mk #─┐
include dsp/tty/tty.mk # ├──ONLINE RUNTIME
@@ -173,12 +171,9 @@ include third_party/maxmind/maxmind.mk
include net/finger/finger.mk
include third_party/double-conversion/test/test.mk
include third_party/lua/lua.mk
include third_party/tr/tr.mk
include third_party/sed/sed.mk
include third_party/awk/awk.mk
include third_party/hiredis/hiredis.mk
include third_party/make/make.mk
include third_party/ctags/ctags.mk
include third_party/finger/finger.mk
include third_party/argon2/argon2.mk
include third_party/smallz4/smallz4.mk
@@ -195,7 +190,6 @@ include third_party/python/python.mk
include tool/build/emucrt/emucrt.mk
include tool/build/emubin/emubin.mk
include tool/build/build.mk
include tool/curl/curl.mk
include examples/examples.mk
include examples/pyapp/pyapp.mk
include examples/pylife/pylife.mk
@@ -282,14 +276,14 @@ o/$(MODE)/hdrs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS
$(file >$@) $(foreach x,$(HDRS) $(INCS),$(file >>$@,$(x)))
TAGS: private .UNSANDBOXED = 1
TAGS: o/$(MODE)/srcs-old.txt $(SRCS) o/$(MODE)/third_party/ctags/ctags.com
TAGS: o/$(MODE)/srcs-old.txt $(SRCS)
@$(RM) $@
@o/$(MODE)/third_party/ctags/ctags.com $(TAGSFLAGS) -L $< -o $@
@$(TAGS) $(TAGSFLAGS) -L $< -o $@
HTAGS: private .UNSANDBOXED = 1
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS) o/$(MODE)/third_party/ctags/ctags.com
HTAGS: o/$(MODE)/hdrs-old.txt $(HDRS)
@$(RM) $@
@build/htags o/$(MODE)/third_party/ctags/ctags.com -L $< -o $@
@build/htags -L $< -o $@
loc: private .UNSANDBOXED = 1
loc: o/$(MODE)/tool/build/summy.com
@@ -310,6 +304,7 @@ COSMOPOLITAN_OBJECTS = \
LIBC_LOG \
LIBC_TIME \
LIBC_ZIPOS \
THIRD_PARTY_ZLIB \
THIRD_PARTY_MUSL \
LIBC_STDIO \
THIRD_PARTY_GDTOA \
@@ -335,7 +330,6 @@ COSMOPOLITAN_OBJECTS = \
LIBC_NT_ADVAPI32 \
LIBC_NT_SYNCHRONIZATION \
LIBC_FMT \
THIRD_PARTY_PUFF \
THIRD_PARTY_COMPILER_RT \
LIBC_TINYMATH \
THIRD_PARTY_XED \
@@ -375,9 +369,11 @@ COSMOPOLITAN_HEADERS = \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_MUSL \
THIRD_PARTY_ZLIB \
THIRD_PARTY_ZLIB_GZ \
THIRD_PARTY_REGEX
o/$(MODE)/cosmopolitan.a: \
o/$(MODE)/cosmopolitan.a: \
$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_A_OBJS))
o/cosmopolitan.h: \
@@ -440,9 +436,9 @@ $(SRCS):
$(HDRS):
$(INCS):
.DEFAULT:
@$(ECHO)
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@
@$(ECHO)
@$(ECHO) >&2
@$(ECHO) NOTE: deleting o/$(MODE)/depend because of an unspecified prerequisite: $@ >&2
@$(ECHO) >&2
$(RM) o/$(MODE)/depend
-include o/$(MODE)/depend
+6 -19
View File
@@ -23,8 +23,8 @@ If you're doing your development work on Linux or BSD then you need just
five files to get started. Here's what you do on Linux:
```sh
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.2.zip
unzip cosmopolitan-amalgamation-2.2.zip
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.1.1.zip
unzip cosmopolitan-amalgamation-2.1.1.zip
printf 'main() { printf("hello world\\n"); }\n' >hello.c
gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \
-fno-omit-frame-pointer -pg -mnop-mcount -mno-tls-direct-seg-refs -gdwarf-4 \
@@ -57,13 +57,9 @@ sudo sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/status'
Since we used the `ape-no-modify-self.o` bootloader (rather than
`ape.o`) your executable will not modify itself when it's run. What
it'll instead do, is extract a 4kb program (the [APE loader](https://justine.lol/apeloader/))
to `${TMPDIR:-${HOME:-.}}` that maps your program into memory without
needing to copy it. The APE loader must be in an executable location
(e.g. not stored on a `noexec` mount) for it to run. See below for
alternatives:
It's possible to install the APE loader systemwide as follows.
it'll instead do, is extract a 4kb program to `${TMPDIR:-${HOME:-.}}`
that maps your program into memory without needing to copy it. It's
possible to install the APE loader systemwide as follows.
```sh
# System-Wide APE Install
@@ -243,11 +239,6 @@ You normally run the `.com.dbg` file under gdb. If you need to debug the
gdb foo.com -ex 'add-symbol-file foo.com.dbg 0x401000'
```
## Discord Chatroom
The Cosmopolitan development team collaborates on the Redbean Discord
server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
## Support Vector
| Platform | Min Version | Circa |
@@ -255,16 +246,12 @@ server. You're welcome to join us! <https://discord.gg/FwAVVu7eJ4>
| AMD | K8 Venus | 2005 |
| Intel | Core | 2006 |
| Linux | 2.6.18 | 2007 |
| Windows | 8 [1] | 2012 |
| Windows | 8 | 2012 |
| Mac OS X | 15.6 | 2018 |
| OpenBSD | 6.4 | 2018 |
| FreeBSD | 13 | 2020 |
| NetBSD | 9.2 | 2021 |
[1] See our [vista branch](https://github.com/jart/cosmopolitan/tree/vista)
for a community supported version of Cosmopolitan that works on Windows
Vista and Windows 7.
## Special Thanks
Funding for this project is crowdsourced using
+73 -322
View File
@@ -35,7 +35,6 @@
#include "ape/macros.internal.h"
#include "ape/notice.inc"
#include "ape/relocations.h"
#include "libc/calls/metalfile.internal.h"
#include "libc/dce.h"
#include "libc/elf/def.h"
#include "libc/macho.internal.h"
@@ -113,33 +112,7 @@ cstr: .endobj cstr,globl,hidden # ←for gdb readability
//
// @param dl is drive number
// @noreturn
ape_mz:
#if SupportsWindows() || SupportsMetal()
.asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
// # in real mode
// dec %bp
// pop %dx
// jno 0x4a
// jo 0x4a
//
// # in legacy mode
// push %ebp
// pop %edx
// jno 0x4a
// jo 0x4a
//
// # 64-bit mode
// rex.WRB
// pop %r10
// jno 0x4a
// jo 0x4a
#else
// Avoid virus scanner reputation damage when targeting System Five.
.asciz "jartsr='\n" # Justine Alexandra Roberts Tunney
// push $0x61
// jb 0x78
// jae 0x78
#endif
ape_mz: .asciz "MZqFpD='\n" # Mark 'Zibo' Joseph Zbikowski
.short 0x1000 # MZ: lowers upper bound load / 16
.short 0xf800 # MZ: roll greed on bss
.short 0 # MZ: lower bound on stack segment
@@ -158,9 +131,6 @@ ape_mz:
.long RVA(ape_pe) # PE: the new technology
#else
.long 0
.org 0x78
pop %rax
jmp _start
#endif
.endfn ape_mz,globl,hidden
@@ -282,9 +252,6 @@ pc: cld
xor %dh,%dh # current head
mov $v_ape_realsectors,%di # total sectors
3: call pcread
mov %es,%si # addr += 512
add $512>>4,%si
mov %si,%es
dec %di
jnz 3b
6: ljmp $0,$REAL(realmodeloader)
@@ -373,7 +340,6 @@ dsknfo: push %bx
pop %ds
xchg %bx,%ax
stosw #→ pc_drive_type, pc_drive_last_sector
scasb
xchg %cx,%ax
stosw #→ pc_drive_last_cylinder
xchg %dx,%ax
@@ -412,6 +378,9 @@ pcread: push %ax
pop %cx
pop %ax
jc 9f
mov %es,%si # addr += 512
add $512>>4,%si
mov %si,%es
inc %al # ++sector
cmp mm+"struct mman::pc_drive_last_sector",%al
jbe 2f
@@ -581,9 +550,6 @@ ape_disk:
#if SupportsWindows() || SupportsMetal() || SupportsXnu()
apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
.ascii "m=\"$(uname -m)\"\n"
.ascii "if [ \"$m\" = x86_64 ] || [ \"$m\" = amd64 ]; then\n"
// Until all operating systems can be updated to support APE,
// we have a beautiful, yet imperfect workaround, which is to
// modify the binary to follow the local system's convention.
@@ -685,99 +651,17 @@ apesh: .ascii "\n@\n#'\"\n" # sixth edition shebang
.ascii "o=\"$t\"\n"
.ascii "exec \"$o\" \"$@\"\n"
#endif /* APE_NO_MODIFY_SELF */
.ascii "exit $?\n"
.ascii "R=$?\n"
.ascii "if [ \"$(uname -m)\" != x86_64 ]; then\n"
.ascii "Q=\"$(command -v qemu-x86_64)\" &&\n"
.ascii "exec \"$Q\" \"$o\" \"$@\"\n"
#ifndef APE_NO_MODIFY_SELF
.ascii "else\n" # means argv[0] was wrong
.ascii " exec \"$o\" \"$@\"\n" # so do a path resolution
#endif /* APE_NO_MODIFY_SELF */
.ascii "fi\n"
.ascii "PHDRS='' <<'@'\n"
.ascii "exit $R\n"
.endobj apesh
// elf program headers get inserted here
// because they need to be in the first 4096 bytes
.section .emush,"a",@progbits
emush: .ascii "\n@\n#'\"\n"
.ascii "s=\"$(uname -s)\"\n"
// our script is running on a non-x86_64 architecture
// 1. `dd` out the appropriate blink vm blob
// 2. gunzip the blink virtual machine executable
// 3. relaunch this program inside the blink vm
.ascii "o=\"$(command -v \"$0\")\"\n"
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-0.9.2\"\n"
// Blink for Apple Silicon, e.g. M1 Macbook
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-darwin-arm64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_darwin_arm64_b9
.byte blink_darwin_arm64_b8
.byte blink_darwin_arm64_b7
.byte blink_darwin_arm64_b6
.byte blink_darwin_arm64_b5
.byte blink_darwin_arm64_b4
.byte blink_darwin_arm64_b3
.byte blink_darwin_arm64_b2
.byte blink_darwin_arm64_b1
.byte blink_darwin_arm64_b0
.ascii ")) count=$(("
.byte blink_darwin_arm64_size_b9
.byte blink_darwin_arm64_size_b8
.byte blink_darwin_arm64_size_b7
.byte blink_darwin_arm64_size_b6
.byte blink_darwin_arm64_size_b5
.byte blink_darwin_arm64_size_b4
.byte blink_darwin_arm64_size_b3
.byte blink_darwin_arm64_size_b2
.byte blink_darwin_arm64_size_b1
.byte blink_darwin_arm64_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
// Blink for Aarch64 Linux, e.g. Raspberry Pi
.ascii "if [ \"$s\" = Linux ]; then\n"
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
.ascii "if ! [ -x \"$e\" ]; then\n"
.ascii "echo \"extracting blink-aarch64 to ${e}\" >&2\n"
.ascii "dd if=\"$o\" bs=1 skip=$(("
.byte blink_aarch64_b9
.byte blink_aarch64_b8
.byte blink_aarch64_b7
.byte blink_aarch64_b6
.byte blink_aarch64_b5
.byte blink_aarch64_b4
.byte blink_aarch64_b3
.byte blink_aarch64_b2
.byte blink_aarch64_b1
.byte blink_aarch64_b0
.ascii ")) count=$(("
.byte blink_aarch64_size_b9
.byte blink_aarch64_size_b8
.byte blink_aarch64_size_b7
.byte blink_aarch64_size_b6
.byte blink_aarch64_size_b5
.byte blink_aarch64_size_b4
.byte blink_aarch64_size_b3
.byte blink_aarch64_size_b2
.byte blink_aarch64_size_b1
.byte blink_aarch64_size_b0
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
.ascii "mv -f \"$e.$$\" \"$e\"\n"
.ascii "chmod +x \"$e\"\n"
.ascii "fi\n"
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
.ascii "fi\n"
.ascii "fi\n"
.ascii "echo unsupported architecture >&2\n"
.rept 16
.ascii "exit 127\n"
.endr
.ascii "exit 1\n"
.endobj emush
#ifdef APE_LOADER
.section .ape.loader,"a",@progbits
.align 64
@@ -1197,42 +1081,6 @@ ape_idata_idt:
ape_idata_idtend:
.previous
.section .piro.data.sort.metal_gdt,"aw",@progbits
.align 8
_gdt:
// ┌G:granularity (1 → limit *= 0x1000)
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
// ││┌L:long mode
// │││┌AVL:this bit is thine (1<<52)
// ││││ ┌P:present
// ││││ │┌DPL:privilege
// ││││ ││ ┌─────────data/code(1)
// ││││ ││ │┌────data(0)──────code(1)
// ││││ ││ ││┌───conforming───expand-down
// ││││ ││ │││┌──writeable────readable
// ││││ ││ ││││┌─accessed─────accessed
// ││││ ││ │││││
// ││││ ┌──││─│││││───────────────────────────────┐
// ┌───││││─│──││─│││││───────────┐ │
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
// │ ││││││ ││││││││││ base address││ segment limit│
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
// │ ││││││ ││││││││││ ││ │
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
// │ ││││││ ││││││││││ ││ │
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
_gdt_end:
.endobj _gdt,global,hidden
.previous
.section .piro.data.sort.iat.1,"aw",@progbits
.type ape_idata_iatend,@object
.type ape_idata_iat,@object
@@ -1290,21 +1138,48 @@ sconf: .short 1843200/*hz*/ / 16/*wut*/ / 9600/*baud*/
// Global Descriptor Table
.align 8
_gdtrlo:
.short 2f-_gdtlo-1 # table byte length
.long REAL(_gdtlo) # table address (base memory space)
.endobj _gdtrlo,global,hidden
_gdtrphy:
.short 2f-1f-1 # table byte length
.long REAL(1f) # table address (physical space)
.endobj _gdtrphy,global,hidden
_gdtr:
.short _gdt_end-_gdt-1 # table byte length
.quad _gdt # table address (final virtual space)
.short 2f-1f-1 # table byte length
.quad 1f # table address (final virtual space)
.endobj _gdtr,global,hidden
.align 8
// Partial GDT with descriptors for switching to unreal mode or long mode.
_gdtlo = .-GDT_LEGACY_DATA
_gdt:
1:
// ┌G:granularity (1 → limit *= 0x1000)
// │┌D/B:default operation size (0 = 16|64bit, 1 = 32-bit)
// ││┌L:long mode
// │││┌AVL:this bit is thine (1<<52)
// ││││ ┌P:present
// ││││ │┌DPL:privilege
// ││││ ││ ┌─────────data/code(1)
// ││││ ││ │┌────data(0)──────code(1)
// ││││ ││ ││┌───conforming───expand-down
// ││││ ││ │││┌──writeable────readable
// ││││ ││ ││││┌─accessed─────accessed
// ││││ ││ │││││
// ││││ ┌──││─│││││───────────────────────────────┐
// ┌───││││─│──││─│││││───────────┐ │
// ┌───┴──┐││││┌┴─┐│├┐│││││┌──────────┴───────────┐┌──────┴───────┐
// │ ││││││ ││││││││││ base address││ segment limit│
// │ ││││││ ││││││││││ 32 bits││ 20 bits│
// │ ││││││ ││││││││││ ││ │
// 6666555555555544444444443333333333222222222211111111110000000000
// 3210987654321098765432109876543210987654321098765432109876543210
// │ ││││││ ││││││││││ ││ │
.quad 0b0000000000000000000000000000000000000000000000000000000000000000 # 0
.quad 0b0000000000001111100110100000000000000000000000001111111111111111 # 8
.quad 0b0000000000001111100100100000000000000000000000001111111111111111 #16
.quad 0b0000000011001111100110100000000000000000000000001111111111111111 #24
.quad 0b0000000011001111100100100000000000000000000000001111111111111111 #32
.quad 0b0000000010101111100110110000000000000000000000001111111111111111 #40
.quad 0b0000000010101111100100110000000000000000000000001111111111111111 #48
.tssdescstub _tss #56,64
2:
.endobj _gdt,global,hidden
/*─────────────────────────────────────────────────────────────────────────────╗
│ αcτµαlly pδrταblε εxεcµταblε § real mode │
@@ -1312,7 +1187,6 @@ _gdtlo = .-GDT_LEGACY_DATA
the default mode of operation on modern cpus */
realmodeloader:
call lhinit
call rlinit
call sinit4
.optfn _start16
@@ -1320,25 +1194,6 @@ realmodeloader:
call longmodeloader
.endfn realmodeloader
// Prepares to later load parts of the program that are not loaded yet.
//
// @param al next sector number
// @param cx next cylinder number
// @param dh next head number
// @param dl drive number
// @clob ax, cx, es, di
lhinit: cmp $0x40,%dl
je 9f
pushpop 0,%es
mov $mm+"struct mman::pc_drive_next_sector",%di
cld
stosb #→ pc_drive_next_sector
xchg %ax,%cx
stosw #→ pc_drive_next_cylinder
mov %dh,%al
stosb #→ pc_drive_next_head
9: ret
.section .sort.text.real.init.1,"ax",@progbits
.type rlinit,@function
rlinit: .previous/*
@@ -1399,19 +1254,17 @@ longmodeloader:
call lcheck
call a20
call e820
call cpyhi
call loadhi
call pinit
call golong
.endfn longmodeloader
// Long Mode Hardware Check
lcheck: pushf # checks for i8086 / i8088 / i80186
pop %ax # see intel manual volume 1 §20.1.2
test $0x80,%ah
jnz 10f # we now assume 32 bit is supported
pushfl # now check for i386, or early i486
pop %eax # tests ability to change cpuid bit
lcheck: pushf # check for i8086 / i8088 / i80186
pop %ax
test $0x80,%ah # see intel manual volume 1 20.1.2
jnz 10f # we now assume 32bit is supported
pushfl # now check for i386 or early i486
pop %eax # test ability to change cpuid bit
mov %eax,%ecx
mov $1<<21,%ebx
xor %ebx,%eax
@@ -1424,16 +1277,16 @@ lcheck: pushf # checks for i8086 / i8088 / i80186
or %ebx,%eax # puts cpuid bit in the on position
push %eax
popfl
mov $0x80000000,%edi # get amd64 ext cpuid thingy length
mov $0x80000000,%edi # get amd ext cpuid thingy length
mov %edi,%eax
inc %edi
cpuid # leaf 0x80000000, clob ax/bx/cx/dx
cpuid # clobbers eax, ebx, ecx, and edx
cmp %edi,%eax
jl 10f
mov %edi,%eax
cpuid # leaf 0x80000001, clob ax/bx/cx/dx
mov $1<<29|1<<20,%edi # 29 = LM (long), 20 = NX (no exec)
and %edi,%edx # we need to both, or we won't work
cpuid
mov $1<<29|1<<20,%edi # need nexgen32e long mode support
and %edi,%edx # & nx support
cmp %edi,%edx
jne 10f
xor %ax,%ax
@@ -1543,88 +1396,10 @@ a20: cli
5: ret
.endfn a20
// Copies program pages loaded into base memory, to extended memory.
//
// @clob esi, edi
cpyhi: push %es
movpp %ds,%es
call unreal
mov $IMAGE_BASE_REAL,%esi
mov $IMAGE_BASE_PHYSICAL,%edi
mov $v_ape_realdwords,%ecx
cld
rep movsl %ds:(%esi),%es:(%edi)
sti
pop %es
ret
.endfn cpyhi
// Disables interrupts and switches to "unreal mode".
//
// @return ds, es have same base addresses as before but can access
// 4 GiB of memory
// @clob eax
unreal: push %ds
push %es
cli
lgdt REAL(_gdtrlo)
mov %cr0,%eax
or $CR0_PE,%al
mov %eax,%cr0
jmp 0f
0: pushpop GDT_LEGACY_DATA,%ds
movpp %ds,%es
and $~CR0_PE,%al
mov %eax,%cr0
jmp 1f
1: pop %es
pop %ds
ret
// Reads any remaining program pages into memory which have not yet
// been read by the boot sector.
//
// @clob eax, ecx, dx, esi, edi, bp
loadhi: mov $v_ape_highsectors,%bp
test %bp,%bp
jz 9f
mov $mm+"struct mman::pc_drive",%si
cld
lodsb #← pc_drive
xchg %ax,%dx
lodsw
lodsb #← pc_drive_next_sector
test %al,%al
jz 9f
xchg %ax,%cx
lodsw #← pc_drive_next_cylinder
xchg %ax,%cx
mov (%si),%dh #← pc_drive_next_head
push %es
#define SEG 0x79000
mov $IMAGE_BASE_PHYSICAL+v_ape_realbytes-SEG,%edi
push $SEG>>4
pop %es
0: call pcread
push %ax
call unreal
pop %ax
push %cx
xor %esi,%esi
xor %ecx,%ecx
mov $512/4,%cl
cld
rep movsl %es:(%esi),%es:(%edi)
sti
pop %cx
dec %bp
jnz 0b
pop %es
9: ret
// Initializes long mode paging.
pinit: push %ds
push %es
#define SEG 0x79000
mov $SEG>>4,%ax
mov %ax,%ds
mov %ax,%es
@@ -1665,7 +1440,7 @@ golong: cli
rdmsr
or $EFER_LME|EFER_SCE|EFER_NXE,%eax
wrmsr
lgdt REAL(_gdtrlo)
lgdt REAL(_gdtrphy)
mov %cr0,%eax
or $CR0_PE|CR0_PG|CR0_MP,%eax
and $~CR0_EM,%eax
@@ -1675,9 +1450,7 @@ golong: cli
// Long mode is long.
.code64
long: movabs $BANE+PHYSICAL(0f),%rax
jmp *%rax
0: xor %eax,%eax
long: xor %eax,%eax
mov $GDT_LONG_DATA,%al
mov %eax,%ds
mov %eax,%ss
@@ -1685,16 +1458,18 @@ long: movabs $BANE+PHYSICAL(0f),%rax
mov %eax,%fs
mov %eax,%gs
mov $0x80000,%esp
mov $GDT_LONG_TSS,%al
ltr %ax
xor %r12d,%r12d
xor %r13d,%r13d
xor %r14d,%r14d
xor %r15d,%r15d
xor %ebx,%ebx
xor %ebp,%ebp
push %rbp
mov $mm,%rdi
mov %cr3,%rsi
mov $IMAGE_BASE_PHYSICAL,%edx
lea v_ape_allbytes(%rdx),%ecx
mov $IMAGE_BASE_REAL,%edx
call __map_phdrs
push $0x037f
fldcw (%rsp)
@@ -1780,25 +1555,21 @@ kernel: movabs $ape_stack_vaddr,%rsp
.byte 0x0f,0x1f,0207 # nop rdi binbase
.long (IMAGE_BASE_VIRTUAL-IMAGE_BASE_REAL)/512
#endif
movabs $BANE+mm,%rdi
mov $0x79000,%esi
mov $0x7f000,%edx
call __reclaim_boot_pages
push $_HOSTMETAL # sets __hostos in crt.S
pop %rcx
pushq .Lenv0(%rip) # envp[0][0]
push $0
mov %rsp,%rbp
pushq .Largv0+8(%rip) # argv[0][8]
pushq .Largv0(%rip) # argv[0][0]
mov %rsp,%rax
mov .Lenv0(%rip),%rax
mov %rax,(%rbp) # envp[0][0]
push $0 # argv[0][0]
push $0 # auxv[1][1]
push $0 # auxv[1][0]
push %rax # auxv[0][1]
push %rbp # auxv[0][1]
push $31 # auxv[0][0] AT_EXECFN
push $0 # envp[1]
push %rbp # envp[0]
push $.Lenv0 # envp[0]
push $0 # argv[1]
push %rax # argv[0]
push %rbp # argv[0]
push $1 # argc
xor %ebp,%ebp
xor %eax,%eax
@@ -1814,9 +1585,6 @@ kernel: movabs $ape_stack_vaddr,%rsp
.rodata
.Lenv0: .asciz "METAL=1"
.Largv0:
.asciz APE_COM_NAME
.org .Largv0+16
.previous
#endif /* SupportsMetal() */
@@ -1829,7 +1597,6 @@ kernel: movabs $ape_stack_vaddr,%rsp
.ldsvar _end
.ldsvar _etext
.ldsvar v_ape_realsectors
.ldsvar v_ape_realbytes
.ldsvar v_ape_highsectors
.ldsvar ape_idata_ro
.ldsvar ape_pad_rodata
@@ -1923,21 +1690,5 @@ __bss_start:
__bss_end:
.previous
.section .blink,"a",@progbits
.globl blink_aarch64_size
blink_aarch64:
.incbin "ape/blink-aarch64.gz"
.endobj blink_aarch64,globl
blink_aarch64_size = . - blink_aarch64
.previous
.section .blink,"a",@progbits
.globl blink_darwin_arm64_size
blink_darwin_arm64:
.incbin "ape/blink-darwin-arm64.gz"
.endobj blink_darwin_arm64,globl
blink_darwin_arm64_size = . - blink_darwin_arm64
.previous
.end

+32 -82
View File
@@ -216,8 +216,6 @@ SECTIONS {
KEEP(*(.elf.phdrs))
HIDDEN(ape_phdrs_end = .);
KEEP(*(.emush))
/* OpenBSD */
. = ALIGN(__SIZEOF_POINTER__);
HIDDEN(ape_note = .);
@@ -275,7 +273,6 @@ SECTIONS {
KEEP(*(.textwindowsprologue))
*(.text.windows)
KEEP(*(.textwindowsepilogue))
KEEP(*(.blink))
*(SORT_BY_ALIGNMENT(.text.modernity))
*(SORT_BY_ALIGNMENT(.text.modernity.*))
*(SORT_BY_ALIGNMENT(.text.hot))
@@ -352,29 +349,8 @@ SECTIONS {
HIDDEN(_etext = .);
PROVIDE_HIDDEN(etext = .);
/*END: Read Only Data (only needed for initialization) */
} :Rom
/* initialization image for thread-local storage, this is copied */
/* out to actual TLS areas at runtime, so just make it read-only */
.tdata . : {
_tdata_start = .;
*(SORT_BY_ALIGNMENT(.tdata))
*(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .;
. = ALIGN(PAGESIZE);
} :Tls :Rom
/*END: Read Only Data */
/* this only tells the linker about the layout of uninitialized */
/* TLS data, and does not advance the linker's location counter */
.tbss . : {
_tbss_start = .;
*(SORT_BY_ALIGNMENT(.tbss))
*(SORT_BY_ALIGNMENT(.tbss.*))
. = ALIGN(TLS_ALIGNMENT);
/* the %fs register is based on this location */
_tbss_end = .;
} :Tls
} :Rom
.data ALIGN(PAGESIZE) : {
/*BEGIN: Read/Write Data */
@@ -409,7 +385,26 @@ SECTIONS {
. = ALIGN(PAGESIZE);
} :Ram
.tdata . : {
_tdata_start = .;
*(SORT_BY_ALIGNMENT(.tdata))
*(SORT_BY_ALIGNMENT(.tdata.*))
_tdata_end = .;
. = ALIGN(PAGESIZE);
} :Tls :Ram
/*END: file content that's loaded by o/s */
/*BEGIN: bss memory void */
.tbss . : {
_tbss_start = .;
*(SORT_BY_ALIGNMENT(.tbss))
*(SORT_BY_ALIGNMENT(.tbss.*))
. = ALIGN(TLS_ALIGNMENT);
/* the %fs register is based on this location */
_tbss_end = .;
} :Tls
/*END: file content */
/*BEGIN: bss memory that's addressable */
@@ -514,7 +509,7 @@ HIDDEN(ape_rom_rva = RVA(ape_rom_vaddr));
HIDDEN(ape_ram_offset = ape_rom_offset + ape_rom_filesz);
HIDDEN(ape_ram_vaddr = ADDR(.data));
HIDDEN(ape_ram_paddr = LOADADDR(.data));
HIDDEN(ape_ram_filesz = SIZEOF(.data));
HIDDEN(ape_ram_filesz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_ram_memsz = ADDR(.bss) + SIZEOF(.bss) - ape_ram_vaddr);
HIDDEN(ape_ram_align = PAGESIZE);
HIDDEN(ape_ram_rva = RVA(ape_ram_vaddr));
@@ -538,16 +533,16 @@ HIDDEN(ape_note_align = __SIZEOF_POINTER__);
HIDDEN(ape_text_offset = ape_rom_offset + LOADADDR(.text) - ape_rom_paddr);
HIDDEN(ape_text_paddr = LOADADDR(.text));
HIDDEN(ape_text_vaddr = ADDR(.text));
HIDDEN(ape_text_filesz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_memsz = SIZEOF(.text) + SIZEOF(.tdata));
HIDDEN(ape_text_filesz = SIZEOF(.text));
HIDDEN(ape_text_memsz = SIZEOF(.text));
HIDDEN(ape_text_align = PAGESIZE);
HIDDEN(ape_text_rva = RVA(ape_text_vaddr));
HIDDEN(ape_data_offset = ape_ram_offset + LOADADDR(.data) - ape_ram_paddr);
HIDDEN(ape_data_paddr = LOADADDR(.data));
HIDDEN(ape_data_vaddr = ADDR(.data));
HIDDEN(ape_data_filesz = SIZEOF(.data));
HIDDEN(ape_data_memsz = SIZEOF(.data));
HIDDEN(ape_data_filesz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_data_memsz = SIZEOF(.data) + SIZEOF(.tdata));
HIDDEN(ape_data_align = PAGESIZE);
HIDDEN(ape_data_rva = RVA(ape_data_vaddr));
@@ -567,58 +562,13 @@ SHSTUB2(ape_loader_dd_count,
? ROUNDUP(ape_loader_end - ape_loader, PAGESIZE) / 64
: 0);
HIDDEN(blink_aarch64_b0 = RVA(blink_aarch64) % 10 + 48);
HIDDEN(blink_aarch64_b1 = RVA(blink_aarch64) < 10 ? 32 : RVA(blink_aarch64) / 10 % 10 + 48);
HIDDEN(blink_aarch64_b2 = RVA(blink_aarch64) < 100 ? 32 : RVA(blink_aarch64) / 100 % 10 + 48);
HIDDEN(blink_aarch64_b3 = RVA(blink_aarch64) < 1000 ? 32 : RVA(blink_aarch64) / 1000 % 10 + 48);
HIDDEN(blink_aarch64_b4 = RVA(blink_aarch64) < 10000 ? 32 : RVA(blink_aarch64) / 10000 % 10 + 48);
HIDDEN(blink_aarch64_b5 = RVA(blink_aarch64) < 100000 ? 32 : RVA(blink_aarch64) / 100000 % 10 + 48);
HIDDEN(blink_aarch64_b6 = RVA(blink_aarch64) < 1000000 ? 32 : RVA(blink_aarch64) / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_b7 = RVA(blink_aarch64) < 10000000 ? 32 : RVA(blink_aarch64) / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_b8 = RVA(blink_aarch64) < 100000000 ? 32 : RVA(blink_aarch64) / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_b9 = RVA(blink_aarch64) < 1000000000 ? 32 : RVA(blink_aarch64) / 1000000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b0 = blink_aarch64_size % 10 + 48);
HIDDEN(blink_aarch64_size_b1 = blink_aarch64_size < 10 ? 32 : blink_aarch64_size / 10 % 10 + 48);
HIDDEN(blink_aarch64_size_b2 = blink_aarch64_size < 100 ? 32 : blink_aarch64_size / 100 % 10 + 48);
HIDDEN(blink_aarch64_size_b3 = blink_aarch64_size < 1000 ? 32 : blink_aarch64_size / 1000 % 10 + 48);
HIDDEN(blink_aarch64_size_b4 = blink_aarch64_size < 10000 ? 32 : blink_aarch64_size / 10000 % 10 + 48);
HIDDEN(blink_aarch64_size_b5 = blink_aarch64_size < 100000 ? 32 : blink_aarch64_size / 100000 % 10 + 48);
HIDDEN(blink_aarch64_size_b6 = blink_aarch64_size < 1000000 ? 32 : blink_aarch64_size / 1000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b7 = blink_aarch64_size < 10000000 ? 32 : blink_aarch64_size / 10000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b8 = blink_aarch64_size < 100000000 ? 32 : blink_aarch64_size / 100000000 % 10 + 48);
HIDDEN(blink_aarch64_size_b9 = blink_aarch64_size < 1000000000 ? 32 : blink_aarch64_size / 1000000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b0 = RVA(blink_darwin_arm64) % 10 + 48);
HIDDEN(blink_darwin_arm64_b1 = RVA(blink_darwin_arm64) < 10 ? 32 : RVA(blink_darwin_arm64) / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_b2 = RVA(blink_darwin_arm64) < 100 ? 32 : RVA(blink_darwin_arm64) / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_b3 = RVA(blink_darwin_arm64) < 1000 ? 32 : RVA(blink_darwin_arm64) / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b4 = RVA(blink_darwin_arm64) < 10000 ? 32 : RVA(blink_darwin_arm64) / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b5 = RVA(blink_darwin_arm64) < 100000 ? 32 : RVA(blink_darwin_arm64) / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b6 = RVA(blink_darwin_arm64) < 1000000 ? 32 : RVA(blink_darwin_arm64) / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b7 = RVA(blink_darwin_arm64) < 10000000 ? 32 : RVA(blink_darwin_arm64) / 10000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b8 = RVA(blink_darwin_arm64) < 100000000 ? 32 : RVA(blink_darwin_arm64) / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_b9 = RVA(blink_darwin_arm64) < 1000000000 ? 32 : RVA(blink_darwin_arm64) / 1000000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b0 = blink_darwin_arm64_size % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b1 = blink_darwin_arm64_size < 10 ? 32 : blink_darwin_arm64_size / 10 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b2 = blink_darwin_arm64_size < 100 ? 32 : blink_darwin_arm64_size / 100 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b3 = blink_darwin_arm64_size < 1000 ? 32 : blink_darwin_arm64_size / 1000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b4 = blink_darwin_arm64_size < 10000 ? 32 : blink_darwin_arm64_size / 10000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b5 = blink_darwin_arm64_size < 100000 ? 32 : blink_darwin_arm64_size / 100000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b6 = blink_darwin_arm64_size < 1000000 ? 32 : blink_darwin_arm64_size / 1000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b7 = blink_darwin_arm64_size < 10000000 ? 32 : blink_darwin_arm64_size / 10000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b8 = blink_darwin_arm64_size < 100000000 ? 32 : blink_darwin_arm64_size / 100000000 % 10 + 48);
HIDDEN(blink_darwin_arm64_size_b9 = blink_darwin_arm64_size < 1000000000 ? 32 : blink_darwin_arm64_size / 1000000000 % 10 + 48);
#if SupportsMetal()
HIDDEN(v_ape_realsectors =
MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512);
HIDDEN(v_ape_realbytes = v_ape_realsectors * 512);
HIDDEN(v_ape_realdwords = v_ape_realsectors * (512 / 4));
HIDDEN(v_ape_allsectors = ROUNDUP(RVA(_ezip), 512) / 512);
HIDDEN(v_ape_allbytes = v_ape_allsectors * 512);
HIDDEN(v_ape_highsectors = MIN(0xffff, v_ape_allsectors - v_ape_realsectors));
MIN(0x70000 - IMAGE_BASE_REAL,
ROUNDUP(RVA(_edata), 512)) / 512);
HIDDEN(v_ape_realpages = v_ape_realsectors / (4096 / 512));
HIDDEN(v_ape_highsectors =
(ROUNDUP(RVA(_edata), 512) / 512) - v_ape_realsectors);
TSSDESCSTUB2(_tss, _tss, _tss_end ? _tss_end - _tss - 1 : 0);
#endif
@@ -701,7 +651,7 @@ CHURN(ADDR(.bss));
CHURN(_start);
CHURN(ape_phdrs);
#if SupportsMetal()
CHURN(v_ape_allsectors);
CHURN(v_ape_realsectors);
#endif
#if SupportsXnu()
CHURN(ape_macho);
@@ -765,7 +715,7 @@ ASSERT(IS2POW(ape_stack_memsz),
"ape_stack_memsz must be a two power");
ASSERT(ape_stack_vaddr % ape_stack_memsz == 0,
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 & -ape_stack_memsz);");
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000040000 - ape_stack_memsz);");
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
+1 -11
View File
@@ -96,10 +96,6 @@ o/ape/idata.inc: \
ape/idata.internal.h \
ape/relocations.h
o/$(MODE)/ape/ape.o: \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
o/$(MODE)/ape/ape-no-modify-self.o: \
ape/ape.S \
ape/macros.internal.h \
@@ -111,7 +107,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/macho.internal.h \
libc/macros.internal.h \
libc/nexgen32e/uart.internal.h \
libc/calls/metalfile.internal.h \
libc/nexgen32e/vidya.internal.h \
libc/nt/pedef.internal.h \
libc/runtime/e820.internal.h \
@@ -119,8 +114,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz \
o/$(MODE)/ape/ape.elf
@$(COMPILE) \
-AOBJECTIFY.S \
@@ -140,16 +133,13 @@ o/$(MODE)/ape/ape-copy-self.o: \
libc/macho.internal.h \
libc/macros.internal.h \
libc/nexgen32e/uart.internal.h \
libc/calls/metalfile.internal.h \
libc/nexgen32e/vidya.internal.h \
libc/nt/pedef.internal.h \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/symbolic.h \
libc/sysv/consts/prot.h \
ape/blink-aarch64.gz \
ape/blink-darwin-arm64.gz
libc/sysv/consts/prot.h
@$(COMPILE) \
-AOBJECTIFY.S \
$(OBJECTIFY.S) \
+1 -3
View File
@@ -1,6 +1,6 @@
#!/bin/sh
if [ "$(id -u)" -eq 0 ]; then
if [ $UID -eq 0 ]; then
SUDO=
else
SUDO=sudo
@@ -97,8 +97,6 @@ if [ x"$(uname -s)" = xLinux ]; then
echo you may need to edit configs to persist across reboot >&2
echo '$SUDO sh -c "echo '"'"':APE:M::MZqFpD::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE:M::MZqFpD::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo '$SUDO sh -c "echo '"'"':APE-jart:M::jartsr::/usr/bin/ape:'"'"' >/proc/sys/fs/binfmt_misc/register"' >&2
$SUDO sh -c "echo ':APE-jart:M::jartsr::/usr/bin/ape:' >/proc/sys/fs/binfmt_misc/register" || exit
echo done >&2
if [ x"$(cat /proc/sys/fs/binfmt_misc/status)" = xdisabled ]; then
+6 -8
View File
@@ -8,19 +8,17 @@ fi
{
echo
echo "APE Uninstaller intends to run (in pseudo-shell)"
echo "APE Uninstaller intends to run"
echo
echo " sudo echo -1 into /proc/sys/fs/binfmt_misc/APE*"
echo " sudo rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo " $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE'"
echo " $SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape"
echo
echo "You may then use ape/apeinstall.sh to reinstall it"
echo
} >&2
set -ex
for f in /proc/sys/fs/binfmt_misc/APE*; do
if [ -f $f ]; then
$SUDO sh -c "echo -1 >$f" || exit
fi
done
if [ -f /proc/sys/fs/binfmt_misc/APE ]; then
$SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit
fi
$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit
Binary file not shown.
Binary file not shown.
-34
View File
@@ -1,34 +0,0 @@
#ifndef COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
#define COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern unsigned char _base[];
extern unsigned char _ehead[];
extern unsigned char _etext[];
extern unsigned char _edata[];
extern unsigned char _ezip[];
extern unsigned char _end[];
extern unsigned char _ereal[];
extern unsigned char _tdata_start[];
extern unsigned char _tdata_end[];
extern unsigned char _tbss_start[];
extern unsigned char _tbss_end[];
extern unsigned char __privileged_start[];
extern unsigned char __privileged_addr[];
extern unsigned char __privileged_size[];
extern unsigned char __privileged_end[];
extern unsigned char __test_start[];
extern unsigned char __ro[];
extern unsigned char *__relo_start[];
extern unsigned char *__relo_end[];
extern uint8_t __zip_start[];
extern uint8_t __zip_end[];
extern uint8_t __data_start[];
extern uint8_t __data_end[];
extern uint8_t __bss_start[];
extern uint8_t __bss_end[];
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_APE_SECTIONS_INTERNAL_H_ */
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6 -27
View File
@@ -29,7 +29,7 @@ endif
#
ifeq ($(MODE),fastbuild)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O
CONFIG_CPPFLAGS += -DSYSDEBUG -DDWARFLESS
CONFIG_CPPFLAGS += -DSYSDEBUG
CONFIG_OFLAGS += -g0
CONFIG_LDFLAGS += -S
TARGET_ARCH ?= -msse3
@@ -125,22 +125,6 @@ TARGET_ARCH ?= -msse3
OVERRIDE_CCFLAGS += -fno-pie
endif
# System Five Mode
#
# - `make MODE=sysv`
# - Optimized
# - Backtraces
# - Debuggable
# - Syscall tracing
# - Function tracing
# - No Windows bloat!
#
ifeq ($(MODE), sysv)
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
TARGET_ARCH ?= -msse3
endif
# Tiny Mode
#
# - `make MODE=tiny`
@@ -167,8 +151,7 @@ CONFIG_CCFLAGS += \
-fschedule-insns2 \
-fomit-frame-pointer \
-momit-leaf-frame-pointer \
-foptimize-sibling-calls \
-DDWARFLESS
-foptimize-sibling-calls
CONFIG_OFLAGS += \
-g0
CONFIG_LDFLAGS += \
@@ -198,8 +181,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=1 \
-DDWARFLESS
-DSUPPORT_VECTOR=1
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
@@ -235,8 +217,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=113 \
-DDWARFLESS
-DSUPPORT_VECTOR=113
DEFAULT_COPTS += \
-mred-zone
CONFIG_OFLAGS += \
@@ -271,8 +252,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=121 \
-DDWARFLESS
-DSUPPORT_VECTOR=121
DEFAULT_COPTS += \
-mred-zone
CONFIG_CCFLAGS += \
@@ -307,8 +287,7 @@ CONFIG_CPPFLAGS += \
-DTINY \
-DNDEBUG \
-DTRUSTWORTHY \
-DSUPPORT_VECTOR=251 \
-DDWARFLESS
-DSUPPORT_VECTOR=251
CONFIG_CCFLAGS += \
-Os \
-fno-align-functions \
+1
View File
@@ -45,6 +45,7 @@
LC_ALL = C
SOURCE_DATE_EPOCH = 0
TAGS ?= /usr/bin/ctags # emacs source builds or something breaks it
ARFLAGS = rcsD
ZFLAGS ?=
XARGS ?= xargs -P4 -rs8000
+1 -4
View File
@@ -43,9 +43,6 @@
# '(progn
# (add-hook 'c-mode-common-hook 'jart-c-mode-common-hook)))
TAGS="$1"
shift
# ctags doesn't understand atomics, e.g.
# extern char **environ;
set -- --regex-c='/_Atomic(\([^)]*\))/\1/b' "$@"
@@ -66,7 +63,7 @@ set -- --regex-c='/^extern [^(]*(\*const \([^)]*\))(/\1/b' "$@"
# struct WorstSoftwareEver;
set -- --regex-c='/^struct.*;$/uehocruehcroue/b' "$@"
exec $TAGS \
exec ${TAGS:-ctags} \
-e \
--langmap=c:.c.h \
--exclude=libc/nt/struct/imagefileheader.internal.h \
+3 -9
View File
@@ -7,12 +7,12 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/dce.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/kprintf.h"
#include "libc/dce.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
/**
@@ -59,15 +59,9 @@
int main(int argc, char *argv[]) {
if (!IsAsan()) {
kprintf("this example is intended for MODE=asan or MODE=dbg\n");
printf("this example is intended for MODE=asan or MODE=dbg\n");
exit(1);
}
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
char *buffer;
ShowCrashReports(); /* not needed but yoinks appropriate symbols */
buffer = malloc(13);
+7 -7
View File
@@ -20,22 +20,22 @@ int main(int argc, char *argv[]) {
volatile unsigned long x;
struct timespec now, start, next, interval;
printf("hammering the cpu...\n");
next = start = timespec_mono();
interval = timespec_frommillis(500);
next = timespec_add(next, interval);
next = start = _timespec_mono();
interval = _timespec_frommillis(500);
next = _timespec_add(next, interval);
for (;;) {
for (i = 0;; ++i) {
x *= 7;
if (!(i % 256)) {
now = timespec_mono();
if (timespec_cmp(now, next) >= 0) {
now = _timespec_mono();
if (_timespec_gte(now, next)) {
break;
}
}
}
next = timespec_add(next, interval);
next = _timespec_add(next, interval);
printf("consumed %10g seconds monotonic time and %10g seconds cpu time\n",
timespec_tonanos(timespec_sub(now, start)) / 1000000000.,
_timespec_tonanos(_timespec_sub(now, start)) / 1000000000.,
(double)clock() / CLOCKS_PER_SEC);
}
}
+1 -3
View File
@@ -28,7 +28,7 @@ void show(int clock) {
}
shown[n++] = clock;
if (clock_getres(clock, &ts) != -1) {
kprintf("%s %'ld ns\n", DescribeClockName(clock), timespec_tonanos(ts));
kprintf("%s %'ld ns\n", DescribeClockName(clock), _timespec_tonanos(ts));
} else {
kprintf("%s %s\n", DescribeClockName(clock), _strerrno(errno));
}
@@ -38,12 +38,10 @@ int main(int argc, char *argv[]) {
show(CLOCK_REALTIME);
show(CLOCK_REALTIME_FAST);
show(CLOCK_REALTIME_PRECISE);
show(CLOCK_REALTIME_COARSE);
show(CLOCK_MONOTONIC);
show(CLOCK_MONOTONIC_RAW);
show(CLOCK_MONOTONIC_FAST);
show(CLOCK_MONOTONIC_PRECISE);
show(CLOCK_MONOTONIC_COARSE);
show(CLOCK_PROCESS_CPUTIME_ID);
show(CLOCK_THREAD_CPUTIME_ID);
show(CLOCK_PROF);
-7
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/runtime/symbols.internal.h"
@@ -25,12 +24,6 @@
*/
noubsan int main(int argc, char *argv[]) {
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
volatile int64_t x;
ShowCrashReports();
return 1 / (x = 0);
+13 -31
View File
@@ -52,10 +52,12 @@
#include "third_party/mbedtls/pk.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/mbedtls/ssl_ticket.h"
#include "tool/curl/cmd.h"
/**
* @fileoverview Downloads HTTP URL to stdout.
*
* make -j8 o//examples/curl.com
* o//examples/curl.com http://justine.lol/ape.html
*/
#define HasHeader(H) (!!msg.headers[H].a)
@@ -115,11 +117,11 @@ static int TlsRecv(void *c, unsigned char *p, size_t n, uint32_t o) {
}
static wontreturn void PrintUsage(FILE *f, int rc) {
fprintf(f, "usage: %s [-iksvV] URL\n", program_invocation_name);
fprintf(f, "usage: %s [-ksvV] URL\n", program_invocation_name);
exit(rc);
}
int _curl(int argc, char *argv[]) {
int main(int argc, char *argv[]) {
if (!NoDebug()) ShowCrashReports();
/*
@@ -130,13 +132,11 @@ int _curl(int argc, char *argv[]) {
size_t n;
char **p;
} headers = {0};
int method = 0;
int method = kHttpGet;
bool authmode = MBEDTLS_SSL_VERIFY_REQUIRED;
bool includeheaders = false;
const char *postdata = NULL;
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
__log_level = kLogWarn;
while ((opt = getopt(argc, argv, "qiksvVIX:H:A:d:")) != -1) {
while ((opt = getopt(argc, argv, "qksvVIX:H:A:")) != -1) {
switch (opt) {
case 's':
case 'q':
@@ -144,9 +144,6 @@ int _curl(int argc, char *argv[]) {
case 'v':
++__log_level;
break;
case 'i':
includeheaders = true;
break;
case 'I':
method = kHttpHead;
break;
@@ -157,9 +154,6 @@ int _curl(int argc, char *argv[]) {
headers.p = realloc(headers.p, ++headers.n * sizeof(*headers.p));
headers.p[headers.n - 1] = optarg;
break;
case 'd':
postdata = optarg;
break;
case 'X':
CHECK((method = GetHttpMethod(optarg, strlen(optarg))));
break;
@@ -230,29 +224,17 @@ int _curl(int argc, char *argv[]) {
/*
* Create HTTP message.
*/
if (!method) method = postdata ? kHttpPost : kHttpGet;
char *request = 0;
appendf(&request,
"%s %s HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Connection: close\r\n"
"User-Agent: %s\r\n",
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), agent);
bool senthost = false, sentcontenttype = false, sentcontentlength = false;
kHttpMethod[method], _gc(EncodeUrl(&url, 0)), host, port, agent);
for (int i = 0; i < headers.n; ++i) {
appendf(&request, "%s\r\n", headers.p[i]);
if (!strncasecmp("Host:", headers.p[i], 5)) senthost = true;
else if (!strncasecmp("Content-Type:", headers.p[i], 13)) sentcontenttype = true;
else if (!strncasecmp("Content-Length:", headers.p[i], 15)) sentcontentlength = true;
}
if (!senthost) appendf(&request, "Host: %s:%s\r\n", host, port);
if (postdata) {
if (!sentcontenttype) appends(&request, "Content-Type: application/x-www-form-urlencoded\r\n");
if (!sentcontentlength) appendf(&request, "Content-Length: %d\r\n", strlen(postdata));
}
appendf(&request, "\r\n");
if (postdata) appends(&request, postdata);
/*
* Setup crypto.
@@ -280,7 +262,7 @@ int _curl(int argc, char *argv[]) {
* Perform DNS lookup.
*/
struct addrinfo *addr;
struct addrinfo hints = {.ai_family = AF_UNSPEC,
struct addrinfo hints = {.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_NUMERICSERV};
@@ -362,10 +344,10 @@ int _curl(int argc, char *argv[]) {
i -= hdrlen;
break;
}
if (method == kHttpHead || includeheaders) {
if (method == kHttpHead) {
Write(p, hdrlen);
}
if (method == kHttpHead || msg.status == 204 || msg.status == 304) {
goto Finished;
} else if (msg.status == 204 || msg.status == 304) {
goto Finished;
}
if (HasHeader(kHttpTransferEncoding) &&
+1 -24
View File
@@ -49,12 +49,12 @@ EXAMPLES_DIRECTDEPS = \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_ADVAPI32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_KERNEL32 \
LIBC_NT_NTDLL \
LIBC_NT_USER32 \
LIBC_NT_WS2_32 \
LIBC_NT_ADVAPI32 \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
@@ -71,7 +71,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_ZIPOS \
NET_HTTP \
NET_HTTPS \
THIRD_PARTY_AWK \
THIRD_PARTY_COMPILER_RT \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_DOUBLECONVERSION \
@@ -80,15 +79,12 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_LIBCXX \
THIRD_PARTY_LINENOISE \
THIRD_PARTY_LUA \
THIRD_PARTY_HIREDIS \
THIRD_PARTY_MBEDTLS \
THIRD_PARTY_MUSL \
THIRD_PARTY_NSYNC \
THIRD_PARTY_NSYNC_MEM \
THIRD_PARTY_QUICKJS \
THIRD_PARTY_SED \
THIRD_PARTY_STB \
THIRD_PARTY_TR \
THIRD_PARTY_XED \
THIRD_PARTY_ZLIB \
TOOL_BUILD_LIB \
@@ -147,25 +143,6 @@ o/$(MODE)/examples/nesemu1.com.dbg: \
$(EXAMPLES_BOOTLOADER)
@$(APELINK)
# # force symtab.com to be a zip file, by pulling a zip asset into linkage
# # we wouldn't need to do this if we depended on functions like localtime
# o/$(MODE)/examples/symtab.com.dbg: \
# $(EXAMPLES_DEPS) \
# o/$(MODE)/examples/symtab.o \
# o/$(MODE)/examples/symtab.c.zip.o \
# o/$(MODE)/examples/examples.pkg \
# $(EXAMPLES_BOOTLOADER)
# @$(APELINK)
# modify .com so it can read the symbol table without needing the .com.dbg file
o/$(MODE)/examples/symtab.com: \
o/$(MODE)/examples/symtab.com.dbg \
o/$(MODE)/third_party/zip/zip.com \
o/$(MODE)/tool/build/symtab.com
@$(MAKE_OBJCOPY)
@$(MAKE_SYMTAB_CREATE)
@$(MAKE_SYMTAB_ZIP)
o/$(MODE)/examples/picol.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
-21
View File
@@ -1,21 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
int main(int argc, char *argv[]) {
char buf[256];
if (!getdomainname(buf, sizeof(buf))) {
printf("%s\n", buf);
return 0;
} else {
return 1;
}
}
-1
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "ape/sections.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/errno.h"
-55
View File
@@ -1,55 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/runtime/runtime.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "third_party/hiredis/hiredis.h"
/**
* @fileoverview Demo of using hiredis to connect to a Redis server
*/
int main(int argc, char *argv[]) {
if (argc < 3 || argc > 5) {
fprintf(stderr, "Usage: %s HOST PORT [KEY] [VALUE]\n", argv[0]);
exit(1);
}
bool setValue = (argc == 5), getValue = (argc == 4);
redisContext *c = redisConnect(argv[1], atoi(argv[2]));
if (c == NULL || c->err) {
if (c) {
fprintf(stderr, "Connection error: %s\n", c->errstr);
redisFree(c);
} else {
fputs("Failed to allocate redis context\n", stderr);
}
exit(1);
}
redisReply *reply;
if (!setValue && !getValue) {
reply = redisCommand(c, "PING");
printf("PING: %s\n", reply->str);
} else if (setValue) {
reply = redisCommand(c, "SET %s %s", argv[3], argv[4]);
printf("SET: %s\n", reply->str);
} else {
reply = redisCommand(c, "GET %s", argv[3]);
printf("GET: %s\n", reply->str);
}
freeReplyObject(reply);
redisFree(c);
return 0;
}
-43
View File
@@ -1,43 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/assert.h"
#include "libc/calls/struct/timespec.h"
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/clock.h"
/**
* @fileoverview shows how accurate clock_nanosleep() is
*/
int main(int argc, char *argv[]) {
long i, ns;
struct timespec x, y, w;
timespec_sleep(timespec_fromnanos(0)); // warmup
printf("\nrelative sleep\n");
for (i = 0; i < 28; ++i) {
ns = 1l << i;
x = timespec_real();
timespec_sleep(timespec_fromnanos(ns));
y = timespec_real();
printf("%,11ld ns sleep took %,ld ns\n", ns,
timespec_tonanos(timespec_sub(y, x)));
}
printf("\nabsolute sleep\n");
for (i = 0; i < 28; ++i) {
ns = 1l << i;
x = timespec_real();
timespec_sleep_until(timespec_add(x, timespec_fromnanos(ns)));
y = timespec_real();
printf("%,11ld ns sleep took %,ld ns\n", ns,
timespec_tonanos(timespec_sub(y, x)));
}
}
+1 -1
View File
@@ -47,7 +47,7 @@
#include "third_party/libcxx/vector"
#include "tool/viz/lib/knobs.h"
STATIC_YOINK("zipos");
STATIC_YOINK("zip_uri_support");
#define USAGE \
" [ROM] [FMV]\n\
-1
View File
@@ -7,7 +7,6 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "ape/sections.internal.h"
#include "libc/dce.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
-127
View File
@@ -1,127 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/timeval.h"
#include "libc/errno.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h"
#include "libc/mem/alloca.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "net/http/ip.h"
/**
* @fileoverview fast local network port scanner, e.g.
*
* make -j8 o//examples/portscan.com
* o//examples/portscan.com 10.10.10.0/24 22
*/
const char *FormatIp(char buf[16], uint32_t ip) {
snprintf(buf, 16, "%hhu.%hhu.%hhu.%hhu", ip >> 24, ip >> 16, ip >> 8, ip);
return buf;
}
#define FormatIp(x) FormatIp(alloca(16), x)
int main(int argc, char *argv[]) {
int port;
struct Cidr in;
uint32_t netmask;
const char *status;
struct timeval timeout;
uint32_t network_address;
uint32_t last_host_address;
uint32_t first_host_address;
if (argc != 3) {
PrintUsage:
fprintf(stderr,
"usage: %s IP/CIDR PORT\n"
"example: %s 192.168.0.0/24 22\n",
argv[0], argv[0]);
return 1;
}
in = ParseCidr(argv[1], -1);
if (in.addr == -1) {
fprintf(stderr, "error: bad ip/cidr\n");
goto PrintUsage;
}
port = atoi(argv[2]);
if (!(1 <= port && port <= 65535)) {
fprintf(stderr, "error: bad port\n");
goto PrintUsage;
}
if (in.cidr > 30) {
fprintf(stderr, "error: maximum supported cidr is 30\n");
goto PrintUsage;
}
if (in.cidr < 22) {
fprintf(stderr, "error: minimum cidr support right now is 22\n");
goto PrintUsage;
}
netmask = -1u << (32 - in.cidr);
network_address = in.addr & netmask;
first_host_address = network_address + 1;
last_host_address = (network_address | ~netmask) - 1;
assert(last_host_address > first_host_address);
assert(last_host_address - first_host_address < 1024);
fprintf(stderr, "scanning %s through %s\n", FormatIp(first_host_address),
FormatIp(last_host_address));
timeout = timeval_frommillis(100);
for (int64_t ip = first_host_address; ip <= last_host_address; ++ip) {
if (!fork()) {
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
setsockopt(3, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
if (!connect(3,
(struct sockaddr *)&(struct sockaddr_in){
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(ip),
.sin_port = htons(port),
},
sizeof(struct sockaddr_in))) {
status = "open";
} else if (errno == ECONNREFUSED) {
status = "closed";
} else if (errno != EINPROGRESS) {
status = _strerrno(errno);
} else {
status = 0;
}
if (status) {
printf("%-15s %s\n", FormatIp(ip), status);
}
_Exit(0);
}
}
for (;;) {
if (wait(0) == -1 && errno == ECHILD) {
break;
}
}
}
-39
View File
@@ -1,39 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/reboot.h"
int main(int argc, char *argv[]) {
char line[8] = {0};
if (argc > 1 && !strcmp(argv[1], "-y")) {
line[0] = 'y';
} else {
printf("reboot your computer? yes or no [no] ");
fflush(stdout);
fgets(line, sizeof(line), stdin);
}
if (line[0] == 'y' || line[0] == 'Y') {
if (reboot(RB_AUTOBOOT)) {
printf("system is rebooting...\n");
exit(0);
} else {
perror("reboot");
exit(1);
}
} else if (line[0] == 'n' || line[0] == 'N') {
exit(0);
} else {
printf("error: unrecognized response\n");
exit(2);
}
}
-39
View File
@@ -1,39 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/calls/calls.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/reboot.h"
int main(int argc, char *argv[]) {
char line[8] = {0};
if (argc > 1 && !strcmp(argv[1], "-y")) {
line[0] = 'y';
} else {
printf("shutdown your computer? yes or no [no] ");
fflush(stdout);
fgets(line, sizeof(line), stdin);
}
if (line[0] == 'y' || line[0] == 'Y') {
if (reboot(RB_POWER_OFF)) {
printf("system is shutting down...\n");
exit(0);
} else {
perror("reboot");
exit(1);
}
} else if (line[0] == 'n' || line[0] == 'N') {
exit(0);
} else {
printf("error: unrecognized response\n");
exit(2);
}
}
File renamed without changes.
+3 -3
View File
@@ -27,13 +27,13 @@ dontinline void ShowIt(const char *path) {
"optimal transfer block size");
sizefmt(ibuf, sf.f_frsize, 1024);
printf("f_frsize = %,zu (%sb %s)\n", sf.f_frsize, ibuf, "fragment size");
sizefmt(ibuf, sf.f_blocks * sf.f_frsize, 1024);
sizefmt(ibuf, sf.f_blocks * sf.f_bsize, 1024);
printf("f_blocks = %,zu (%sb %s)\n", sf.f_blocks, ibuf,
"total data blocks in filesystem");
sizefmt(ibuf, sf.f_bfree * sf.f_frsize, 1024);
sizefmt(ibuf, sf.f_bfree * sf.f_bsize, 1024);
printf("f_bfree = %,zu (%sb %s)\n", sf.f_bfree, ibuf,
"free blocks in filesystem");
sizefmt(ibuf, sf.f_bavail * sf.f_frsize, 1024);
sizefmt(ibuf, sf.f_bavail * sf.f_bsize, 1024);
printf("f_bavail = %,zu (%sb %s)\n", sf.f_bavail, ibuf,
"free blocks available to use");
printf("f_files = %,zu (%s)\n", sf.f_files,
-42
View File
@@ -1,42 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
│ To the extent possible under law, Justine Tunney has waived │
│ all copyright and related or neighboring rights to this file, │
│ as it is written in the following disclaimers: │
│ • http://unlicense.org/ │
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
/**
* @fileoverview example of how to embed symbol table in .com file
*
* # build our binary
* make -j16 o//examples/symtab.com
*
* # move binary somewhere else
* # so it can't find the .com.dbg binary
* cp o//examples/symtab.com /tmp
*
* # run program
* # notice that it has a symbolic backtrace
* /tmp/symtab.com
*
* @see examples/examples.mk
*/
int main(int argc, char *argv[]) {
// this links all the debugging and zip functionality
ShowCrashReports();
kprintf("----------------\n");
kprintf(" THIS IS A TEST \n");
kprintf("SIMULATING CRASH\n");
kprintf("----------------\n");
volatile int64_t x;
return 1 / (x = 0);
}
+16 -16
View File
@@ -46,31 +46,31 @@ int main(int argc, char *argv[]) {
1. / 65536 * si.loads[1], //
1. / 65536 * si.loads[2]); //
sizefmt(ibuf, si.totalram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalram", si.totalram, ibuf);
sizefmt(ibuf, si.totalram, 1024);
printf("%-16s %s\n", "totalram", ibuf);
sizefmt(ibuf, si.freeram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeram", si.freeram, ibuf);
sizefmt(ibuf, si.freeram, 1024);
printf("%-16s %s\n", "freeram", ibuf);
sizefmt(ibuf, si.sharedram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "sharedram", si.sharedram, ibuf);
sizefmt(ibuf, si.sharedram, 1024);
printf("%-16s %s\n", "sharedram", ibuf);
sizefmt(ibuf, si.bufferram * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "bufferram", si.bufferram, ibuf);
sizefmt(ibuf, si.bufferram, 1024);
printf("%-16s %s\n", "bufferram", ibuf);
sizefmt(ibuf, si.totalswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalswap", si.totalswap, ibuf);
sizefmt(ibuf, si.totalswap, 1024);
printf("%-16s %s\n", "totalswap", ibuf);
sizefmt(ibuf, si.freeswap * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freeswap", si.freeswap, ibuf);
sizefmt(ibuf, si.freeswap, 1024);
printf("%-16s %s\n", "freeswap", ibuf);
printf("%-16s %lu\n", "processes", si.procs);
sizefmt(ibuf, si.totalhigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "totalhigh", si.totalhigh, ibuf);
sizefmt(ibuf, si.totalhigh, 1024);
printf("%-16s %s\n", "totalhigh", ibuf);
sizefmt(ibuf, si.freehigh * si.mem_unit, 1024);
printf("%-16s %ld (%s)\n", "freehigh", si.freehigh, ibuf);
sizefmt(ibuf, si.freehigh, 1024);
printf("%-16s %s\n", "freehigh", ibuf);
sizefmt(ibuf, si.mem_unit, 1024);
printf("%-16s %s\n", "mem_unit", ibuf);
+6 -13
View File
@@ -7,20 +7,13 @@
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
╚─────────────────────────────────────────────────────────────────*/
#endif
#include "libc/runtime/runtime.h"
#include "libc/dce.h"
#include "libc/stdio/stdio.h"
/**
* @fileoverview Cosmopolitan Command Interpreter Demo
* Yes this works on Windows.
*/
STATIC_YOINK("_tr");
STATIC_YOINK("_sed");
int main(int argc, char *argv[]) {
system("x=world\n"
"echo hello $x |\n"
" tr a-z A-Z |\n"
" sed 's/\\(.\\)/\\1 /g'");
if (IsWindows()) {
system("notepad");
} else {
system("ls | tr a-z A-Z");
}
}
-6
View File
@@ -24,16 +24,10 @@
STATIC_YOINK("vga_console");
STATIC_YOINK("_idt");
STATIC_YOINK("EfiMain");
int main(int argc, char *argv[]) {
int i;
volatile int x = 1;
volatile int y = 2;
printf("argc = %d\n", argc);
for (i = 0; i < argc; ++i) {
printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
printf("\e[92;44mHello World!\e[0m %d\n", 1 / (x + y - 3));
for (;;);
}
-21
View File
@@ -1,21 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_AR_H_
#define COSMOPOLITAN_LIBC_AR_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define ARMAG "!<arch>\n"
#define SARMAG 8
#define ARFMAG "`\n"
struct ar_hdr {
char ar_name[16];
char ar_date[12];
char ar_uid[6], ar_gid[6];
char ar_mode[8];
char ar_size[10];
char ar_fmag[2];
};
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_AR_H_ */
+2 -2
View File
@@ -4,7 +4,7 @@
COSMOPOLITAN_C_START_
extern bool __assert_disable;
void __assert_fail(const char *, const char *, int) _Hide relegated;
void __assert_fail(const char *, const char *, int) hidden relegated;
#ifdef NDEBUG
#define assert(x) ((void)0)
@@ -17,7 +17,7 @@ void __assert_fail(const char *, const char *, int) _Hide relegated;
#endif
#ifdef __GNUC__
#if !defined(TINY) && !defined(MODE_DBG)
#ifndef TINY
/**
* Specifies expression can't possibly be false.
*
+6 -4
View File
@@ -16,7 +16,6 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "ape/sections.internal.h"
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/sig.internal.h"
@@ -108,6 +107,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
STRACE("delivering %G", sig);
// enter the signal
__sig_lock();
rva = __sighandrvas[sig];
flags = __sighandflags[sig];
if ((~flags & SA_NODEFER) || (flags & SA_RESETHAND)) {
@@ -118,6 +118,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
// signal handler. in that case you must use SA_NODEFER.
__sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL;
}
__sig_unlock();
// setup the somewhat expensive information args
// only if they're requested by the user in sigaction()
@@ -139,9 +140,11 @@ static bool __sig_deliver(bool restartable, int sig, int si_code,
// since sigaction() is @asyncsignalsafe we only restore it if the
// user didn't change it during the signal handler. we also don't
// need to do anything if this was a oneshot signal or nodefer.
__sig_lock();
if (__sighandrvas[sig] == (int32_t)(intptr_t)SIG_DFL) {
__sighandrvas[sig] = rva;
}
__sig_unlock();
}
if (!restartable) {
@@ -204,7 +207,6 @@ textwindows int __sig_raise(int sig, int si_code) {
if (1 <= sig && sig <= 64) {
if (!__sig_is_masked(sig)) {
++__sig_count;
// TODO(jart): ucontext_t support
__sig_handle(false, sig, si_code, 0);
return 0;
} else {
@@ -225,12 +227,12 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
int rc;
struct Signal *mem;
if (1 <= sig && sig <= 64) {
__sig_lock();
if (__sighandrvas[sig] == (unsigned)(intptr_t)SIG_IGN) {
STRACE("ignoring %G", sig);
rc = 0;
} else {
STRACE("enqueuing %G", sig);
__sig_lock();
++__sig_count;
if ((mem = __sig_alloc())) {
mem->tid = tid;
@@ -242,8 +244,8 @@ textwindows int __sig_add(int tid, int sig, int si_code) {
} else {
rc = enomem();
}
__sig_unlock();
}
__sig_unlock();
} else {
rc = einval();
}
+1 -6
View File
@@ -16,9 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/tls.h"
@@ -47,10 +45,7 @@ textwindows int __sig_mask(int how, const sigset_t *neu, sigset_t *old) {
} else {
x = y;
}
x &= ~(0
#define M(x) | GetSigBit(x)
#include "libc/intrin/sigisprecious.inc"
);
x &= ~(GetSigBit(SIGKILL) | GetSigBit(SIGSTOP) | GetSigBit(SIGABRT));
*mask = x;
}
return 0;
@@ -21,7 +21,7 @@
/**
* Adds two nanosecond timestamps.
*/
struct timespec timespec_add(struct timespec x, struct timespec y) {
struct timespec _timespec_add(struct timespec x, struct timespec y) {
x.tv_sec += y.tv_sec;
x.tv_nsec += y.tv_nsec;
if (x.tv_nsec >= 1000000000) {
@@ -20,10 +20,8 @@
/**
* Compares nanosecond timestamps.
*
* @return 0 if equal, -1 if `a < b`, or +1 if `a > b`
*/
int timespec_cmp(struct timespec a, struct timespec b) {
int _timespec_cmp(struct timespec a, struct timespec b) {
int cmp;
if (!(cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec))) {
cmp = (a.tv_nsec > b.tv_nsec) - (a.tv_nsec < b.tv_nsec);
@@ -16,10 +16,11 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "third_party/awk/cmd.h"
#include "tool/args/args.h"
#include "libc/calls/struct/timespec.h"
int main(int argc, char *argv[]) {
LoadZipArgs(&argc, &argv);
return _awk(argc, argv);
/**
* Checks if 𝑥 = 𝑦.
*/
bool _timespec_eq(struct timespec x, struct timespec y) {
return x.tv_sec == y.tv_sec && x.tv_nsec == y.tv_nsec;
}
@@ -21,7 +21,7 @@
/**
* Converts timespec interval from microseconds.
*/
struct timespec timespec_frommicros(int64_t x) {
struct timespec _timespec_frommicros(int64_t x) {
struct timespec ts;
ts.tv_sec = x / 1000000;
ts.tv_nsec = x % 1000000 * 1000;
@@ -21,7 +21,7 @@
/**
* Converts timespec interval from milliseconds.
*/
struct timespec timespec_frommillis(int64_t x) {
struct timespec _timespec_frommillis(int64_t x) {
struct timespec ts;
ts.tv_sec = x / 1000;
ts.tv_nsec = x % 1000 * 1000000;
@@ -21,7 +21,7 @@
/**
* Converts timespec interval from nanoseconds.
*/
struct timespec timespec_fromnanos(int64_t x) {
struct timespec _timespec_fromnanos(int64_t x) {
struct timespec ts;
ts.tv_sec = x / 1000000000;
ts.tv_nsec = x % 1000000000;
@@ -26,7 +26,7 @@
* @param ts receives `CLOCK_REALTIME` timestamp
* @param base must be `TIME_UTC`
* @return `base` on success, or `0` on failure
* @see timespec_real()
* @see _timespec_real()
*/
int timespec_get(struct timespec *ts, int base) {
if (base == TIME_UTC && !clock_gettime(CLOCK_REALTIME, ts)) {
File renamed without changes.
+34
View File
@@ -0,0 +1,34 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timespec.h"
/**
* Returns true if timespec `x` is greater than `y`.
*/
bool _timespec_gt(struct timespec x, struct timespec y) {
if (x.tv_sec > y.tv_sec) {
return true;
}
if (x.tv_sec == y.tv_sec) {
if (x.tv_nsec > y.tv_nsec) {
return true;
}
}
return false;
}
+28
View File
@@ -0,0 +1,28 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timespec.h"
/**
* Checks if 𝑥 ≥ 𝑦.
*/
bool _timespec_gte(struct timespec x, struct timespec y) {
if (x.tv_sec > y.tv_sec) return true;
if (x.tv_sec < y.tv_sec) return false;
return x.tv_nsec >= y.tv_nsec;
}
@@ -25,10 +25,10 @@
*
* This function uses a `CLOCK_MONOTONIC` clock and never fails.
*
* @see timespec_real()
* @see _timespec_real()
*/
struct timespec timespec_mono(void) {
struct timespec _timespec_mono(void) {
struct timespec ts;
_npassert(!clock_gettime(CLOCK_MONOTONIC, &ts));
_npassert(!clock_gettime(CLOCK_MONOTONIC_FAST, &ts));
return ts;
}
@@ -27,10 +27,10 @@
* clock_gettime() or timespec_real() this interface avoids the use of
* pointers which lets time handling code become more elegant.
*
* @see timespec_mono()
* @see _timespec_mono()
*/
struct timespec timespec_real(void) {
struct timespec _timespec_real(void) {
struct timespec ts;
_npassert(!clock_gettime(CLOCK_REALTIME, &ts));
_npassert(!clock_gettime(CLOCK_REALTIME_FAST, &ts));
return ts;
}
@@ -17,10 +17,8 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/clock.h"
/**
@@ -28,14 +26,13 @@
*
* @return unslept time which may be non-zero if the call was interrupted
*/
struct timespec timespec_sleep(struct timespec delay) {
errno_t rc;
struct timespec _timespec_sleep(struct timespec delay) {
int rc;
struct timespec remain;
BLOCK_CANCELLATIONS;
bzero(&remain, sizeof(remain));
if ((rc = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, &delay, &remain))) {
return (struct timespec){0};
} else {
_npassert(rc == EINTR);
return remain;
}
ALLOW_CANCELLATIONS;
return remain;
}
@@ -26,13 +26,10 @@
* Sleeps until the specified time.
*
* @return 0 on success, or EINTR if interrupted
* @raise ECANCELED if thread was cancelled in masked mode
* @raise EINTR if signal was delivered
* @cancellationpoint
*/
errno_t timespec_sleep_until(struct timespec abs_deadline) {
errno_t rc;
int _timespec_sleep_until(struct timespec abs_deadline) {
int rc;
rc = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs_deadline, 0);
_npassert(!rc || rc == EINTR || rc == ECANCELED);
_npassert(!rc || rc == EINTR);
return rc;
}
@@ -21,7 +21,7 @@
/**
* Subtracts two nanosecond timestamps.
*/
struct timespec timespec_sub(struct timespec a, struct timespec b) {
struct timespec _timespec_sub(struct timespec a, struct timespec b) {
a.tv_sec -= b.tv_sec;
if (a.tv_nsec < b.tv_nsec) {
a.tv_nsec += 1000000000;
@@ -31,9 +31,9 @@
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
*
* @return 64-bit scalar holding microseconds since epoch
* @see timespec_totimeval()
* @see _timespec_totimeval()
*/
int64_t timespec_tomicros(struct timespec ts) {
int64_t _timespec_tomicros(struct timespec ts) {
int64_t us;
// reduce precision from nanos to micros
if (ts.tv_nsec <= 999999000) {
@@ -32,7 +32,7 @@
*
* @return 64-bit scalar milliseconds since epoch
*/
int64_t timespec_tomillis(struct timespec ts) {
int64_t _timespec_tomillis(struct timespec ts) {
int64_t ms;
// reduce precision from nanos to millis
if (ts.tv_nsec <= 999000000) {
@@ -22,13 +22,12 @@
/**
* Converts timespec to scalar.
*
* This returns the absolute number of nanoseconds in a timespec. If
* overflow happens, then `INT64_MAX` or `INT64_MIN` is returned. The
* `errno` variable isn't changed.
* This function will detect overflow in which case `INT64_MAX` or
* `INT64_MIN` may be returned. The `errno` variable isn't changed.
*
* @return 64-bit integer holding nanoseconds since epoch
*/
int64_t timespec_tonanos(struct timespec x) {
int64_t _timespec_tonanos(struct timespec x) {
int64_t ns;
if (!__builtin_mul_overflow(x.tv_sec, 1000000000ul, &ns) &&
!__builtin_add_overflow(ns, x.tv_nsec, &ns)) {
@@ -27,9 +27,9 @@
* timestamp has a special meaning.
*
* @return microseconds since epoch
* @see timespec_tomicros()
* @see _timespec_tomicros()
*/
struct timeval timespec_totimeval(struct timespec ts) {
struct timeval _timespec_totimeval(struct timespec ts) {
if (ts.tv_nsec < 1000000000 - 999) {
return (struct timeval){ts.tv_sec, (ts.tv_nsec + 999) / 1000};
} else {
@@ -21,7 +21,7 @@
/**
* Adds two microsecond timestamps.
*/
struct timeval timeval_add(struct timeval x, struct timeval y) {
struct timeval _timeval_add(struct timeval x, struct timeval y) {
x.tv_sec += y.tv_sec;
x.tv_usec += y.tv_usec;
if (x.tv_usec >= 1000000) {
@@ -19,11 +19,9 @@
#include "libc/calls/struct/timeval.h"
/**
* Compares microsecond timestamps.
*
* @return 0 if equal, -1 if `a < b`, or +1 if `a > b`
* Compares microseconds timestamps.
*/
int timeval_cmp(struct timeval a, struct timeval b) {
int _timeval_cmp(struct timeval a, struct timeval b) {
int cmp;
if (!(cmp = (a.tv_sec > b.tv_sec) - (a.tv_sec < b.tv_sec))) {
cmp = (a.tv_usec > b.tv_usec) - (a.tv_usec < b.tv_usec);
@@ -19,11 +19,8 @@
#include "libc/calls/struct/timeval.h"
/**
* Converts timeval interval from microseconds.
* Checks if 𝑥 = 𝑦.
*/
struct timeval timeval_frommicros(int64_t x) {
struct timeval tv;
tv.tv_sec = x / 1000000;
tv.tv_usec = x % 1000000;
return tv;
bool _timeval_eq(struct timeval x, struct timeval y) {
return x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec;
}
+34
View File
@@ -0,0 +1,34 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timeval.h"
/**
* Returns true if timeval `x` is greater than `y`.
*/
bool _timeval_gt(struct timeval x, struct timeval y) {
if (x.tv_sec > y.tv_sec) {
return true;
}
if (x.tv_sec == y.tv_sec) {
if (x.tv_usec > y.tv_usec) {
return true;
}
}
return false;
}
@@ -19,11 +19,10 @@
#include "libc/calls/struct/timeval.h"
/**
* Converts timeval interval from milliseconds.
* Checks if 𝑥 ≥ 𝑦.
*/
struct timeval timeval_frommillis(int64_t x) {
struct timeval tv;
tv.tv_sec = x / 1000;
tv.tv_usec = x % 1000 * 1000;
return tv;
bool _timeval_gte(struct timeval x, struct timeval y) {
if (x.tv_sec > y.tv_sec) return true;
if (x.tv_sec < y.tv_sec) return false;
return x.tv_usec >= y.tv_usec;
}
@@ -21,7 +21,7 @@
/**
* Subtracts two nanosecond timestamps.
*/
struct timeval timeval_sub(struct timeval a, struct timeval b) {
struct timeval _timeval_sub(struct timeval a, struct timeval b) {
a.tv_sec -= b.tv_sec;
if (a.tv_usec < b.tv_usec) {
a.tv_usec += 1000000;
@@ -21,6 +21,6 @@
/**
* Coerces `tv` from 1e-6 to 1e-9 granularity.
*/
struct timespec timeval_totimespec(struct timeval tv) {
struct timespec _timeval_totimespec(struct timeval tv) {
return (struct timespec){tv.tv_sec, tv.tv_usec * 1000};
}
@@ -22,9 +22,9 @@
/**
* Accumulates resource statistics in `y` to `x`.
*/
void rusage_add(struct rusage *x, const struct rusage *y) {
x->ru_utime = timeval_add(x->ru_utime, y->ru_utime);
x->ru_stime = timeval_add(x->ru_stime, y->ru_stime);
void _addrusage(struct rusage *x, const struct rusage *y) {
x->ru_utime = _timeval_add(x->ru_utime, y->ru_utime);
x->ru_stime = _timeval_add(x->ru_stime, y->ru_stime);
x->ru_maxrss = MAX(x->ru_maxrss, y->ru_maxrss);
x->ru_ixrss += y->ru_ixrss;
x->ru_idrss += y->ru_idrss;
-22
View File
@@ -1,22 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
#define COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_
#include "libc/thread/thread.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define BLOCK_CANCELLATIONS \
do { \
int _CancelState; \
_CancelState = _pthread_block_cancellations()
#define ALLOW_CANCELLATIONS \
_pthread_allow_cancellations(_CancelState); \
} \
while (0)
int _pthread_block_cancellations(void);
void _pthread_allow_cancellations(int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_BLOCKCANCEL_H_ */
-19
View File
@@ -1,19 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_
#define COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_
#include "libc/calls/struct/sigset.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define BLOCK_SIGNALS \
do { \
sigset_t _SigMask; \
_SigMask = _sigblockall()
#define ALLOW_SIGNALS \
_sigsetmask(_SigMask); \
} \
while (0)
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_BLOCKSIGS_H_ */
+47 -65
View File
@@ -5,25 +5,6 @@
#define _POSIX2_VERSION _POSIX_VERSION
#define _XOPEN_VERSION 700
#define _POSIX_MAPPED_FILES _POSIX_VERSION
#define _POSIX_FSYNC _POSIX_VERSION
#define _POSIX_IPV6 _POSIX_VERSION
#define _POSIX_THREADS _POSIX_VERSION
#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
#define _POSIX_THREAD_CPUTIME _POSIX_VERSION
#define _POSIX_TIMEOUTS _POSIX_VERSION
#define _POSIX_MONOTONIC_CLOCK _POSIX_VERSION
#define _POSIX_CPUTIME _POSIX_VERSION
#define _POSIX_BARRIERS _POSIX_VERSION
#define _POSIX_SPIN_LOCKS _POSIX_VERSION
#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
#define _POSIX_SEMAPHORES _POSIX_VERSION
#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
#define EOF -1 /* end of file */
#define WEOF -1u /* end of file (multibyte) */
#define _IOFBF 0 /* fully buffered */
@@ -54,10 +35,11 @@
#define WIFCONTINUED(s) ((s) == 0xffff)
#define WIFEXITED(s) (!WTERMSIG(s))
#define WIFSIGNALED(s) ((0xffff & (s)) - 1u < 0xffu)
#define WIFSTOPPED(s) ((255 & (s)) == 127)
#define WSTOPSIG(s) WEXITSTATUS(s)
#define WTERMSIG(s) (127 & (s))
#define W_STOPCODE(s) ((s) << 8 | 0177)
#define WIFSTOPPED(s) \
((short)(((0xffff & (unsigned)(s)) * 0x10001) >> 8) > 0x7f00)
#define WSTOPSIG(s) WEXITSTATUS(s)
#define WTERMSIG(s) (127 & (s))
#define W_STOPCODE(s) ((s) << 8 | 0177)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@@ -83,13 +65,13 @@ char *ttyname(int);
int access(const char *, int) dontthrow;
int arch_prctl();
int chdir(const char *);
int chmod(const char *, unsigned);
int chown(const char *, unsigned, unsigned);
int chmod(const char *, uint32_t);
int chown(const char *, uint32_t, uint32_t);
int chroot(const char *);
int close(int);
int close_range(unsigned, unsigned, unsigned);
int closefrom(int);
int creat(const char *, unsigned);
int creat(const char *, uint32_t);
int dup(int);
int dup2(int, int);
int dup3(int, int, int);
@@ -102,22 +84,25 @@ int execv(const char *, char *const[]);
int execve(const char *, char *const[], char *const[]);
int execvp(const char *, char *const[]);
int execvpe(const char *, char *const[], char *const[]);
int fexecve(int, char *const[], char *const[]);
int faccessat(int, const char *, int, int);
int fadvise(int, uint64_t, uint64_t, int);
int fchdir(int);
int fchmod(int, unsigned) dontthrow;
int fchmodat(int, const char *, unsigned, int);
int fchown(int, unsigned, unsigned);
int fchownat(int, const char *, unsigned, unsigned, int);
int fchmod(int, uint32_t) dontthrow;
int fchmodat(int, const char *, uint32_t, int);
int fchown(int, uint32_t, uint32_t);
int fchownat(int, const char *, uint32_t, uint32_t, int);
int fcntl(int, int, ...);
int fdatasync(int);
int fexecve(int, char *const[], char *const[]);
int flock(int, int);
int fork(void);
int fsync(int);
int ftruncate(int, int64_t);
int getdomainname(char *, size_t);
int getgroups(int, unsigned[]);
uint32_t getegid(void) nosideeffect;
uint32_t geteuid(void) nosideeffect;
uint32_t getgid(void) nosideeffect;
int getgroups(int size, uint32_t list[]);
int gethostname(char *, size_t);
int getloadavg(double *, int);
int getpgid(int) libcesque;
@@ -125,29 +110,36 @@ int getpgrp(void) nosideeffect;
int getpid(void) nosideeffect libcesque;
int getppid(void);
int getpriority(int, unsigned);
int getresgid(unsigned *, unsigned *, unsigned *);
int getresuid(unsigned *, unsigned *, unsigned *);
int getresgid(uint32_t *, uint32_t *, uint32_t *);
int getresuid(uint32_t *, uint32_t *, uint32_t *);
int getsid(int) nosideeffect libcesque;
int gettid(void) libcesque;
uint32_t getuid(void) libcesque;
int sys_iopl(int);
int ioprio_get(int, int);
int ioprio_set(int, int, int);
int issetugid(void);
int kill(int, int);
int killpg(int, int);
int lchmod(const char *, unsigned);
int lchown(const char *, unsigned, unsigned);
int lchmod(const char *, uint32_t);
int lchown(const char *, uint32_t, uint32_t);
int link(const char *, const char *) dontthrow;
int linkat(int, const char *, int, const char *, int);
int madvise(void *, uint64_t, int);
int makedirs(const char *, unsigned);
int memfd_create(const char *, unsigned int);
int mincore(void *, size_t, unsigned char *);
int mkdir(const char *, unsigned);
int mkdirat(int, const char *, unsigned);
int mkfifo(const char *, unsigned);
int mkfifoat(int, const char *, unsigned);
int mknod(const char *, unsigned, uint64_t);
int mknodat(int, const char *, int, uint64_t);
int makedirs(const char *, unsigned);
int mkfifo(const char *, uint32_t);
int mkfifoat(int, const char *, uint32_t);
int mknod(const char *, uint32_t, uint64_t);
int mknodat(int, const char *, int32_t, uint64_t);
int sys_mlock(const void *, size_t);
int sys_mlock2(const void *, size_t, int);
int sys_mlockall(int);
int sys_munlock(const void *, size_t);
int sys_munlockall(void);
int nice(int);
int open(const char *, int, ...);
int openat(int, const char *, int, ...);
@@ -169,19 +161,19 @@ int renameat2(long, const char *, long, const char *, int);
int rmdir(const char *);
int sched_yield(void);
int seccomp(unsigned, unsigned, void *);
int setegid(unsigned);
int seteuid(unsigned);
int setegid(uint32_t);
int seteuid(uint32_t);
int setfsgid(unsigned);
int setfsuid(unsigned);
int setgid(unsigned);
int setgroups(size_t, const unsigned[]);
int setgroups(size_t, const uint32_t[]);
int setpgid(int, int);
int setpgrp(void);
int setpriority(int, unsigned, int);
int setregid(unsigned, unsigned);
int setresgid(unsigned, unsigned, unsigned);
int setresuid(unsigned, unsigned, unsigned);
int setreuid(unsigned, unsigned);
int setregid(uint32_t, uint32_t);
int setresgid(uint32_t, uint32_t, uint32_t);
int setresuid(uint32_t, uint32_t, uint32_t);
int setreuid(uint32_t, uint32_t);
int setsid(void);
int setuid(unsigned);
int sigignore(int);
@@ -189,22 +181,16 @@ int siginterrupt(int, int);
int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned);
int sys_iopl(int);
int sys_mlock(const void *, size_t);
int sys_mlock2(const void *, size_t, int);
int sys_mlockall(int);
int sys_munlock(const void *, size_t);
int sys_munlockall(void);
int sys_ptrace(int, ...);
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
int tcgetpgrp(int);
int tcsetpgrp(int, int);
int tcsetpgrp(int, int32_t);
int tgkill(int, int, int);
int tkill(int, int);
int tmpfd(void);
int touch(const char *, unsigned);
int touch(const char *, uint32_t);
int truncate(const char *, int64_t);
int ttyname_r(int, char *, size_t);
unsigned umask(unsigned);
int unlink(const char *);
int unlink_s(const char **);
int unlinkat(int, const char *, int);
@@ -213,10 +199,11 @@ int usleep(unsigned);
int vfork(void) returnstwice;
int wait(int *);
int waitpid(int, int *, int);
int32_t tcgetpgrp(int);
intptr_t syscall(int, ...);
long ptrace(int, ...);
ssize_t copy_file_range(int, long *, int, long *, size_t, unsigned);
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, unsigned);
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
ssize_t getfiledescriptorsize(int);
ssize_t lseek(int, int64_t, int);
ssize_t pread(int, void *, size_t, int64_t);
@@ -225,13 +212,8 @@ ssize_t read(int, void *, size_t);
ssize_t readansi(int, char *, size_t);
ssize_t readlink(const char *, char *, size_t);
ssize_t readlinkat(int, const char *, char *, size_t);
ssize_t splice(int, int64_t *, int, int64_t *, size_t, unsigned);
ssize_t splice(int, int64_t *, int, int64_t *, size_t, uint32_t);
ssize_t write(int, const void *, size_t);
unsigned getegid(void) nosideeffect;
unsigned geteuid(void) nosideeffect;
unsigned getgid(void) nosideeffect;
unsigned getuid(void) libcesque;
unsigned umask(unsigned);
void sync(void);
COSMOPOLITAN_C_END_
+16 -10
View File
@@ -121,12 +121,21 @@ o/$(MODE)/libc/calls/execlp.o \
o/$(MODE)/libc/calls/statfs.o \
o/$(MODE)/libc/calls/fstatfs.o \
o/$(MODE)/libc/calls/execve-sysv.o \
o/$(MODE)/libc/calls/readlinkat-nt.o \
o/$(MODE)/libc/calls/execve-nt.greg.o \
o/$(MODE)/libc/calls/mkntenvblock.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
# we must disable static stack safety because:
# PATH_MAX*sizeof(char16_t)*2 exceeds 4096 byte frame limit
o/$(MODE)/libc/calls/copyfile.o \
o/$(MODE)/libc/calls/symlinkat-nt.o \
o/$(MODE)/libc/calls/readlinkat-nt.o \
o/$(MODE)/libc/calls/linkat-nt.o \
o/$(MODE)/libc/calls/renameat-nt.o: private \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
# we must segregate codegen because:
# file contains multiple independently linkable apis
o/$(MODE)/libc/calls/ioctl-siocgifconf.o \
@@ -170,15 +179,12 @@ o//libc/calls/statfs2cosmo.o: private \
# we always want -O2 because:
# division is expensive if not optimized
o/$(MODE)/libc/calls/clock.o \
o/$(MODE)/libc/calls/timespec_tomillis.o \
o/$(MODE)/libc/calls/timespec_tomicros.o \
o/$(MODE)/libc/calls/timespec_totimeval.o \
o/$(MODE)/libc/calls/timespec_fromnanos.o \
o/$(MODE)/libc/calls/timespec_frommillis.o \
o/$(MODE)/libc/calls/timespec_frommicros.o \
o/$(MODE)/libc/calls/timeval_tomillis.o \
o/$(MODE)/libc/calls/timeval_frommillis.o \
o/$(MODE)/libc/calls/timeval_frommicros.o: private \
o/$(MODE)/libc/calls/_timespec_tomillis.o \
o/$(MODE)/libc/calls/_timespec_tomicros.o \
o/$(MODE)/libc/calls/_timespec_totimeval.o \
o/$(MODE)/libc/calls/_timespec_fromnanos.o \
o/$(MODE)/libc/calls/_timespec_frommillis.o \
o/$(MODE)/libc/calls/_timespec_frommicros.o: private \
OVERRIDE_CFLAGS += \
-O2
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 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,14 +16,13 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/runtime.h"
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
const char *GetCpuidEmulator(void) {
static bool once;
static char s[13];
if (!once) {
GetCpuidBrand(s, 0x40000000);
once = true;
uint32_t cfgetispeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ispeed;
}
return s;
}
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2023 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,14 +16,13 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/runtime.h"
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
const char *GetCpuidOs(void) {
static bool once;
static char s[13];
if (!once) {
GetCpuidBrand(s, 0x40031337);
once = true;
uint32_t cfgetospeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ospeed;
}
return s;
}
+33
View File
@@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/termios.h"
#include "libc/sysv/errfuns.h"
int cfsetispeed(struct termios *t, unsigned speed) {
if (speed) {
if (CBAUD) {
if (speed & ~CBAUD) return einval();
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
} else {
t->c_ispeed = speed;
}
}
return 0;
}
+36
View File
@@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
int cfsetospeed(struct termios *t, unsigned speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
return 0;
} else {
return einval();
}
} else {
t->c_ospeed = speed;
return 0;
}
}
-88
View File
@@ -1,88 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/termios.h"
#include "libc/sysv/consts/termios.h"
#include "libc/sysv/errfuns.h"
/**
* Returns input baud rate.
* @asyncsignalsafe
*/
uint32_t cfgetispeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ispeed;
}
}
/**
* Returns output baud rate.
* @asyncsignalsafe
*/
uint32_t cfgetospeed(const struct termios *t) {
if (CBAUD) {
return t->c_cflag & CBAUD;
} else {
return t->c_ospeed;
}
}
/**
* Sets input baud rate.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int cfsetispeed(struct termios *t, unsigned speed) {
if (speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
} else {
return einval();
}
} else {
t->c_ispeed = speed;
}
}
return 0;
}
/**
* Sets output baud rate.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int cfsetospeed(struct termios *t, unsigned speed) {
if (CBAUD) {
if (!(speed & ~CBAUD)) {
t->c_cflag &= ~CBAUD;
t->c_cflag |= speed;
return 0;
} else {
return einval();
}
} else {
t->c_ospeed = speed;
return 0;
}
}
+1 -1
View File
@@ -36,7 +36,7 @@
int chdir(const char *path) {
int rc;
GetProgramExecutableName(); // XXX: ugly workaround
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
rc = efault();
} else if (!IsWindows()) {
rc = sys_chdir(path);
+1 -1
View File
@@ -49,7 +49,7 @@
*/
int chroot(const char *path) {
int rc;
if (!path || (IsAsan() && !__asan_is_valid_str(path))) {
if (!path || (IsAsan() && !__asan_is_valid(path, 1))) {
rc = efault();
} else {
rc = sys_chroot(path);
+1 -1
View File
@@ -55,7 +55,7 @@ int64_t clock(void) {
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) {
errno = e;
if (getrusage(RUSAGE_SELF, &ru) != -1) {
ts = timeval_totimespec(timeval_add(ru.ru_utime, ru.ru_stime));
ts = _timeval_totimespec(_timeval_add(ru.ru_utime, ru.ru_stime));
} else {
return -1;
}
+3 -3
View File
@@ -17,11 +17,11 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timespec.h"
#include "libc/thread/thread.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
static struct {
pthread_once_t once;
@@ -30,7 +30,7 @@ static struct {
} g_mono;
static void sys_clock_gettime_mono_init(void) {
g_mono.base_wall = timespec_real();
g_mono.base_wall = _timespec_real();
g_mono.base_tick = rdtsc();
}
@@ -42,7 +42,7 @@ int sys_clock_gettime_mono(struct timespec *time) {
pthread_once(&g_mono.once, sys_clock_gettime_mono_init);
cycles = rdtsc() - g_mono.base_tick;
nanos = cycles / 3;
*time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos));
*time = _timespec_add(g_mono.base_wall, _timespec_fromnanos(nanos));
return 0;
} else {
return einval();
+16 -19
View File
@@ -50,23 +50,20 @@
* sys_clock_gettime l: 220𝑐 71𝑛𝑠
*
* @param clock can be one of:
* - `CLOCK_REALTIME`: universally supported
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
* - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd
* - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC`: universally supported
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd
* - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+
* - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
* - `CLOCK_MONOTONIC_COARSE`: linux, freebsd
* - `CLOCK_PROF`: linux and netbsd
* - `CLOCK_BOOTTIME`: linux and openbsd
* - `CLOCK_REALTIME_ALARM`: linux-only
* - `CLOCK_BOOTTIME_ALARM`: linux-only
* - `CLOCK_TAI`: linux-only
* - `CLOCK_REALTIME`: universally supported
* - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC`: universally supported
* - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd
* - `CLOCK_MONOTONIC_RAW`: nearly universally supported
* - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd
* - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd
* - `CLOCK_REALTIME_COARSE`: : linux and openbsd
* - `CLOCK_MONOTONIC_COARSE`: linux
* - `CLOCK_PROF`: linux and netbsd
* - `CLOCK_BOOTTIME`: linux and openbsd
* - `CLOCK_REALTIME_ALARM`: linux-only
* - `CLOCK_BOOTTIME_ALARM`: linux-only
* - `CLOCK_TAI`: linux-only
* @param ts is where the result is stored
* @return 0 on success, or -1 w/ errno
* @error EPERM if pledge() is in play without stdio promise
@@ -87,7 +84,7 @@ int clock_gettime(int clock, struct timespec *ts) {
rc = __clock_gettime(clock, ts);
}
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock),
DescribeTimespec(rc, ts), rc);
}
@@ -119,7 +116,7 @@ clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) {
return res;
}
_Hide int __clock_gettime_init(int clockid, struct timespec *ts) {
hidden int __clock_gettime_init(int clockid, struct timespec *ts) {
clock_gettime_f *gettime;
__clock_gettime = gettime = __clock_gettime_get(0);
return gettime(clockid, ts);
+3 -3
View File
@@ -7,9 +7,9 @@ COSMOPOLITAN_C_START_
typedef int clock_gettime_f(int, struct timespec *);
extern clock_gettime_f *__clock_gettime;
clock_gettime_f *__clock_gettime_get(bool *) _Hide;
int __clock_gettime_init(int, struct timespec *) _Hide;
int sys_clock_gettime_mono(struct timespec *) _Hide;
clock_gettime_f *__clock_gettime_get(bool *) hidden;
int __clock_gettime_init(int, struct timespec *) hidden;
int sys_clock_gettime_mono(struct timespec *) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
+8 -8
View File
@@ -33,24 +33,24 @@ textwindows int sys_clock_nanosleep_nt(int clock, int flags,
abs = *req;
for (;;) {
if (sys_clock_gettime_nt(clock, &now)) return -1;
if (timespec_cmp(now, abs) >= 0) return 0;
if (_check_interrupts(false, g_fds.p)) return -1;
if (_timespec_gte(now, abs)) return 0;
if (_check_interrupts(false, g_fds.p)) return eintr();
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
timespec_tomillis(timespec_sub(abs, now))),
_timespec_tomillis(_timespec_sub(abs, now))),
false);
}
} else {
if (sys_clock_gettime_nt(clock, &now)) return -1;
abs = timespec_add(now, *req);
abs = _timespec_add(now, *req);
for (;;) {
sys_clock_gettime_nt(clock, &now);
if (timespec_cmp(now, abs) >= 0) return 0;
if (_timespec_gte(now, abs)) return 0;
if (_check_interrupts(false, g_fds.p)) {
if (rem) *rem = timespec_sub(abs, now);
return -1;
if (rem) *rem = _timespec_sub(abs, now);
return eintr();
}
SleepEx(MIN(__SIG_POLLING_INTERVAL_MS,
timespec_tomillis(timespec_sub(abs, now))),
_timespec_tomillis(_timespec_sub(abs, now))),
false);
}
}
+2 -2
View File
@@ -31,8 +31,8 @@ int sys_clock_nanosleep_openbsd(int clock, int flags,
res = sys_nanosleep(req, rem);
} else {
sys_clock_gettime(clock, &now);
if (timespec_cmp(*req, now) > 0) {
rel = timespec_sub(*req, now);
if (_timespec_gt(*req, now)) {
rel = _timespec_sub(*req, now);
res = sys_nanosleep(&rel, 0);
} else {
res = 0;
+3 -3
View File
@@ -31,10 +31,10 @@ int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
struct timeval now, abs, rel;
if (clock == CLOCK_REALTIME) {
if (flags & TIMER_ABSTIME) {
abs = timespec_totimeval(*req);
abs = _timespec_totimeval(*req);
sys_gettimeofday_xnu(&now, 0, 0);
if (timeval_cmp(abs, now) > 0) {
rel = timeval_sub(abs, now);
if (_timeval_gt(abs, now)) {
rel = _timeval_sub(abs, now);
res = sys_select(0, 0, 0, 0, &rel);
} else {
res = 0;
+27 -171
View File
@@ -16,12 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/asan.internal.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/clock_gettime.internal.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
@@ -31,158 +26,11 @@
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/nt/ntdll.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
static int64_t g_nanosleep_latency;
static errno_t sys_clock_nanosleep(int clock, int flags,
const struct timespec *req,
struct timespec *rem) {
int e, rc;
BEGIN_CANCELLATION_POINT;
e = errno;
if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = __sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
}
if (rc == -1) {
rc = errno;
errno = e;
}
END_CANCELLATION_POINT;
return rc;
}
// determine sched_yield() vs. clock_nanosleep() threshold
// 1ns sys_clock_nanosleep() on Windows takes milliseconds :'(
// 1ns sys_clock_nanosleep() on Linux/FreeBSD takes tens of microseconds
// 1ns sys_clock_nanosleep() on OpenBSD/NetBSD takes tens of milliseconds D:
static struct timespec GetNanosleepLatency(void) {
errno_t rc;
int64_t nanos;
clock_gettime_f *cgt;
struct timespec x, y, w = {0, 1};
if (!(nanos = g_nanosleep_latency)) {
BLOCK_CANCELLATIONS;
for (cgt = __clock_gettime_get(0);;) {
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &x));
rc = sys_clock_nanosleep(CLOCK_REALTIME, 0, &w, 0);
_npassert(!rc || rc == EINTR);
if (!rc) {
_npassert(!cgt(CLOCK_REALTIME_PRECISE, &y));
nanos = timespec_tonanos(timespec_sub(y, x));
g_nanosleep_latency = nanos;
break;
}
}
ALLOW_CANCELLATIONS;
}
return timespec_fromnanos(nanos);
}
static errno_t CheckCancel(void) {
if (_weaken(pthread_testcancel_np)) {
return _weaken(pthread_testcancel_np)();
} else {
return 0;
}
}
static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req,
struct timespec *rem) {
errno_t rc;
clock_gettime_f *cgt;
struct timespec now, start, elapsed;
if ((rc = CheckCancel())) {
if (rc == EINTR && !flags && rem) {
*rem = *req;
}
return rc;
}
cgt = __clock_gettime_get(0);
_npassert(!cgt(CLOCK_REALTIME, &start));
for (;;) {
sched_yield();
_npassert(!cgt(CLOCK_REALTIME, &now));
if (flags & TIMER_ABSTIME) {
if (timespec_cmp(now, *req) >= 0) {
return 0;
}
if ((rc = CheckCancel())) {
return rc;
}
} else {
if (timespec_cmp(now, start) < 0) continue;
elapsed = timespec_sub(now, start);
if ((rc = CheckCancel())) {
if (rc == EINTR && rem) {
if (timespec_cmp(elapsed, *req) >= 0) {
bzero(rem, sizeof(*rem));
} else {
*rem = elapsed;
}
}
return rc;
}
if (timespec_cmp(elapsed, *req) >= 0) {
return 0;
}
}
}
}
static bool ShouldUseSpinNanosleep(int clock, int flags,
const struct timespec *req) {
errno_t e;
struct timespec now;
if (IsWindows()) {
// Our spin technique here is intended to take advantage of the fact
// that sched_yield() takes about a hundred nanoseconds. But Windows
// SleepEx(0, 0) a.k.a. NtYieldExecution() takes a whole millisecond
// and it matters not whether our intent is to yielding or sleeping,
// since we use the SleepEx() function to implement both. Therefore,
// there's no reason to use SpinNanosleep() on Windows.
return false;
}
if (clock != CLOCK_REALTIME && //
clock != CLOCK_REALTIME_PRECISE && //
clock != CLOCK_MONOTONIC && //
clock != CLOCK_MONOTONIC_RAW && //
clock != CLOCK_MONOTONIC_PRECISE) {
return false;
}
if (!flags) {
return timespec_cmp(*req, GetNanosleepLatency()) < 0;
}
// We need a clock_gettime() system call to perform this check if the
// sleep request is an absolute timestamp. So we avoid doing that on
// systems where sleep latency isn't too outrageous.
if (timespec_cmp(GetNanosleepLatency(), timespec_fromnanos(50 * 1000)) < 0) {
return false;
}
e = errno;
if (__clock_gettime_get(0)(clock, &now)) {
// punt to the nanosleep system call
errno = e;
return false;
}
return timespec_cmp(*req, now) < 0 ||
timespec_cmp(timespec_sub(*req, now), GetNanosleepLatency()) < 0;
}
/**
* Sleeps for particular amount of time.
*
@@ -207,12 +55,12 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
*
* struct timespec rel, now, abs;
* clock_gettime(CLOCK_REALTIME, &now);
* rel = timespec_frommillis(100);
* abs = timespec_add(now, rel);
* rel = _timespec_frommillis(100);
* abs = _timespec_add(now, rel);
* while (clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &abs, 0));
*
* will accurately spin on `EINTR` errors. That way you're not impeding
* signal delivery and you're not loosing precision on the wait timeout.
* signal delivery and you're not losing precision on your wait timeout.
* This function has first-class support on Linux, FreeBSD, and NetBSD;
* on OpenBSD it's good; on XNU it's bad; and on Windows it's ugly.
*
@@ -226,43 +74,51 @@ static bool ShouldUseSpinNanosleep(int clock, int flags,
* if flags is `TIMER_ABSTIME` then `rem` is ignored
* @return 0 on success, or errno on error
* @raise EINTR when a signal got delivered while we were waiting
* @raise ECANCELED if thread was cancelled in masked mode
* @raise ENOTSUP if `clock` is known but we can't use it here
* @raise EFAULT if `req` or null or bad memory was passed
* @raise EINVAL if `clock` is unknown to current platform
* @raise EINVAL if `flags` has an unrecognized value
* @raise EINVAL if `req->tv_nsec ∉ [0,1000000000)`
* @raise ENOSYS on bare metal
* @cancellationpoint
* @returnserrno
* @norestart
*/
errno_t clock_nanosleep(int clock, int flags, const struct timespec *req,
struct timespec *rem) {
int rc;
LOCKTRACE("clock_nanosleep(%s, %s, %s) → ...", DescribeClockName(clock),
DescribeSleepFlags(flags), DescribeTimespec(0, req));
if (IsMetal()) {
rc = ENOSYS;
} else if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
(rem && !__asan_is_valid_timespec(rem))))) {
rc = EFAULT;
int rc, e = errno;
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
(rem && !__asan_is_valid_timespec(rem))))) {
rc = efault();
} else if (clock == 127 || //
(flags & ~TIMER_ABSTIME) || //
req->tv_sec < 0 || //
!(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
rc = EINVAL;
} else if (ShouldUseSpinNanosleep(clock, flags, req)) {
rc = SpinNanosleep(clock, flags, req, rem);
} else {
rc = einval();
} else if (IsLinux() || IsFreebsd() || IsNetbsd()) {
rc = sys_clock_nanosleep(clock, flags, req, rem);
} else if (IsXnu()) {
rc = sys_clock_nanosleep_xnu(clock, flags, req, rem);
} else if (IsOpenbsd()) {
rc = sys_clock_nanosleep_openbsd(clock, flags, req, rem);
} else if (IsMetal()) {
rc = enosys();
} else {
rc = sys_clock_nanosleep_nt(clock, flags, req, rem);
}
if (rc == -1) {
rc = errno;
errno = e;
}
#if SYSDEBUG
if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
if (!(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) {
STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock),
DescribeSleepFlags(flags), DescribeTimespec(0, req),
DescribeTimespec(rc, rem), DescribeErrno(rc));
DescribeTimespec(rc, rem), DescribeErrnoResult(rc));
}
#endif
return rc;
}
+1 -8
View File
@@ -18,22 +18,15 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/fd.internal.h"
#include "libc/errno.h"
#include "libc/intrin/weaken.h"
#include "libc/nt/enum/filetype.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/sysv/consts/o.h"
void sys_fcntl_nt_lock_cleanup(int) _Hide;
textwindows int sys_close_nt(struct Fd *fd, int fildes) {
textwindows int sys_close_nt(struct Fd *fd) {
int e;
bool ok = true;
if (_weaken(sys_fcntl_nt_lock_cleanup)) {
_weaken(sys_fcntl_nt_lock_cleanup)(fildes);
}
if (fd->kind == kFdFile && ((fd->flags & O_ACCMODE) != O_RDONLY &&
GetFileType(fd->handle) == kNtFileTypeDisk)) {
// Like Linux, closing a file on Windows doesn't guarantee it's
+2 -2
View File
@@ -16,10 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/struct/fd.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
@@ -81,7 +81,7 @@ int close(int fd) {
} else if (__isfdkind(fd, kFdFile) || //
__isfdkind(fd, kFdConsole) || //
__isfdkind(fd, kFdProcess)) { //
rc = sys_close_nt(g_fds.p + fd, fd);
rc = sys_close_nt(g_fds.p + fd);
} else {
rc = eio();
}
+5 -3
View File
@@ -27,9 +27,12 @@
/**
* Closes extra file descriptors, e.g.
*
* if (closefrom(3))
* for (int i = 3; i < 256; ++i)
* // close all non-stdio file descriptors
* if (closefrom(3) == -1) {
* for (int i = 3; i < 256; ++i) {
* close(i);
* }
* }
*
* @return 0 on success, or -1 w/ errno
* @raise EBADF if `first` is negative
@@ -37,7 +40,6 @@
* @raise EBADF on OpenBSD if `first` is greater than highest fd
* @raise EINVAL if flags are bad or first is greater than last
* @raise EMFILE if a weird race condition happens on Linux
* @raise ECANCELED if thread was cancelled in masked mode
* @raise EINTR possibly on OpenBSD
* @raise ENOMEM on Linux maybe
*/
+4 -18
View File
@@ -16,18 +16,16 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/calls/calls.h"
#include "libc/intrin/strace.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/log/libfatal.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
static bool IsExePath(const char *s, size_t n) {
@@ -50,9 +48,6 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
size_t pathlen) {
size_t suffixlen;
suffixlen = strlen(suffix);
if (IsWindows() && suffixlen == 0 && !IsExePath(name, namelen) &&
!IsComPath(name, namelen))
return false;
if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false;
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
path[pathlen] = !IsWindows() ? '/'
@@ -62,16 +57,7 @@ static bool AccessCommand(const char *name, char *path, size_t pathsz,
}
memcpy(path + pathlen, name, namelen);
memcpy(path + pathlen + namelen, suffix, suffixlen + 1);
if (!access(path, X_OK)) {
struct stat st;
if (!stat(path, &st)) {
if (S_ISREG(st.st_mode)) {
return true;
} else {
errno = EACCES;
}
}
}
if (!access(path, X_OK)) return true;
if (errno == EACCES || *err != EACCES) *err = errno;
return false;
}
-10
View File
@@ -16,9 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/cp.internal.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/sigset.internal.h"
@@ -41,7 +39,6 @@ static bool HasCopyFileRange(void) {
bool ok;
int e, rc;
e = errno;
BLOCK_CANCELLATIONS;
if (IsLinux()) {
// We modernize our detection by a few years for simplicity.
// This system call is chosen since it's listed by pledge().
@@ -52,7 +49,6 @@ static bool HasCopyFileRange(void) {
} else {
ok = false;
}
ALLOW_CANCELLATIONS;
errno = e;
return ok;
}
@@ -85,7 +81,6 @@ static void copy_file_range_init(void) {
* @raise EBADF if `infd` or `outfd` aren't open files or append-only
* @raise EPERM if `fdout` refers to an immutable file on Linux
* @raise ENOTSUP if `infd` or `outfd` is a zip file descriptor
* @raise ECANCELED if thread was cancelled in masked mode
* @raise EINVAL if ranges overlap or `flags` is non-zero
* @raise EFBIG if `setrlimit(RLIMIT_FSIZE)` is exceeded
* @raise EFAULT if one of the pointers memory is bad
@@ -98,15 +93,12 @@ static void copy_file_range_init(void) {
* @raise EIO if a low-level i/o error happens
* @see sendfile() for seekable → socket
* @see splice() for fd ↔ pipe
* @cancellationpoint
*/
ssize_t copy_file_range(int infd, int64_t *opt_in_out_inoffset, int outfd,
int64_t *opt_in_out_outoffset, size_t uptobytes,
uint32_t flags) {
ssize_t rc;
pthread_once(&g_copy_file_range.once, copy_file_range_init);
BEGIN_CANCELLATION_POINT;
if (!g_copy_file_range.ok) {
rc = enosys();
} else if (IsAsan() && ((opt_in_out_inoffset &&
@@ -120,8 +112,6 @@ ssize_t copy_file_range(int infd, int64_t *opt_in_out_inoffset, int outfd,
rc = sys_copy_file_range(infd, opt_in_out_inoffset, outfd,
opt_in_out_outoffset, uptobytes, flags);
}
END_CANCELLATION_POINT;
STRACE("copy_file_range(%d, %s, %d, %s, %'zu, %#x) → %'ld% m", infd,
DescribeInOutInt64(rc, opt_in_out_inoffset), outfd,
DescribeInOutInt64(rc, opt_in_out_outoffset), uptobytes, flags);
-59
View File
@@ -1,59 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2022 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/cp.internal.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/tls.h"
#ifdef MODE_DBG
int begin_cancellation_point(void) {
int state = 0;
struct CosmoTib *tib;
struct PosixThread *pt;
if (__enable_tls) {
tib = __get_tls();
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
state = pt->flags & PT_INCANCEL;
pt->flags |= PT_INCANCEL;
}
}
return state;
}
void end_cancellation_point(int state) {
struct CosmoTib *tib;
struct PosixThread *pt;
if (__enable_tls) {
tib = __get_tls();
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
pt->flags &= ~PT_INCANCEL;
pt->flags |= state;
}
}
}
void report_cancellation_point(void) {
BLOCK_CANCELLATIONS;
_bt("error: need BEGIN/END_CANCELLATION_POINT\n");
ALLOW_CANCELLATIONS;
}
#endif /* MODE_DBG */
-25
View File
@@ -1,25 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_
#define COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int begin_cancellation_point(void);
void end_cancellation_point(int);
#ifndef MODE_DBG
#define BEGIN_CANCELLATION_POINT (void)0
#define END_CANCELLATION_POINT (void)0
#else
#define BEGIN_CANCELLATION_POINT \
do { \
int _Cp; \
_Cp = begin_cancellation_point()
#define END_CANCELLATION_POINT \
end_cancellation_point(_Cp); \
} \
while (0)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_CP_INTERNAL_H_ */
-1
View File
@@ -31,7 +31,6 @@
* @param mode is octal bits, e.g. 0644 usually
* @return file descriptor, or -1 w/ errno
* @see openat() for further documentation
* @cancellationpoint
* @asyncsignalsafe
* @restartable
* @threadsafe
+25 -14
View File
@@ -31,11 +31,13 @@
// Implements dup(), dup2(), dup3(), and F_DUPFD for Windows.
textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
int64_t rc, proc, handle;
_unassert(oldfd >= 0);
_unassert(newfd >= -1);
_unassert(!(flags & ~O_CLOEXEC));
__fds_lock();
if (!__isfdopen(oldfd) || newfd < -1 ||
if (oldfd >= g_fds.n ||
(g_fds.p[oldfd].kind != kFdFile && g_fds.p[oldfd].kind != kFdSocket &&
g_fds.p[oldfd].kind != kFdConsole)) {
__fds_unlock();
@@ -43,18 +45,27 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
}
// allocate a new file descriptor
if (newfd == -1) {
if ((newfd = __reservefd_unlocked(start)) == -1) {
__fds_unlock();
return -1;
}
} else {
if (__ensurefds_unlocked(newfd) == -1) {
__fds_unlock();
return -1;
}
if (g_fds.p[newfd].kind) {
sys_close_nt(g_fds.p + newfd, newfd);
for (;;) {
if (newfd == -1) {
if ((newfd = __reservefd_unlocked(start)) == -1) {
__fds_unlock();
return -1;
}
break;
} else {
if (__ensurefds_unlocked(newfd) == -1) {
__fds_unlock();
return -1;
}
if (g_fds.p[newfd].kind) {
__fds_unlock();
close(newfd);
__fds_lock();
}
if (!g_fds.p[newfd].kind) {
g_fds.p[newfd].kind = kFdReserved;
break;
}
}
}
@@ -75,7 +86,7 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
}
rc = newfd;
} else {
__releasefd(newfd);
__releasefd_unlocked(newfd);
rc = __winerr();
}
+26 -41
View File
@@ -16,10 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/blocksigs.internal.h"
#include "libc/calls/calls.h"
#include "libc/calls/execve-sysv.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@@ -38,22 +35,16 @@ static bool CanExecute(const char *path) {
return !sys_faccessat(AT_FDCWD, path, X_OK, 0);
}
bool IsAPEMagic(char buf[8]) {
return READ64LE(buf) == READ64LE("MZqFpD='") ||
READ64LE(buf) == READ64LE("JTqFpD='");
}
static bool IsApeBinary(const char *path) {
int fd;
char buf[8];
bool res = false;
// TODO(jart): Should we block signals too?
BLOCK_CANCELLATIONS;
if ((fd = sys_open(path, O_RDONLY, 0)) != -1) {
res = sys_read(fd, buf, 8) == 8 && IsAPEMagic(buf);
if (sys_read(fd, buf, 8) == 8 && READ64LE(buf) == READ64LE("MZqFpD='")) {
res = true;
}
sys_close(fd);
}
ALLOW_CANCELLATIONS;
return res;
}
@@ -70,41 +61,35 @@ static const char *Join(const char *a, const char *b, char buf[PATH_MAX]) {
}
int sys_execve(const char *prog, char *const argv[], char *const envp[]) {
int e;
size_t i;
int e, rc;
char *buf;
char **shargs;
const char *ape;
e = errno;
__sys_execve(prog, argv, envp);
if (errno == ENOEXEC) {
for (i = 0; argv[i];) ++i;
buf = alloca(PATH_MAX);
shargs = alloca((i + 4) * sizeof(char *));
if (IsApeBinary(prog) &&
(CanExecute((ape = "/usr/bin/ape")) ||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
firstnonnull(getenv("HOME"), ".")),
".ape", buf))) ||
CanExecute(
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
shargs[0] = ape;
shargs[1] = "-";
shargs[2] = prog;
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
errno = e;
rc = __sys_execve(shargs[0], shargs, envp);
} else if (CanExecute(prog)) {
shargs[0] = _PATH_BSHELL;
shargs[1] = prog;
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
errno = e;
rc = __sys_execve(shargs[0], shargs, envp);
} else {
rc = enoexec();
}
if (errno != ENOEXEC) return -1;
for (i = 0; argv[i];) ++i;
buf = alloca(PATH_MAX);
shargs = alloca((i + 4) * sizeof(char *));
if (IsApeBinary(prog) &&
(CanExecute((ape = "/usr/bin/ape")) ||
CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"),
firstnonnull(getenv("HOME"), ".")),
".ape", buf))) ||
CanExecute(
(ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) {
shargs[0] = ape;
shargs[1] = "-";
shargs[2] = prog;
memcpy(shargs + 3, argv, (i + 1) * sizeof(char *));
} else if (CanExecute(prog)) {
shargs[0] = _PATH_BSHELL;
shargs[1] = prog;
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
} else {
rc = -1;
return enoexec();
}
return rc;
errno = e;
return __sys_execve(shargs[0], shargs, envp);
}
-10
View File
@@ -1,10 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#define COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
bool IsAPEMagic(char[8]) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_EXECVE_SYSV_H_ */
+27 -27
View File
@@ -23,7 +23,6 @@
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/likely.h"
#include "libc/intrin/promises.internal.h"
@@ -32,7 +31,6 @@
#include "libc/log/libfatal.internal.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
/**
* Replaces current process with program.
@@ -52,37 +50,39 @@
* @vforksafe
*/
int execve(const char *prog, char *const argv[], char *const envp[]) {
struct ZiposUri uri;
int rc;
size_t i;
if (!prog || !argv || !envp ||
(IsAsan() && (!__asan_is_valid_str(prog) || //
!__asan_is_valid_strlist(argv) || //
!__asan_is_valid_strlist(envp)))) {
(IsAsan() &&
(!__asan_is_valid(prog, 1) || !__asan_is_valid_strlist(argv) ||
!__asan_is_valid_strlist(envp)))) {
rc = efault();
} else {
STRACE("execve(%#s, %s, %s) → ...", prog, DescribeStringList(argv),
DescribeStringList(envp));
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
if (_weaken(__zipos_parseuri) &&
(_weaken(__zipos_parseuri)(prog, &uri) != -1)) {
rc = _weaken(__zipos_open)(&uri, O_RDONLY | O_CLOEXEC, 0);
if (rc != -1) {
const int zipFD = rc;
strace_enabled(-1);
rc = fexecve(zipFD, argv, envp);
close(zipFD);
strace_enabled(+1);
}
} else if (!IsWindows()) {
rc = sys_execve(prog, argv, envp);
} else {
rc = sys_execve_nt(prog, argv, envp);
#ifdef SYSDEBUG
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "execve(%#s, {", prog);
for (i = 0; argv[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", argv[i]);
}
kprintf("}, {");
for (i = 0; envp[i]; ++i) {
if (i) kprintf(", ");
kprintf("%#s", envp[i]);
}
kprintf("})\n");
}
#endif
if (!IsWindows()) {
rc = 0;
if (IsLinux() && __execpromises && _weaken(sys_pledge_linux)) {
rc = _weaken(sys_pledge_linux)(__execpromises, __pledge_mode);
}
if (!rc) {
rc = sys_execve(prog, argv, envp);
}
} else {
rc = sys_execve_nt(prog, argv, envp);
}
}
STRACE("execve(%#s) failed %d% m", prog, rc);
Loaded 100 of 1596 files, more files were not shown because too many files have changed in this diff. Show more