mirror of
https://github.com/jart/cosmopolitan.git
synced 2026-11-08 17:19:47 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fea68b142e | ||
|
|
8f001857de | ||
|
|
7b26b42769 | ||
|
|
555260d2e5 | ||
|
|
0740e68ea0 | ||
|
|
9c5a7795ad | ||
|
|
f4ff1729d1 | ||
|
|
4381b3d925 | ||
|
|
30140812f0 | ||
|
|
c64e7eaf7c | ||
|
|
a5fa90a21f | ||
|
|
050062bcbb | ||
|
|
827f25f054 | ||
|
|
790c661317 | ||
|
|
c4eb701d56 | ||
|
|
116bda997e | ||
|
|
c03359c637 | ||
|
|
0305194d98 | ||
|
|
55ddf73484 | ||
|
|
569c031934 | ||
|
|
9b89a7c51d | ||
|
|
b5cb71ab84 | ||
|
|
3de35e196c | ||
|
|
5dff63a31c | ||
|
|
cdb2284f0d | ||
|
|
333768440c | ||
|
|
cfcf5918bc | ||
|
|
bae7367774 | ||
|
|
155b378a39 | ||
|
|
e9272f03fb | ||
|
|
3265324e00 | ||
|
|
c3208eb9d5 | ||
|
|
1729a8259c | ||
|
|
094ccbb4bd | ||
|
|
e97f1a99cf | ||
|
|
1db76c288e | ||
|
|
f68151c010 | ||
|
|
2d17ab016c | ||
|
|
c32e2d4486 | ||
|
|
5140897c27 | ||
|
|
9f963dc597 | ||
|
|
0547eabcd6 | ||
|
|
b73e35c6fa | ||
|
|
0e2b1bfeed | ||
|
|
571c2c3c69 | ||
|
|
b7c07d548c | ||
|
|
6c323383e5 | ||
|
|
de511bc71a | ||
|
|
114176c304 | ||
|
|
a849a63771 | ||
|
|
4339d9f15e | ||
|
|
d5c9308a43 | ||
|
|
8bd9ad8342 | ||
|
|
3fdb1c14f1 | ||
|
|
598640864a | ||
|
|
d861d2787b | ||
|
|
dbf12c30b0 | ||
|
|
11ec60d5fc | ||
|
|
55c6297e13 | ||
|
|
12d9e1e128 | ||
|
|
7ff0ea8c13 | ||
|
|
7de2f229a7 | ||
|
|
4b4ea046c4 | ||
|
|
44c315d789 | ||
|
|
8cd4248f7f | ||
|
|
d721ff8938 | ||
|
|
9be364d40a | ||
|
|
af24f21556 | ||
|
|
b0287ef34c | ||
|
|
6a04bc3318 | ||
|
|
8dd4ec68d0 | ||
|
|
b9dc74b672 | ||
|
|
e1590e1e38 | ||
|
|
8569704c1d | ||
|
|
9c017c98d3 | ||
|
|
74879bf067 | ||
|
|
8a3d8497e3 | ||
|
|
3c00d8c29c | ||
|
|
1ef955c33b | ||
|
|
494d74271b | ||
|
|
12212894eb | ||
|
|
a4522fba8d | ||
|
|
0c70e8963d | ||
|
|
b66bd064d8 | ||
|
|
c5c4dfcd21 | ||
|
|
c5659b93f8 | ||
|
|
263711965f | ||
|
|
33b5b5b312 | ||
|
|
d213a48190 | ||
|
|
3f0414e1cb | ||
|
|
adaaeb7dd0 | ||
|
|
164e2ab27b | ||
|
|
d2cec808dc | ||
|
|
91a3252434 | ||
|
|
8cab92a069 | ||
|
|
5a632cf72d | ||
|
|
7b74f6e20e | ||
|
|
253cc1754b | ||
|
|
8722006c46 | ||
|
|
58d22c7c3d | ||
|
|
2227cefa5d | ||
|
|
f0bf9f3389 | ||
|
|
04cd62c319 | ||
|
|
e204fc0820 | ||
|
|
b76540105d | ||
|
|
14e3025749 | ||
|
|
51fa5535ac | ||
|
|
bea0b55576 | ||
|
|
57b39d8793 | ||
|
|
d52170ca34 | ||
|
|
bf757c4646 | ||
|
|
99a92048b4 | ||
|
|
2f1679e5cf | ||
|
|
ee49b71be2 | ||
|
|
73845be1f0 | ||
|
|
35203c0551 | ||
|
|
83d41e4588 | ||
|
|
a51edaa0db | ||
|
|
d76dfadc7a | ||
|
|
8835b82a7c | ||
|
|
2827df688a |
No files matched your search
@@ -4,10 +4,12 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "vista"
|
||||
- "flake"
|
||||
pull_request:
|
||||
branches:
|
||||
- "master"
|
||||
- "vista"
|
||||
|
||||
# run workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -11,3 +11,5 @@ __pycache__
|
||||
/TAGS
|
||||
/bx_enh_dbg.ini
|
||||
/tool/emacs/*.elc
|
||||
/perf.data
|
||||
/perf.data.old
|
||||
Vendored
+2
-2
@@ -43,10 +43,10 @@
|
||||
"forcealignargpointer=",
|
||||
"noasan=",
|
||||
"noubsan=",
|
||||
"testonly=",
|
||||
"donothing=",
|
||||
"nosideeffect=",
|
||||
"unreachable=",
|
||||
"unreachable=",,
|
||||
"notpossible=",
|
||||
"thatispacked=",
|
||||
"dontthrow=",
|
||||
"nocallback=",
|
||||
|
||||
@@ -92,7 +92,9 @@ o/$(MODE): \
|
||||
rw:/dev/null \
|
||||
w:o/stack.log \
|
||||
/etc/hosts \
|
||||
~/.runit.psk
|
||||
~/.runit.psk \
|
||||
/proc/self/status \
|
||||
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
|
||||
|
||||
PKGS =
|
||||
|
||||
@@ -115,10 +117,12 @@ include third_party/xed/xed.mk # │
|
||||
include third_party/zlib/zlib.mk # │
|
||||
include libc/elf/elf.mk # │
|
||||
include ape/ape.mk # │
|
||||
include libc/fmt/fmt.mk #─┘
|
||||
include libc/fmt/fmt.mk # │
|
||||
include libc/vga/vga.mk #─┘
|
||||
include libc/calls/calls.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 libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
|
||||
@@ -158,6 +162,8 @@ include third_party/maxmind/maxmind.mk
|
||||
include net/finger/finger.mk
|
||||
include third_party/double-conversion/double-conversion.mk
|
||||
include third_party/lua/lua.mk
|
||||
include third_party/sed/sed.mk
|
||||
include third_party/awk/awk.mk
|
||||
include third_party/make/make.mk
|
||||
include third_party/finger/finger.mk
|
||||
include third_party/argon2/argon2.mk
|
||||
@@ -206,6 +212,7 @@ include test/libc/fmt/test.mk
|
||||
include test/libc/dns/test.mk
|
||||
include test/libc/time/test.mk
|
||||
include test/libc/stdio/test.mk
|
||||
include test/libc/zipos/test.mk
|
||||
include test/libc/release/test.mk
|
||||
include test/libc/test.mk
|
||||
include test/net/http/test.mk
|
||||
@@ -293,6 +300,7 @@ COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_MEM \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
LIBC_RUNTIME \
|
||||
THIRD_PARTY_NSYNC \
|
||||
LIBC_ELF \
|
||||
LIBC_CALLS \
|
||||
LIBC_SYSV_CALLS \
|
||||
@@ -314,7 +322,8 @@ COSMOPOLITAN_OBJECTS = \
|
||||
LIBC_SYSV \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NT_KERNEL32 \
|
||||
LIBC_NEXGEN32E
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_VGA
|
||||
|
||||
COSMOPOLITAN_HEADERS = \
|
||||
APE \
|
||||
@@ -331,6 +340,7 @@ COSMOPOLITAN_HEADERS = \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_XED \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
@@ -339,6 +349,7 @@ COSMOPOLITAN_HEADERS = \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
LIBC_VGA \
|
||||
NET_HTTP \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_GDTOA \
|
||||
@@ -359,6 +370,7 @@ o/cosmopolitan.h: \
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@),libc/integral/normalize.inc $(foreach x,$(COSMOPOLITAN_HEADERS),$($(x)_HDRS)))
|
||||
@$(COMPILE) -AROLLUP -T$@ o/$(MODE)/tool/build/rollup.com @$(TMPDIR)/$(subst /,_,$@) >$@
|
||||
|
||||
o/cosmopolitan.html: .UNSANDBOXED = 1
|
||||
o/cosmopolitan.html: \
|
||||
o/$(MODE)/third_party/chibicc/chibicc.com.dbg \
|
||||
$(filter-out %.s,$(foreach x,$(COSMOPOLITAN_OBJECTS),$($(x)_SRCS))) \
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||

|
||||
|
||||
[](https://github.com/jart/cosmopolitan/actions/workflows/build.yml)
|
||||
# Cosmopolitan
|
||||
# Cosmopolitan (Vista Edition)
|
||||
|
||||
**This is a community supported legacy branch of Cosmopolitan 2.0 that's
|
||||
intended to preserve compatibility with Windows Vista and Windows 7.**
|
||||
|
||||
[Cosmopolitan Libc](https://justine.lol/cosmopolitan/index.html) makes C
|
||||
a build-once run-anywhere language, like Java, except it doesn't need an
|
||||
@@ -23,8 +26,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.0.zip
|
||||
unzip cosmopolitan-amalgamation-2.0.zip
|
||||
wget https://justine.lol/cosmopolitan/cosmopolitan-amalgamation-2.0.1.zip
|
||||
unzip cosmopolitan-amalgamation-2.0.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 \
|
||||
@@ -40,6 +43,21 @@ You now have a portable program.
|
||||
bash -c './hello.com' # zsh/fish workaround (we patched them in 2021)
|
||||
```
|
||||
|
||||
If `./hello.com` executed on Linux throws an error about not finding an
|
||||
interpreter, it should be fixed by running the following command (although
|
||||
note that it may not survive a system restart):
|
||||
|
||||
```sh
|
||||
sudo sh -c "echo ':APE:M::MZqFpD::/bin/sh:' >/proc/sys/fs/binfmt_misc/register"
|
||||
```
|
||||
|
||||
If the same command produces puzzling errors on WSL or WINE when using
|
||||
Redbean 2.x, they may be fixed by disabling binfmt_misc:
|
||||
|
||||
```sh
|
||||
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 to `${TMPDIR:-${HOME:-.}}`
|
||||
@@ -196,7 +214,7 @@ For further details, see [//build/config.mk](build/config.mk).
|
||||
|
||||
Here's the recommended `~/.gdbinit` config:
|
||||
|
||||
```
|
||||
```gdb
|
||||
set host-charset UTF-8
|
||||
set target-charset UTF-8
|
||||
set target-wide-charset UTF-8
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/macho.internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/nexgen32e/vidya.internal.h"
|
||||
#include "libc/nt/pedef.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
@@ -250,6 +249,7 @@ pc: cld
|
||||
xor %cx,%cx # current cylinder
|
||||
xor %dh,%dh # current head
|
||||
mov $v_ape_realsectors,%di # total sectors
|
||||
sub $v_ape_realslacksectors,%di
|
||||
3: call pcread
|
||||
dec %di
|
||||
jnz 3b
|
||||
@@ -328,7 +328,7 @@ dsknfo: push %bx
|
||||
movpp %es,%ds
|
||||
xor %si,%si
|
||||
mov %si,%es
|
||||
mov $0x1510,%si # mman::pc_drive_base_table
|
||||
mov $0x1d10,%si # mman::pc_drive_base_table
|
||||
xchg %si,%di
|
||||
movsw #→ headunloadtime, headloadtime
|
||||
movsw #→ shutofftime, bytespersector
|
||||
@@ -381,11 +381,11 @@ pcread: push %ax
|
||||
add $512>>4,%si
|
||||
mov %si,%es
|
||||
inc %al # ++sector
|
||||
cmp 0x151c,%al # mman::pc_drive_last_sector
|
||||
cmp 0x1d1c,%al # mman::pc_drive_last_sector
|
||||
jbe 2f
|
||||
mov $1,%al
|
||||
inc %dh # ++head
|
||||
cmp 0x1520,%dh # mman::pc_drive_last_head
|
||||
cmp 0x1d20,%dh # mman::pc_drive_last_head
|
||||
jbe 2f
|
||||
xor %dh,%dh
|
||||
inc %cx # ++cylinder
|
||||
@@ -484,19 +484,19 @@ ape.mbrpad:
|
||||
ape_disk:
|
||||
.stub ape.diskid,quad
|
||||
.org 0x1be,0x00
|
||||
.macro .partn x
|
||||
.stub ape.part\x\().status,byte # 0=absent / 0x80=present
|
||||
.stub ape.part\x\().first.head,byte # in low 6 bits
|
||||
.stub ape.part\x\().first.cylinder,byte
|
||||
.stub ape.part\x\().first.sector,byte
|
||||
.stub ape.part\x\().filesystem,byte
|
||||
.stub ape.part\x\().last.head,byte
|
||||
.stub ape.part\x\().last.cylinder,byte
|
||||
.stub ape.part\x\().last.sector,byte
|
||||
.stub ape.part\x\().lba,long # c₀*Cₙ + h₀*Hₙ + s₀*Sₙ
|
||||
.stub ape.part\x\().sector.count,long # sectors are 512 bytes
|
||||
.macro .partn x:req sta h0 s0 c0 fs h9 s9 c9 lba0 nsec
|
||||
.stub ape.part\x\().status,byte,\sta # 0=non-boot / 0x80=active
|
||||
.stub ape.part\x\().first.head,byte,\h0
|
||||
.stub ape.part\x\().first.sector,byte,\s0 # in low 6 bits
|
||||
.stub ape.part\x\().first.cylinder,byte,\c0
|
||||
.stub ape.part\x\().filesystem,byte,\fs
|
||||
.stub ape.part\x\().last.head,byte,\h9
|
||||
.stub ape.part\x\().last.sector,byte,\s9
|
||||
.stub ape.part\x\().last.cylinder,byte,\c9
|
||||
.stub ape.part\x\().lba,long,\lba0 # c₀*Cₙ + h₀*Hₙ + s₀*Sₙ
|
||||
.stub ape.part\x\().sector.count,long,\nsec # sectors are 512 bytes
|
||||
.endm
|
||||
.partn 1
|
||||
.partn 1,0x80,0,1,0,0x7f,0xff,0xff,0xff,0,0xffffffff
|
||||
.partn 2
|
||||
.partn 3
|
||||
.partn 4
|
||||
@@ -568,11 +568,11 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
||||
.ascii "t=\"${TMPDIR:-${HOME:-.}}/.ape\"\n"
|
||||
.ascii "[ -x \"$t\" ] || {\n"
|
||||
.ascii "mkdir -p \"${t%/*}\" &&\n"
|
||||
.ascii "dd if=\"$o\" of=\"$t.$$\" skip=\""
|
||||
.ascii "dd if=\"$o\" of=\"$t.$$\" skip="
|
||||
.shstub ape_loader_dd_skip,2
|
||||
.ascii "\" count=\""
|
||||
.ascii " count="
|
||||
.shstub ape_loader_dd_count,2
|
||||
.ascii "\" bs=64 2>/dev/null\n"
|
||||
.ascii " bs=64 2>/dev/null\n"
|
||||
#if SupportsXnu()
|
||||
.ascii "[ -d /Applications ] && "
|
||||
.ascii "dd if=\"$t.$$\""
|
||||
@@ -636,11 +636,11 @@ apesh: .ascii "'\n#'\"\n" # sixth edition shebang
|
||||
.ascii "dd if=\"$o\""
|
||||
.ascii " of=\"$o\""
|
||||
.ascii " bs=8"
|
||||
.ascii " skip=\""
|
||||
.ascii " skip="
|
||||
.shstub ape_macho_dd_skip,2
|
||||
.ascii "\" count=\""
|
||||
.ascii " count="
|
||||
.shstub ape_macho_dd_count,2
|
||||
.ascii "\" conv=notrunc 2>/dev/null\n"
|
||||
.ascii " conv=notrunc 2>/dev/null\n"
|
||||
#endif /* XNU */
|
||||
.ascii "[ x\"$1\" = x--assimilate ] && exit 0\n"
|
||||
#ifndef APE_NO_MODIFY_SELF
|
||||
@@ -1290,27 +1290,38 @@ lcheck: pushf # check for i8086 / i8088 / i80186
|
||||
// Gets memory map from BIOS.
|
||||
e820: mov $0x0510>>4,%di # mman::e820
|
||||
mov %di,%es
|
||||
xor %edi,%edi # es:di is destination buffer
|
||||
xor %di,%di # es:di is destination buffer
|
||||
xor %ebx,%ebx # ebx is an api state tracker
|
||||
1: mov $0xE820,%eax # magic
|
||||
mov $8+8+4+4,%ecx # sizeof(struct SmapEntry)
|
||||
mov $0x534d4150,%edx # magic number
|
||||
movl $1,8+8+4/*SmapEntry::acpi3*/(%di) # prefill ACPI attributes;
|
||||
# apparently some buggy BIOSes say
|
||||
# that they return this field, yet
|
||||
# do not fill it correctly
|
||||
int $0x15 # ax,bx,cx,dx,di → ax,bx,cx
|
||||
jc 9f # cf = unsupported or abuse
|
||||
cmp %edx,%eax # more magic means success
|
||||
jne 9f
|
||||
test %cx,%cx # discard empty results
|
||||
jz 5f
|
||||
mov 8/*LODWORD(SmapEntry::size)*/(%di),%eax
|
||||
or 8+4/*HIDWORD(SmapEntry::size)*/(%di),%eax
|
||||
jz 5f
|
||||
cmp $8+8+4+1,%cx # discard if ignore flag
|
||||
jb 4f
|
||||
testb $1/*ignore*/,8+8+4/*SmapEntry::__acpi3*/(%di)
|
||||
jnz 5f
|
||||
testb $1/*don't ignore*/,8+8+4/*SmapEntry::acpi3*/(%di)
|
||||
jz 5f
|
||||
4: add $8+8+4+4,%di # keep entry
|
||||
5: test %ebx,%ebx # last entry?
|
||||
jz 8f
|
||||
cmp $0x1000,%di
|
||||
cmp $(256-1)*(8+8+4+4),%di
|
||||
jb 1b
|
||||
8: ret
|
||||
8: xor %ax,%ax # add a blank sentinel entry
|
||||
mov $(8+8)/2,%cx
|
||||
cld
|
||||
rep stosw
|
||||
ret
|
||||
9: mov $REAL(str.e820),%di
|
||||
call rldie
|
||||
.endfn e820
|
||||
@@ -1380,9 +1391,16 @@ a20: cli
|
||||
|
||||
// Initializes long mode paging.
|
||||
pinit: push %ds
|
||||
push %es
|
||||
#define SEG 0x79000
|
||||
mov $SEG>>4,%ax
|
||||
mov %ax,%ds
|
||||
mov %ax,%es
|
||||
xor %di,%di
|
||||
xor %ax,%ax
|
||||
mov $(0x7f000-SEG)/2,%cx
|
||||
cld
|
||||
rep stosw
|
||||
movl $0x7d000+PAGE_V+PAGE_RW,0x7e000-SEG # PDPT←PML4T (+)
|
||||
movl $0x7c000+PAGE_V+PAGE_RW,0x7e800-SEG # PDPT←PML4T (-)
|
||||
movl $0x7b000+PAGE_V+PAGE_RW,0x7d000-SEG # PDT←PDPT (+)
|
||||
@@ -1391,13 +1409,14 @@ pinit: push %ds
|
||||
movl $0x79000+PAGE_V+PAGE_RW,0x7a000-SEG # PD←PDT (-)
|
||||
mov $512,%cx # PD±2MB
|
||||
mov $PAGE_V+PAGE_RW,%eax
|
||||
xor %si,%si
|
||||
0: mov %eax,(%si)
|
||||
xor %di,%di
|
||||
0: stosl
|
||||
add $0x1000,%eax
|
||||
add $8,%si
|
||||
scasl # di += 4
|
||||
loop 0b
|
||||
mov $0x7e000,%eax # PML4T←CR3
|
||||
mov %eax,%cr3
|
||||
pop %es
|
||||
pop %ds
|
||||
ret
|
||||
.endfn pinit
|
||||
@@ -1406,7 +1425,7 @@ pinit: push %ds
|
||||
//
|
||||
// @see Intel Manual V3A §4.1.2
|
||||
golong: cli
|
||||
lidt 0x1522 # mman::bad_idt
|
||||
lidt 0x1d22 # mman::bad_idt
|
||||
mov %cr4,%eax
|
||||
or $CR4_PAE|CR4_PGE|CR4_OSFXSR,%eax
|
||||
mov %eax,%cr4
|
||||
@@ -1424,8 +1443,8 @@ golong: cli
|
||||
|
||||
// Long mode is long.
|
||||
.code64
|
||||
long: push $GDT_LONG_DATA
|
||||
pop %rax
|
||||
long: xor %eax,%eax
|
||||
mov $GDT_LONG_DATA,%al
|
||||
mov %eax,%ds
|
||||
mov %eax,%ss
|
||||
mov %eax,%es
|
||||
@@ -1567,6 +1586,7 @@ kernel: movabs $ape_stack_vaddr,%rsp
|
||||
.ldsvar _end
|
||||
.ldsvar _etext
|
||||
.ldsvar v_ape_realsectors
|
||||
.ldsvar v_ape_realslacksectors
|
||||
.ldsvar v_ape_highsectors
|
||||
.ldsvar ape_idata_ro
|
||||
.ldsvar ape_pad_rodata
|
||||
|
||||
+16
-7
@@ -180,6 +180,7 @@
|
||||
#include "libc/elf/def.h"
|
||||
#include "libc/elf/pf2prot.internal.h"
|
||||
#include "libc/nt/pedef.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/zip.h"
|
||||
|
||||
ENTRY(_start)
|
||||
@@ -279,6 +280,7 @@ SECTIONS {
|
||||
KEEP(*(.keep.text))
|
||||
*(.text .stub .text.*)
|
||||
KEEP(*(SORT_BY_NAME(.sort.text.*)))
|
||||
*(.subrs)
|
||||
|
||||
KEEP(*(.ape.pad.test));
|
||||
*(.test.unlikely)
|
||||
@@ -380,17 +382,16 @@ SECTIONS {
|
||||
PROVIDE_HIDDEN(edata = .);
|
||||
KEEP(*(SORT_BY_NAME(.zip.*)))
|
||||
HIDDEN(_ezip = .);
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Ram
|
||||
|
||||
.tdata . : {
|
||||
_tdata_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tdata))
|
||||
*(SORT_BY_ALIGNMENT(.tdata.*))
|
||||
. = ALIGN(16);
|
||||
_tdata_end = .;
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Tls
|
||||
. = ALIGN(PAGESIZE);
|
||||
} :Tls :Ram
|
||||
|
||||
/*END: file content that's loaded by o/s */
|
||||
/*BEGIN: bss memory void */
|
||||
@@ -399,7 +400,7 @@ SECTIONS {
|
||||
_tbss_start = .;
|
||||
*(SORT_BY_ALIGNMENT(.tbss))
|
||||
*(SORT_BY_ALIGNMENT(.tbss.*))
|
||||
. = ALIGN(16);
|
||||
. = ALIGN(TLS_ALIGNMENT);
|
||||
/* the %fs register is based on this location */
|
||||
_tbss_end = .;
|
||||
} :Tls
|
||||
@@ -485,8 +486,10 @@ PFSTUB4(ape_elf_phnum, (ape_phdrs_end - ape_phdrs) / 56);
|
||||
PFSTUB4(ape_elf_shnum, 0);
|
||||
PFSTUB4(ape_elf_shstrndx, 0);
|
||||
|
||||
HIDDEN(_tdata_size = _tdata_end - _tdata_start);
|
||||
HIDDEN(_tls_size = _tbss_end - _tdata_start);
|
||||
HIDDEN(_tdata_size = _tdata_end - _tdata_start);
|
||||
HIDDEN(_tbss_size = _tbss_end - _tbss_start);
|
||||
HIDDEN(_tbss_offset = _tbss_start - _tdata_start);
|
||||
HIDDEN(_tls_content = (_tdata_end - _tdata_start) + (_tbss_end - _tbss_start));
|
||||
|
||||
HIDDEN(__privileged_addr = ROUNDDOWN(__privileged_start, PAGESIZE));
|
||||
@@ -561,6 +564,9 @@ SHSTUB2(ape_loader_dd_count,
|
||||
HIDDEN(v_ape_realsectors =
|
||||
MIN(0x70000 - IMAGE_BASE_REAL,
|
||||
ROUNDUP(RVA(_edata), 4096)) / 512);
|
||||
HIDDEN(v_ape_realslacksectors =
|
||||
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);
|
||||
@@ -708,8 +714,11 @@ ASSERT(!DEFINED(_start16) || REAL(_end) < 65536,
|
||||
ASSERT(IS2POW(ape_stack_memsz),
|
||||
"ape_stack_memsz must be a two power");
|
||||
|
||||
ASSERT(!(ape_stack_vaddr & (ape_stack_memsz - 1)),
|
||||
"ape_stack_vaddr must have ape_stack_memsz alignment; try using STATIC_STACK_ADDR(0x700000000000 - ape_stack_memsz);");
|
||||
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);");
|
||||
|
||||
ASSERT(ALIGNOF(.tdata) <= TLS_ALIGNMENT && ALIGNOF(.tbss) <= TLS_ALIGNMENT,
|
||||
"_Thread_local _Alignof can't exceed TLS_ALIGNMENT");
|
||||
|
||||
/* Let's not be like Knight Capital. */
|
||||
/* NOCROSSREFS_TO(.test .text) */
|
||||
|
||||
+19
@@ -63,6 +63,24 @@ o/$(MODE)/ape/ape.lds: \
|
||||
ape/macros.internal.h \
|
||||
ape/relocations.h \
|
||||
libc/intrin/bits.h \
|
||||
libc/thread/tls.h \
|
||||
libc/calls/struct/timespec.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
libc/elf/pf2prot.internal.h \
|
||||
libc/macros.internal.h \
|
||||
libc/nt/pedef.internal.h \
|
||||
libc/str/str.h \
|
||||
libc/zip.h
|
||||
|
||||
o/$(MODE)/ape/public/ape.lds: OVERRIDE_CPPFLAGS += -UCOSMO
|
||||
o/$(MODE)/ape/public/ape.lds: \
|
||||
ape/public/ape.lds \
|
||||
ape/ape.lds \
|
||||
ape/macros.internal.h \
|
||||
ape/relocations.h \
|
||||
libc/intrin/bits.h \
|
||||
libc/thread/tls.h \
|
||||
libc/calls/struct/timespec.h \
|
||||
libc/dce.h \
|
||||
libc/elf/def.h \
|
||||
@@ -159,6 +177,7 @@ o/$(MODE)/ape/ape.macho.dbg: \
|
||||
o/$(MODE)/ape: $(APE_CHECKS) \
|
||||
o/$(MODE)/ape/ape.o \
|
||||
o/$(MODE)/ape/ape.lds \
|
||||
o/$(MODE)/ape/public/ape.lds \
|
||||
o/$(MODE)/ape/ape.elf \
|
||||
o/$(MODE)/ape/ape.macho \
|
||||
o/$(MODE)/ape/ape-copy-self.o \
|
||||
|
||||
+17
-17
@@ -179,7 +179,7 @@ struct ElfPhdr {
|
||||
|
||||
extern char ehdr[];
|
||||
extern char _end[];
|
||||
static void *syscall;
|
||||
static void *syscall_;
|
||||
static char relocated;
|
||||
static struct PathSearcher ps;
|
||||
extern char __syscall_loader[];
|
||||
@@ -275,7 +275,7 @@ __attribute__((__noreturn__)) static void Exit(int rc, int os) {
|
||||
asm volatile("call\t*%2"
|
||||
: /* no outputs */
|
||||
: "a"((IsLinux() ? 60 : 1) | (IsXnu() ? 0x2000000 : 0)), "D"(rc),
|
||||
"rm"(syscall)
|
||||
"rm"(syscall_)
|
||||
: "memory");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -285,7 +285,7 @@ static void Close(int fd, int os) {
|
||||
asm volatile("call\t*%4"
|
||||
: "=a"(ax), "=D"(di)
|
||||
: "0"((IsLinux() ? 3 : 6) | (IsXnu() ? 0x2000000 : 0)), "1"(fd),
|
||||
"rm"(syscall)
|
||||
"rm"(syscall_)
|
||||
: "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ static int Read(int fd, void *data, int size, int os) {
|
||||
asm volatile("call\t*%8"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx)
|
||||
: "0"((IsLinux() ? 0 : 3) | (IsXnu() ? 0x2000000 : 0)), "1"(fd),
|
||||
"2"(data), "3"(size), "rm"(syscall)
|
||||
"2"(data), "3"(size), "rm"(syscall_)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory");
|
||||
return ax;
|
||||
}
|
||||
@@ -306,7 +306,7 @@ static void Write(int fd, const void *data, int size, int os) {
|
||||
asm volatile("call\t*%8"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx)
|
||||
: "0"((IsLinux() ? 1 : 4) | (IsXnu() ? 0x2000000 : 0)), "1"(fd),
|
||||
"2"(data), "3"(size), "rm"(syscall)
|
||||
"2"(data), "3"(size), "rm"(syscall_)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ static void Execve(const char *prog, char **argv, char **envp, int os) {
|
||||
asm volatile("call\t*%8"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx)
|
||||
: "0"(59 | (IsXnu() ? 0x2000000 : 0)), "1"(prog), "2"(argv),
|
||||
"3"(envp), "rm"(syscall)
|
||||
"3"(envp), "rm"(syscall_)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ static int Access(const char *path, int mode, int os) {
|
||||
asm volatile("call\t*%7"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx)
|
||||
: "0"((IsLinux() ? 21 : 33) | (IsXnu() ? 0x2000000 : 0)),
|
||||
"1"(path), "2"(mode), "rm"(syscall)
|
||||
"1"(path), "2"(mode), "rm"(syscall_)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
return ax;
|
||||
}
|
||||
@@ -338,7 +338,7 @@ static int Msyscall(long p, long n, int os) {
|
||||
} else {
|
||||
asm volatile("call\t*%6"
|
||||
: "=a"(ax), "=D"(di), "=S"(si)
|
||||
: "0"(37), "1"(p), "2"(n), "rm"(syscall)
|
||||
: "0"(37), "1"(p), "2"(n), "rm"(syscall_)
|
||||
: "rcx", "rdx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
return ax;
|
||||
}
|
||||
@@ -350,7 +350,7 @@ static int Open(const char *path, int flags, int mode, int os) {
|
||||
asm volatile("call\t*%8"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx)
|
||||
: "0"((IsLinux() ? 2 : 5) | (IsXnu() ? 0x2000000 : 0)),
|
||||
"1"(path), "2"(flags), "3"(mode), "rm"(syscall)
|
||||
"1"(path), "2"(flags), "3"(mode), "rm"(syscall_)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
return ax;
|
||||
}
|
||||
@@ -369,7 +369,7 @@ __attribute__((__noinline__)) static long Mmap(long addr, long size, int prot,
|
||||
"pop\t%%r9"
|
||||
: "=a"(ax), "=D"(di), "=S"(si), "=d"(dx), "+r"(flags_),
|
||||
"+r"(fd_), "+r"(off_)
|
||||
: "rm"(syscall),
|
||||
: "rm"(syscall_),
|
||||
"0"((IsLinux() ? 9
|
||||
: IsFreebsd() ? 477
|
||||
: 197) |
|
||||
@@ -379,7 +379,7 @@ __attribute__((__noinline__)) static long Mmap(long addr, long size, int prot,
|
||||
return ax;
|
||||
}
|
||||
|
||||
static int MunmapLinux(const void *addr, unsigned long size) {
|
||||
int MunmapLinux(const void *addr, unsigned long size) {
|
||||
int ax;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ax)
|
||||
@@ -388,7 +388,7 @@ static int MunmapLinux(const void *addr, unsigned long size) {
|
||||
return ax;
|
||||
}
|
||||
|
||||
static int PrctlLinux(int op, long a, long b, long c, long d) {
|
||||
int PrctlLinux(int op, long a, long b, long c, long d) {
|
||||
int rc;
|
||||
asm volatile("mov\t%5,%%r10\n\t"
|
||||
"mov\t%6,%%r8\n\t"
|
||||
@@ -589,7 +589,7 @@ __attribute__((__noreturn__)) static void Spawn(int os, const char *exe, int fd,
|
||||
// since it probably means a userspace program executed this loader
|
||||
// and passed us a custom syscall function earlier.
|
||||
if (Msyscall(code, codesize, os) != -1) {
|
||||
syscall = 0;
|
||||
syscall_ = 0;
|
||||
}
|
||||
|
||||
#if TROUBLESHOOT
|
||||
@@ -600,7 +600,7 @@ __attribute__((__noreturn__)) static void Spawn(int os, const char *exe, int fd,
|
||||
// to extend the behavior of this loader in the future. we don't need
|
||||
// to clear the xmm registers since the ape loader should be compiled
|
||||
// with the -mgeneral-regs-only flag.
|
||||
register void *r8 asm("r8") = syscall;
|
||||
register void *r8 asm("r8") = syscall_;
|
||||
asm volatile("xor\t%%eax,%%eax\n\t"
|
||||
"xor\t%%r9d,%%r9d\n\t"
|
||||
"xor\t%%r10d,%%r10d\n\t"
|
||||
@@ -659,10 +659,10 @@ __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, char dl,
|
||||
}
|
||||
|
||||
// get syscall function pointer
|
||||
if (handoff && handoff->syscall) {
|
||||
syscall = handoff->syscall;
|
||||
if (handoff && handoff->systemcall) {
|
||||
syscall_ = handoff->systemcall;
|
||||
} else {
|
||||
syscall = __syscall_loader;
|
||||
syscall_ = __syscall_loader;
|
||||
}
|
||||
|
||||
if (handoff) {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ struct ApeLoader {
|
||||
int os;
|
||||
char *prog;
|
||||
char *page;
|
||||
void *syscall;
|
||||
void *systemcall;
|
||||
};
|
||||
|
||||
#endif /* COSMOPOLITAN_APE_LOADER_H_ */
|
||||
+34
-37
@@ -221,44 +221,41 @@
|
||||
/**
|
||||
* Binary coded decimal support.
|
||||
*
|
||||
* <p>This allows linker scripts to generate dd commands. Leading spaces
|
||||
* need to be inserted so Mac doesn't consider them octal; therefore,
|
||||
* parameters must be quoted; and eight digits should be good enough.
|
||||
* <p>This allows linker scripts to generate dd commands, e.g. ape.lds.
|
||||
* There are a few ways to pad each number to the necessary 8 bytes.
|
||||
* Spaces cannot be prepended because busybox refuses to parse them.
|
||||
* Zeros cannot be prepended because Mac will take numbers as octal.
|
||||
* That leaves appending spaces. The user's shell ought to treat any
|
||||
* unquoted run of spaces as if there was only one, so this is safe.
|
||||
*/
|
||||
#define SHSTUB2(SYM, X) \
|
||||
HIDDEN(SYM##_bcs0 = BCD10K(X)); \
|
||||
HIDDEN(SYM##_bcs1 = BCD(X))
|
||||
#define BCD(X) \
|
||||
((X) == 0 \
|
||||
? 0x20202030 \
|
||||
: (X) < 10 ? 0x30202020 + (((X) % 10) << 24) \
|
||||
: (X) < 100 ? 0x30302020 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) \
|
||||
: (X) < 1000 ? 0x30303020 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) + \
|
||||
(((X) / 100 % 10) << 8) \
|
||||
: 0x30303030 + (((X) % 10) << 24) + \
|
||||
(((X) / 10 % 10) << 16) + \
|
||||
(((X) / 100 % 10) << 8) + \
|
||||
(((X) / 1000 % 10) << 0))
|
||||
#define BCD10K(X) \
|
||||
((X) < 10000 \
|
||||
? 0x20202020 \
|
||||
: (X) < 100000 \
|
||||
? 0x30202020 + (((X) / 10000 % 10) << 24) \
|
||||
: (X) < 1000000 \
|
||||
? 0x30302020 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) \
|
||||
: (X) < 10000000 \
|
||||
? 0x30303020 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) + \
|
||||
(((X) / 1000000 % 10) << 8) \
|
||||
: (X) < 100000000 \
|
||||
? 0x30303030 + (((X) / 10000 % 10) << 24) + \
|
||||
(((X) / 100000 % 10) << 16) + \
|
||||
(((X) / 1000000 % 10) << 8) + \
|
||||
(((X) / 10000000 % 10) << 0) \
|
||||
: 0xffffffffffffffff)
|
||||
#define SHSTUB2(SYM, X) \
|
||||
HIDDEN(SYM##_bcs0 = BCD_LEFT(X)); \
|
||||
HIDDEN(SYM##_bcs1 = BCD_RIGHT(X))
|
||||
#define BCD_SMEAR(X) ((X) + (X) * 10000)
|
||||
#define BCD_LEFT(X) \
|
||||
(((X)) < 10000 ? BCD_RIGHT(BCD_SMEAR(X)) | 0x10 \
|
||||
: (X) < 100000 ? BCD_RIGHT(BCD_SMEAR((X) / 10)) \
|
||||
: (X) < 1000000 ? BCD_RIGHT(BCD_SMEAR((X) / 100)) \
|
||||
: (X) < 10000000 ? BCD_RIGHT(BCD_SMEAR((X) / 1000)) \
|
||||
: (X) < 100000000 ? BCD_RIGHT(BCD_SMEAR((X) / 10000)) \
|
||||
: 0xffffffffffffffff)
|
||||
#define BCD_RIGHT(X) \
|
||||
(((X)) < 10000 ? 0x20202020 \
|
||||
: (X) < 100000 ? 0x20202030 + \
|
||||
(X) % 10 \
|
||||
: (X) < 1000000 ? 0x20203030 + \
|
||||
((X) / 10) % 10 + \
|
||||
(X) % 10 * 0x100 \
|
||||
: (X) < 10000000 ? 0x20303030 + \
|
||||
((X) / 100) % 10 + \
|
||||
((X) / 10) % 10 * 0x100 + \
|
||||
(X) % 10 * 0x10000 \
|
||||
: (X) < 100000000 ? 0x30303030 + \
|
||||
((X) / 1000) % 10 + \
|
||||
((X) / 100) % 10 * 0x100 + \
|
||||
((X) / 10) % 10 * 0x10000 + \
|
||||
(X) % 10 * 0x1000000 \
|
||||
: 0xffffffffffffffff)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* APE_MACROS_H_ */
|
||||
@@ -0,0 +1 @@
|
||||
#include "ape/ape.lds"
|
||||
+2
-2
@@ -36,8 +36,8 @@
|
||||
*/
|
||||
#define REAL(x) ((x) - (IMAGE_BASE_VIRTUAL - IMAGE_BASE_REAL))
|
||||
|
||||
#if IMAGE_BASE_VIRTUAL % 0x200000 != 0
|
||||
#error "IMAGE_BASE_VIRTUAL must be 2mb aligned"
|
||||
#if IMAGE_BASE_VIRTUAL % 0x1000 != 0
|
||||
#error "IMAGE_BASE_VIRTUAL must be 4kb aligned"
|
||||
#endif
|
||||
#if IMAGE_BASE_PHYSICAL % 0x1000 != 0
|
||||
#error "IMAGE_BASE_PHYSICAL must be 4kb aligned"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+53
-63
@@ -4,20 +4,35 @@
|
||||
# Default Mode
|
||||
#
|
||||
# - `make`
|
||||
# - Optimized
|
||||
# - Backtraces
|
||||
# - Debuggable
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - Reasonably small
|
||||
# - Reasonably optimized
|
||||
# - Reasonably debuggable
|
||||
#
|
||||
ifeq ($(MODE),)
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-DSYSDEBUG \
|
||||
-O2
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
TARGET_ARCH ?= -msse3
|
||||
endif
|
||||
|
||||
# Fast Build Mode
|
||||
#
|
||||
# - `make MODE=fastbuild`
|
||||
# - No debugging
|
||||
# - Syscall tracing
|
||||
# - Function tracing
|
||||
# - Some optimizations
|
||||
# - Limited Backtraces
|
||||
# - Compiles 28% faster
|
||||
#
|
||||
ifeq ($(MODE),fastbuild)
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
CONFIG_OFLAGS += -g0
|
||||
CONFIG_LDFLAGS += -S
|
||||
TARGET_ARCH ?= -msse3
|
||||
endif
|
||||
|
||||
# Optimized Mode
|
||||
@@ -31,19 +46,11 @@ endif
|
||||
# - No memory corruption detection
|
||||
# - assert() / CHECK_xx() may leak code into binary for debuggability
|
||||
# - GCC 8+ hoists check fails into .text.cold, thus minimizing impact
|
||||
#
|
||||
ifeq ($(MODE), opt)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DNDEBUG \
|
||||
-msse2avx \
|
||||
-Wa,-msse2avx
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-DSYSDEBUG \
|
||||
-O3 \
|
||||
-fmerge-all-constants
|
||||
TARGET_ARCH ?= \
|
||||
-march=native
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -msse2avx -Wa,-msse2avx
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O3 -fmerge-all-constants
|
||||
TARGET_ARCH ?= -march=native
|
||||
endif
|
||||
|
||||
# Optimized Linux Mode
|
||||
@@ -54,18 +61,12 @@ endif
|
||||
# - Turns off function tracing
|
||||
# - Turns off support for older cpu models
|
||||
# - Turns off support for other operating systems
|
||||
#
|
||||
ifeq ($(MODE), optlinux)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DNDEBUG \
|
||||
-msse2avx \
|
||||
-Wa,-msse2avx \
|
||||
-DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += \
|
||||
-O3 -fmerge-all-constants
|
||||
DEFAULT_COPTS += \
|
||||
-mred-zone
|
||||
TARGET_ARCH ?= \
|
||||
-march=native
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -msse2avx -Wa,-msse2avx -DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||
DEFAULT_COPTS += -mred-zone
|
||||
TARGET_ARCH ?= -march=native
|
||||
endif
|
||||
|
||||
# Release Mode
|
||||
@@ -81,16 +82,12 @@ endif
|
||||
# - DCHECK_xx() statements removed
|
||||
# - No memory corruption detection
|
||||
# - CHECK_xx() won't leak strings into binary
|
||||
#
|
||||
ifeq ($(MODE), rel)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DNDEBUG
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
-O2
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
PYFLAGS += \
|
||||
-O1
|
||||
CONFIG_CPPFLAGS += -DNDEBUG
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
TARGET_ARCH ?= -msse3
|
||||
PYFLAGS += -O1
|
||||
endif
|
||||
|
||||
# Asan Mode
|
||||
@@ -103,14 +100,11 @@ endif
|
||||
# - Backtraces
|
||||
# - Debuggability
|
||||
# - Larger binaries
|
||||
#
|
||||
ifeq ($(MODE), asan)
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
-O2
|
||||
CONFIG_COPTS += \
|
||||
-fsanitize=address
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
CONFIG_COPTS += -fsanitize=address
|
||||
TARGET_ARCH ?= -msse3
|
||||
endif
|
||||
|
||||
# Debug Mode
|
||||
@@ -122,22 +116,13 @@ endif
|
||||
# - Stack canaries
|
||||
# - No optimization (TODO)
|
||||
# - Enormous binaries
|
||||
#
|
||||
ifeq ($(MODE), dbg)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DMODE_DBG
|
||||
CONFIG_CCFLAGS += \
|
||||
$(BACKTRACES) \
|
||||
$(FTRACE) \
|
||||
-DSYSDEBUG \
|
||||
-O2 \
|
||||
-fno-inline
|
||||
CONFIG_COPTS += \
|
||||
-fsanitize=address \
|
||||
-fsanitize=undefined
|
||||
TARGET_ARCH ?= \
|
||||
-msse3
|
||||
OVERRIDE_CCFLAGS += \
|
||||
-fno-pie
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O -fno-inline
|
||||
CONFIG_COPTS += -fsanitize=address -fsanitize=undefined
|
||||
TARGET_ARCH ?= -msse3
|
||||
OVERRIDE_CCFLAGS += -fno-pie
|
||||
endif
|
||||
|
||||
# Tiny Mode
|
||||
@@ -151,6 +136,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tiny)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -185,6 +171,7 @@ endif
|
||||
# - No portability
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinylinux)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -216,6 +203,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinylinuxbsd)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -246,6 +234,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinysysv)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
@@ -276,6 +265,7 @@ endif
|
||||
# - No backtraces
|
||||
# - No algorithmics
|
||||
# - YOLO
|
||||
#
|
||||
ifeq ($(MODE), tinynowin)
|
||||
CONFIG_CPPFLAGS += \
|
||||
-DTINY \
|
||||
|
||||
@@ -65,7 +65,6 @@ ZIPOBJ = build/bootstrap/zipobj.com
|
||||
FIXUPOBJ = build/bootstrap/fixupobj.com
|
||||
MKDIR = build/bootstrap/mkdir.com -p
|
||||
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
|
||||
SYMTAB = $(TMPDIR)/$(subst /,_,$@).symtab
|
||||
|
||||
COMMA := ,
|
||||
PWD := $(shell build/bootstrap/pwd.com)
|
||||
@@ -108,6 +107,12 @@ export MODE
|
||||
export SOURCE_DATE_EPOCH
|
||||
export TMPDIR
|
||||
|
||||
ifeq ($(LANDLOCKMAKE_VERSION),)
|
||||
TMPSAFE = $(TMPDIR)/$(subst /,_,$@).tmp
|
||||
else
|
||||
TMPSAFE = $(TMPDIR)/
|
||||
endif
|
||||
|
||||
FTRACE = \
|
||||
-pg
|
||||
|
||||
|
||||
+5
-1
@@ -12,5 +12,9 @@
|
||||
|
||||
tail = $(wordlist 2,$(words $1),$1)
|
||||
reverse = $(if $1,$(call reverse,$(call tail,$1)) $(firstword $1))
|
||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
uniqr = $(if $1,$(call uniqr,$(filter-out $(firstword $1),$1)) $(firstword $1))
|
||||
|
||||
# polyfill uniq native (landlock make 1.4)
|
||||
ifneq ($(call uniq,c b c a),c b a)
|
||||
uniq = $(if $1,$(firstword $1) $(call uniq,$(filter-out $(firstword $1),$1)))
|
||||
endif
|
||||
+115
-15
@@ -25,7 +25,6 @@ o/%.o: o/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(
|
||||
o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
||||
o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
|
||||
o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
|
||||
o/%.zip.o: o/% ; @$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
o/$(MODE)/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $<
|
||||
@@ -44,14 +43,6 @@ o/$(MODE)/%.initabi.o: %.initabi.c ; @$(COMPILE) -AOBJECTIFY.init $(OBJECTIFY.in
|
||||
o/$(MODE)/%.ncabi.o: %.ncabi.c ; @$(COMPILE) -AOBJECTIFY.nc $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%.real.o: %.c ; @$(COMPILE) -AOBJECTIFY.real $(OBJECTIFY.real.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%.runs: o/$(MODE)/% ; @$(COMPILE) -ACHECK -wtT$@ $< $(TESTARGS)
|
||||
o/$(MODE)/%.zip.o: % ; @$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-gcc.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-clang.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
|
||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
||||
|
||||
o/%.o: %.cc
|
||||
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||
@$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@
|
||||
@@ -77,12 +68,12 @@ o/%.a:
|
||||
@$(COMPILE) -AARCHIVE -wT$@ $(AR) $(ARFLAGS) $@ @$(TMPDIR)/$(subst /,_,$@)
|
||||
|
||||
o/%.pkg:
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@).args,$(filter %.o,$^))
|
||||
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPDIR)/$(subst /,_,$@)
|
||||
$(file >$(TMPSAFE).args,$(filter %.o,$^))
|
||||
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPSAFE).args
|
||||
|
||||
o/$(MODE)/%.pkg:
|
||||
$(file >$(TMPDIR)/$(subst /,_,$@),$(filter %.o,$^))
|
||||
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPDIR)/$(subst /,_,$@)
|
||||
$(file >$(TMPSAFE).args,$(filter %.o,$^))
|
||||
@$(COMPILE) -APACKAGE -wT$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) @$(TMPSAFE).args
|
||||
|
||||
o/$(MODE)/%.o: %.py o/$(MODE)/third_party/python/pyobj.com
|
||||
@$(COMPILE) -wAPYOBJ o/$(MODE)/third_party/python/pyobj.com $(PYFLAGS) -o $@ $<
|
||||
@@ -101,8 +92,76 @@ o/$(MODE)/%: o/$(MODE)/%.com o/$(MODE)/tool/build/cp.com o/$(MODE)/tool/build/as
|
||||
@$(COMPILE) -wAASSIMILATE -T$@ o/$(MODE)/tool/build/assimilate.com $@
|
||||
|
||||
################################################################################
|
||||
# strict header checking
|
||||
# these rules are unsandboxed since they're kind of a sandboxing test themselves
|
||||
# LOCAL UNIT TESTS
|
||||
#
|
||||
# We always run unit tests as part of the normal `make` invocation. you
|
||||
# may override the $(TESTARGS) variable to do things such as enable the
|
||||
# benchmarking feature. For example:
|
||||
#
|
||||
# TESTARGS = -b
|
||||
#
|
||||
# May be specified in your ~/.cosmo.mk file. You can also use this to
|
||||
# enable things like function tracing. For example:
|
||||
#
|
||||
# TESTARGS = ----ftrace
|
||||
# .PLEDGE += prot_exec
|
||||
#
|
||||
# You could then run a command like:
|
||||
#
|
||||
# make -j8 o//test/libc/calls/openbsd_test.com.runs
|
||||
#
|
||||
# You need PROT_EXEC permission since ftrace morphs the binary. It's
|
||||
# also worth mentioning that the pledge.com command can simulate what
|
||||
# Landlock Make does:
|
||||
#
|
||||
# o//tool/build/pledge.com \
|
||||
# -v. -p 'stdio rpath wpath cpath tty prot_exec' \
|
||||
# o//test/libc/calls/openbsd_test.com \
|
||||
# ----ftrace
|
||||
#
|
||||
# This is useful in the event a test binary should run by itself, but
|
||||
# fails to run beneath Landlock Make. It's also useful sometimes to
|
||||
# override the verbosity when running tests:
|
||||
#
|
||||
# make V=5 TESTARGS=-b o//test/libc/calls/openbsd_test.com.runs
|
||||
#
|
||||
# This way, if for some reason a test should fail but calls exit(0),
|
||||
# then the stdout/stderr output, which would normally be suppressed,
|
||||
# will actually be displayed.
|
||||
|
||||
o/$(MODE)/%.runs: o/$(MODE)/%
|
||||
@$(COMPILE) -ACHECK -wtT$@ $< $(TESTARGS)
|
||||
|
||||
################################################################################
|
||||
# ELF ZIP FILES
|
||||
#
|
||||
# zipobj.com lets us do fast incremental linking of compressed data.
|
||||
# it's nice because if we link a hundred binaries that use the time zone
|
||||
# database, then that database only needs to be DEFLATE'd once.
|
||||
|
||||
o/%.zip.o: o/%
|
||||
@$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%.zip.o: %
|
||||
@$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%.zip.o: %
|
||||
@$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
# an issue with sandboxing arises when creating directory entries in the
|
||||
# zip file. we need the trailing slash (e.g. o//foo/.zip.o) but Landlock
|
||||
# Make avoids sandboxing directory names that have a trailing slash (so
|
||||
# they can be used to watch for deleted files, without creating overly
|
||||
# broad unveiling). such rules need to be written more explicitly.
|
||||
o/$(MODE)%/.zip.o: %
|
||||
@$(COMPILE) -wAZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
|
||||
|
||||
################################################################################
|
||||
# STRICT HEADER CHECKING
|
||||
#
|
||||
# these rules are unsandboxed since they're already a sandboxing test,
|
||||
# and it would be too costly in terms of make latency to have every
|
||||
# header file depend on $(HDRS) and $(INCS).
|
||||
|
||||
o/%.h.ok: .UNSANDBOXED = 1
|
||||
o/%.h.ok: %.h
|
||||
@@ -123,3 +182,44 @@ o/%.okk: %
|
||||
o/$(MODE)/%.okk: .UNSANDBOXED = 1
|
||||
o/$(MODE)/%.okk: %
|
||||
@$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
|
||||
|
||||
################################################################################
|
||||
# EXECUTABLE HELPERS
|
||||
|
||||
MAKE_OBJCOPY = \
|
||||
$(COMPILE) -AOBJCOPY -T$@ \
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
MAKE_SYMTAB_CREATE = \
|
||||
$(COMPILE) -wASYMTAB \
|
||||
o/$(MODE)/tool/build/symtab.com \
|
||||
-o $(TMPSAFE)/.symtab \
|
||||
$<
|
||||
|
||||
MAKE_SYMTAB_ZIP = \
|
||||
$(COMPILE) -AZIP -T$@ \
|
||||
o/$(MODE)/third_party/zip/zip.com \
|
||||
-b$(TMPDIR) \
|
||||
-9qj \
|
||||
$@ \
|
||||
$(TMPSAFE)/.symtab
|
||||
|
||||
################################################################################
|
||||
# EMACS ASSEMBLY GENERATION
|
||||
|
||||
o/$(MODE)/%-gcc.asm: .UNSANDBOXED = 1
|
||||
o/$(MODE)/%-gcc.asm: %.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%-gcc.asm: .UNSANDBOXED = 1
|
||||
o/$(MODE)/%-gcc.asm: %.cc
|
||||
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%-clang.asm: .UNSANDBOXED = 1
|
||||
o/$(MODE)/%-clang.asm: %.c
|
||||
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%-clang.asm: CC = $(CLANG)
|
||||
o/$(MODE)/%-clang.asm: .UNSANDBOXED = 1
|
||||
o/$(MODE)/%-clang.asm: %.cc
|
||||
@$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
|
||||
+2
-2
@@ -67,7 +67,7 @@ plm_buffer_t *plm_buffer_create_with_file(FILE *fh, int close_when_done) {
|
||||
|
||||
plm_buffer_t *plm_buffer_create_with_memory(unsigned char *bytes, size_t length, int free_when_done) {
|
||||
plm_buffer_t *b;
|
||||
b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t));
|
||||
b = memalign(_Alignof(plm_buffer_t), sizeof(plm_buffer_t));
|
||||
memset(b, 0, sizeof(plm_buffer_t));
|
||||
b->capacity = length;
|
||||
b->length = length;
|
||||
@@ -79,7 +79,7 @@ plm_buffer_t *plm_buffer_create_with_memory(unsigned char *bytes, size_t length,
|
||||
|
||||
plm_buffer_t * plm_buffer_create_with_capacity(size_t capacity) {
|
||||
plm_buffer_t *b;
|
||||
b = memalign(alignof(plm_buffer_t), sizeof(plm_buffer_t));
|
||||
b = memalign(_Alignof(plm_buffer_t), sizeof(plm_buffer_t));
|
||||
memset(b, 0, sizeof(plm_buffer_t));
|
||||
b->capacity = capacity;
|
||||
b->free_when_done = true;
|
||||
|
||||
+1
-1
@@ -277,7 +277,7 @@ void plm_audio_read_samples(plm_audio_t *self, int ch, int sb, int part);
|
||||
void plm_audio_matrix_transform(int s[32][3], int ss, float *d, int dp);
|
||||
|
||||
plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer, int destroy_when_done) {
|
||||
plm_audio_t *self = (plm_audio_t *)memalign(alignof(plm_audio_t), sizeof(plm_audio_t));
|
||||
plm_audio_t *self = (plm_audio_t *)memalign(_Alignof(plm_audio_t), sizeof(plm_audio_t));
|
||||
memset(self, 0, sizeof(plm_audio_t));
|
||||
|
||||
self->samples.count = PLM_AUDIO_SAMPLES_PER_FRAME;
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
#include "dsp/core/ituround.h"
|
||||
#include "dsp/core/q.h"
|
||||
#include "dsp/core/twixt8.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
@@ -203,8 +203,8 @@ void *Gyarados(long dyw, long dxw, int dst[dyw][dxw], long syw, long sxw,
|
||||
CHECK_LE(sxn, sxw);
|
||||
CHECK_LE(dyn, dyw);
|
||||
CHECK_LE(dxn, dxw);
|
||||
CHECK_LT(bsrl(syn) + bsrl(sxn), 32);
|
||||
CHECK_LT(bsrl(dyn) + bsrl(dxn), 32);
|
||||
CHECK_LT(_bsrl(syn) + _bsrl(sxn), 32);
|
||||
CHECK_LT(_bsrl(dyn) + _bsrl(dxn), 32);
|
||||
CHECK_LE(dyw, 0x7fff);
|
||||
CHECK_LE(dxw, 0x7fff);
|
||||
CHECK_LE(syw, 0x7fff);
|
||||
|
||||
+4
-3
@@ -83,10 +83,11 @@ int ttyident(struct TtyIdent *ti, int ttyinfd, int ttyoutfd) {
|
||||
if (ttyident_probe(ti, ttyinfd, ttyoutfd, "\e[>c") != -1) {
|
||||
rc = 0;
|
||||
memset(&outer, 0, sizeof(outer));
|
||||
if (ti->id == 83 /* GNU Screen */ && (ti->next || weaken(malloc)) &&
|
||||
if (ti->id == 83 /* GNU Screen */ && (ti->next || _weaken(malloc)) &&
|
||||
ttyident_probe(&outer, ttyinfd, ttyoutfd, "\eP\e[>c\e\\") != -1 &&
|
||||
(ti->next = (ti->next ? ti->next
|
||||
: weaken(malloc)(sizeof(struct TtyIdent))))) {
|
||||
(ti->next =
|
||||
(ti->next ? ti->next
|
||||
: _weaken(malloc)(sizeof(struct TtyIdent))))) {
|
||||
memcpy(ti->next, &outer, sizeof(outer));
|
||||
} else {
|
||||
free_s(&ti->next);
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/* TODO(jart): DELETE */
|
||||
|
||||
+5
-4
@@ -25,7 +25,7 @@
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xsigaction.h"
|
||||
|
||||
/* TODO(jart): DELETE */
|
||||
|
||||
@@ -97,8 +98,8 @@ static relegated void ttyraw_onsig(int sig, struct siginfo *info,
|
||||
}
|
||||
for (i = 0; i < ARRAYLEN(g_ttyraw.sigs); ++i) {
|
||||
if (g_ttyraw.sigs[i] == sig) {
|
||||
if (g_ttyraw.next[i] != SIG_IGN) {
|
||||
if (g_ttyraw.next[i] != SIG_DFL) {
|
||||
if (g_ttyraw.next[i] != (void *)SIG_IGN) {
|
||||
if (g_ttyraw.next[i] != (void *)SIG_DFL) {
|
||||
if (g_ttyraw.next[i]) {
|
||||
g_ttyraw.next[i](sig, info, ctx);
|
||||
}
|
||||
@@ -117,7 +118,7 @@ static textstartup void ttyraw_initsig(int sig, unsigned flags, unsigned mask) {
|
||||
struct sigaction old;
|
||||
g_ttyraw.next[i] = xsigaction(sig, ttyraw_onsig, flags, mask, &old) != -1
|
||||
? old.sa_sigaction
|
||||
: SIG_DFL;
|
||||
: (void *)SIG_DFL;
|
||||
g_ttyraw.sigs[i++] = sig;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#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/struct/timespec.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* @fileoverview clock() function demo
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned long i;
|
||||
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);
|
||||
for (;;) {
|
||||
for (i = 0;; ++i) {
|
||||
x *= 7;
|
||||
if (!(i % 256)) {
|
||||
now = _timespec_mono();
|
||||
if (_timespec_gte(now, next)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
next = _timespec_add(next, interval);
|
||||
printf("consumed %10g seconds monotonic time and %10g seconds cpu time\n",
|
||||
_timespec_tonanos(_timespec_sub(now, start)) / 1000000000.,
|
||||
(double)clock() / CLOCKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -8,11 +8,12 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
+5
-3
@@ -9,19 +9,21 @@
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/appendresourcereport.internal.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
@@ -152,7 +154,7 @@ int main(int argc, char *argv[]) {
|
||||
while ((line = linenoiseWithHistory(prompt, "cmd"))) {
|
||||
n = 0;
|
||||
start = line;
|
||||
if (startswith(start, "time ")) {
|
||||
if (_startswith(start, "time ")) {
|
||||
timeit = true;
|
||||
start += 5;
|
||||
} else {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
|
||||
+5
-4
@@ -7,7 +7,6 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/dce.h"
|
||||
@@ -15,15 +14,16 @@
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/str.h"
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "libc/sysv/consts/tcp.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xsigaction.h"
|
||||
#include "net/http/http.h"
|
||||
#include "net/http/url.h"
|
||||
#include "net/https/https.h"
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "net/http/escape.h"
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xiso8601.h"
|
||||
|
||||
/**
|
||||
* @fileoverview ISO-8601 international high-precision timestamp printer.
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,6 +66,7 @@ EXAMPLES_DIRECTDEPS = \
|
||||
LIBC_THREAD \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_VGA \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
NET_HTTP \
|
||||
@@ -79,6 +80,7 @@ EXAMPLES_DIRECTDEPS = \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_XED \
|
||||
|
||||
+2
-3
@@ -8,14 +8,13 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/nt/nt/process.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
volatile long double x = -.5;
|
||||
volatile long double y = 1.5;
|
||||
printf("Hello World! %.19Lg\n", atan2l(x, y));
|
||||
return 0;
|
||||
char *p = _gc(malloc(64));
|
||||
strcpy(p, "this memory is free'd when main() returns");
|
||||
}
|
||||
+3
-13
@@ -7,19 +7,9 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int c, n;
|
||||
char a[22], *p;
|
||||
if ((c = GetCpuCount())) {
|
||||
p = FormatInt64(a, c);
|
||||
*p++ = '\n';
|
||||
return write(1, a, p - a) == p - a ? 0 : 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
int main() {
|
||||
kprintf("%d\n", GetCpuCount());
|
||||
}
|
||||
@@ -7,20 +7,21 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/xorshift.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/stdio/xorshift.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
|
||||
+20
-17
@@ -8,23 +8,23 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/wait0.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
@@ -47,6 +47,9 @@
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/consts/tcp.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "libc/thread/wait0.internal.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "net/http/http.h"
|
||||
@@ -103,14 +106,14 @@
|
||||
"Cache-Control: private; max-age=0\r\n"
|
||||
|
||||
int threads;
|
||||
_Atomic(int) workers;
|
||||
_Atomic(int) messages;
|
||||
_Atomic(int) listening;
|
||||
_Atomic(int) connections;
|
||||
_Atomic(int) closingtime;
|
||||
atomic_int workers;
|
||||
atomic_int messages;
|
||||
atomic_int listening;
|
||||
atomic_int connections;
|
||||
atomic_int closingtime;
|
||||
const char *volatile status;
|
||||
|
||||
int Worker(void *id, int tid) {
|
||||
void *Worker(void *id) {
|
||||
int server, yes = 1;
|
||||
|
||||
// load balance incoming connections for port 8080 across all threads
|
||||
@@ -164,7 +167,7 @@ int Worker(void *id, int tid) {
|
||||
|
||||
// wait for client connection
|
||||
clientaddrsize = sizeof(clientaddr);
|
||||
client = accept(server, &clientaddr, &clientaddrsize);
|
||||
client = accept(server, (struct sockaddr *)&clientaddr, &clientaddrsize);
|
||||
|
||||
// accept() can raise a very diverse number of errors but none of
|
||||
// them are really true showstoppers that would necessitate us to
|
||||
@@ -276,8 +279,8 @@ void PrintStatus(void) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
struct spawn *th;
|
||||
int i, rc;
|
||||
pthread_t *th;
|
||||
uint32_t *hostips;
|
||||
// ShowCrashReports();
|
||||
|
||||
@@ -298,7 +301,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
threads = argc > 1 ? atoi(argv[1]) : GetCpuCount();
|
||||
if (!(1 <= threads && threads <= 100000)) {
|
||||
kprintf("error: invalid number of threads\n");
|
||||
kprintf("error: invalid number of threads: %d\n", threads);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -309,12 +312,12 @@ int main(int argc, char *argv[]) {
|
||||
pledge("stdio inet", 0);
|
||||
|
||||
// spawn over 9,000 worker threads
|
||||
th = calloc(threads, sizeof(*th));
|
||||
th = calloc(threads, sizeof(pthread_t));
|
||||
for (i = 0; i < threads; ++i) {
|
||||
++workers;
|
||||
if (_spawn(Worker, (void *)(intptr_t)i, th + i) == -1) {
|
||||
if ((rc = pthread_create(th + i, 0, Worker, (void *)(intptr_t)i))) {
|
||||
--workers;
|
||||
kprintf("error: _spawn(%d) failed %m\n", i);
|
||||
kprintf("error: pthread_create(%d) failed %s\n", i, strerror(rc));
|
||||
}
|
||||
if (!(i % 500)) {
|
||||
PrintStatus();
|
||||
@@ -332,7 +335,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
// join the workers
|
||||
for (i = 0; i < threads; ++i) {
|
||||
_join(th + i);
|
||||
pthread_join(th[i], 0);
|
||||
}
|
||||
|
||||
// clean up memory
|
||||
|
||||
+1
-2
@@ -14,8 +14,7 @@
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xsigaction.h"
|
||||
|
||||
const struct itimerval kHertz = {
|
||||
{1, 0},
|
||||
|
||||
+6
-4
@@ -8,12 +8,14 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char hostname[254];
|
||||
CHECK_NE(-1, gethostname(hostname, sizeof(hostname)));
|
||||
puts(hostname);
|
||||
char name[254];
|
||||
gethostname(name, sizeof(name));
|
||||
kprintf("gethostname() → %#s\n", name);
|
||||
getdomainname(name, sizeof(name));
|
||||
kprintf("getdomainname() → %#s\n", name);
|
||||
return 0;
|
||||
}
|
||||
+6
-4
@@ -9,9 +9,11 @@
|
||||
#endif
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xasprintf.h"
|
||||
#include "net/http/escape.h"
|
||||
#include "net/http/http.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
@@ -43,15 +45,15 @@ void PrintImg(const char *path) {
|
||||
size_t n;
|
||||
int opt, i, yn, xn, cn, w, h;
|
||||
void *img, *pix, *src, *mime;
|
||||
if (!(img = gc(xslurp(path, &n)))) exit(2);
|
||||
if (!(pix = gc(stbi_load_from_memory(img, n, &xn, &yn, &cn, 0)))) exit(3);
|
||||
if (!(img = _gc(xslurp(path, &n)))) exit(2);
|
||||
if (!(pix = _gc(stbi_load_from_memory(img, n, &xn, &yn, &cn, 0)))) exit(3);
|
||||
if (linktag) {
|
||||
printf("<a href=\"%s\"\n >", path);
|
||||
}
|
||||
src = path;
|
||||
if (datauri) {
|
||||
src = xasprintf("data:%s;base64,%s", FindContentType(path, -1),
|
||||
gc(EncodeBase64(img, n, &n)));
|
||||
_gc(EncodeBase64(img, n, &n)));
|
||||
}
|
||||
w = (xn + (1 << scale) / 2) >> scale;
|
||||
h = (yn + (1 << scale) / 2) >> scale;
|
||||
|
||||
@@ -1,160 +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/mem/alg.h"
|
||||
#include "libc/mem/arraylist.internal.h"
|
||||
#include "libc/mem/critbit0.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpdecode.internal.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
STATIC_YOINK("zip_uri_support");
|
||||
|
||||
/**
|
||||
* @fileoverview Simple Interactive Spell Checker.
|
||||
*
|
||||
* This is an attempt to get spell checking to work in Emacs across
|
||||
* platforms. While the computer science behind spell checking is very
|
||||
* simple, unfortunately Emacs probes all these System Five spell progs
|
||||
* similar to how websites have been known to probe User-Agent strings.
|
||||
*
|
||||
* Here's how we believe the repl works:
|
||||
*
|
||||
* $ make -j8 o//examples/ispell.com
|
||||
* $ o//examples/ispell.com
|
||||
* @(#) Cosmopolitan Ispell Version 3.4.00 8 Feb 2015
|
||||
* word: hello
|
||||
* ok
|
||||
* word: héllo
|
||||
* how about: hills, hello, hilly, jello
|
||||
* word: lova
|
||||
* how about: diva, dona, dora, dove, elva, fora, hove, iota
|
||||
* word: hecruhecrue
|
||||
* not found
|
||||
*
|
||||
* The dictionary for this program is embedded as a text file within the
|
||||
* zip structure of the binary. It can be edited after distribution.
|
||||
*
|
||||
* It's possible to go even fancier than what this code is doing, by
|
||||
* using cmudict phonemes, bloom filters, unicode tables e.g. e vs. é,
|
||||
* and even doing ML similar to Google's online spell checker.
|
||||
*
|
||||
* TODO: Figure out why Emacs rejects this interface.
|
||||
*/
|
||||
|
||||
#define MISSING_LETTER_DISTANCE 5
|
||||
#define MAX_NEARBY_WORD_DISTANCE 6
|
||||
#define MAX_NEARBY_RESULTS 8
|
||||
|
||||
FILE *f;
|
||||
char *line;
|
||||
size_t linesize;
|
||||
const char *query;
|
||||
struct critbit0 words; /* does O(log 𝑛) fast path lookup */
|
||||
|
||||
struct NearbyWords {
|
||||
size_t i, n;
|
||||
struct WordMatch {
|
||||
long dist;
|
||||
char *word;
|
||||
} * p;
|
||||
} nearby;
|
||||
|
||||
long WordDistance(const char *a, const char *b) {
|
||||
long dist;
|
||||
int gota, gotb;
|
||||
unsigned long h, p;
|
||||
wint_t chara, charb;
|
||||
dist = p = 0;
|
||||
for (;;) {
|
||||
gota = abs(tpdecode(a, &chara)); /* parses utf-8 multibyte characters */
|
||||
gotb = abs(tpdecode(b, &charb)); /* abs() handles -1, always yields � */
|
||||
if (!chara && !charb) break;
|
||||
if (!chara || !charb) {
|
||||
dist += MISSING_LETTER_DISTANCE;
|
||||
} else if ((h = hamming(chara, charb))) {
|
||||
dist += h + p++; /* penalize multiple mismatched letters */
|
||||
}
|
||||
if (chara) a += gota;
|
||||
if (charb) b += gotb;
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
|
||||
intptr_t ConsiderWord(const char *word, void *arg) {
|
||||
long dist;
|
||||
if ((dist = WordDistance(word, query)) < MAX_NEARBY_WORD_DISTANCE) {
|
||||
append(&nearby, &((struct WordMatch){dist, word}));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CompareWords(const struct WordMatch *a, const struct WordMatch *b) {
|
||||
return a->dist < b->dist;
|
||||
}
|
||||
|
||||
void FindNearbyWords(void) {
|
||||
nearby.i = 0;
|
||||
critbit0_allprefixed(&words, "", ConsiderWord, NULL);
|
||||
qsort(nearby.p, nearby.i, sizeof(struct WordMatch), (void *)CompareWords);
|
||||
}
|
||||
|
||||
void SpellChecker(void) {
|
||||
int i;
|
||||
printf("@(#) Cosmopolitan Ispell Version 3.4.00 8 Feb 2015\r\n");
|
||||
while (!feof(stdin)) {
|
||||
printf("word: ");
|
||||
fflush(stdout);
|
||||
if (getline(&line, &linesize, stdin) > 0) {
|
||||
query = strtolower(_chomp(line));
|
||||
if (critbit0_contains(&words, query)) {
|
||||
printf("ok\r\n");
|
||||
} else {
|
||||
FindNearbyWords();
|
||||
if (nearby.i) {
|
||||
printf("how about: ");
|
||||
for (i = 0; i < MIN(MAX_NEARBY_RESULTS, nearby.i); ++i) {
|
||||
if (i) printf(", ");
|
||||
fputs(nearby.p[i].word, stdout);
|
||||
}
|
||||
printf("\r\n");
|
||||
} else {
|
||||
printf("not found\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
}
|
||||
CHECK_NE(-1, fclose(stdin));
|
||||
CHECK_NE(-1, fclose(stdout));
|
||||
}
|
||||
|
||||
void LoadWords(void) {
|
||||
CHECK_NOTNULL((f = fopen("/zip/usr/share/dict/words", "r")));
|
||||
while (getline(&line, &linesize, f) > 0) {
|
||||
critbit0_insert(&words, strtolower(_chomp(line)));
|
||||
}
|
||||
CHECK_NE(-1, fclose(f));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!NoDebug()) ShowCrashReports();
|
||||
LoadWords();
|
||||
SpellChecker();
|
||||
return 0;
|
||||
}
|
||||
+3
-3
@@ -58,14 +58,14 @@ Contact: [email protected]\"\n\
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
@@ -355,7 +355,7 @@ int getCursorPosition(int64_t ifd, int64_t ofd, int *rows, int *cols) {
|
||||
* Returns 0 on success, -1 on error. */
|
||||
int getWindowSize(int64_t ifd, int64_t ofd, int *rows, int *cols) {
|
||||
struct winsize ws;
|
||||
if (getttysize(STDOUT_FILENO, &ws) == -1 || ws.ws_col == 0) {
|
||||
if (_getttysize(1, &ws) == -1 || ws.ws_col == 0) {
|
||||
/* ioctl() failed. Try to query the terminal itself. */
|
||||
int orig_row, orig_col, retval;
|
||||
|
||||
|
||||
+3
-3
@@ -11,12 +11,12 @@
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xasprintf.h"
|
||||
|
||||
struct stat st;
|
||||
|
||||
@@ -49,7 +49,7 @@ void List(const char *path) {
|
||||
const char *vpath;
|
||||
if (strcmp(path, ".") == 0) {
|
||||
vpath = "";
|
||||
} else if (!endswith(path, "/")) {
|
||||
} else if (!_endswith(path, "/")) {
|
||||
vpath = _gc(xasprintf("%s/", path));
|
||||
} else {
|
||||
vpath = path;
|
||||
|
||||
+5
-4
@@ -7,19 +7,20 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xiso8601.h"
|
||||
|
||||
struct stat st;
|
||||
struct Files {
|
||||
|
||||
+2054
File diff suppressed because it is too large.
Load diff
+6
-5
@@ -10,21 +10,21 @@
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/inttypes.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
@@ -39,7 +39,8 @@
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xasprintf.h"
|
||||
#include "libc/x/xsigaction.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
@@ -286,7 +287,7 @@ void GetTermSize(void) {
|
||||
struct winsize wsize_;
|
||||
wsize_.ws_row = 25;
|
||||
wsize_.ws_col = 80;
|
||||
getttysize(STDIN_FILENO, &wsize_);
|
||||
_getttysize(0, &wsize_);
|
||||
FreeSamplingSolution(ssy_);
|
||||
FreeSamplingSolution(ssx_);
|
||||
tyn_ = wsize_.ws_row * 2;
|
||||
|
||||
+3
-2
@@ -17,14 +17,15 @@
|
||||
#include "libc/log/gdb.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xasprintf.h"
|
||||
#include "tool/build/lib/panel.h"
|
||||
|
||||
/**
|
||||
@@ -76,7 +77,7 @@ void GetTtySize(void) {
|
||||
struct winsize wsize;
|
||||
wsize.ws_row = tyn;
|
||||
wsize.ws_col = txn;
|
||||
getttysize(1, &wsize);
|
||||
_getttysize(1, &wsize);
|
||||
tyn = wsize.ws_row;
|
||||
txn = wsize.ws_col;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "libc/fmt/fmt.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"
|
||||
|
||||
|
||||
+1
-2
@@ -8,11 +8,10 @@
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/color.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
volatile bool gotalrm;
|
||||
|
||||
void OnSigAlrm(int sig, siginfo_t *si, ucontext_t *ctx) {
|
||||
void OnSigAlrm(int sig, siginfo_t *si, void *ctx) {
|
||||
gotalrm = true;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -14,11 +14,11 @@
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xiso8601.h"
|
||||
|
||||
/**
|
||||
* @fileoverview File metadata viewer.
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#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/thread/thread.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Basic POSIX Threads Example.
|
||||
*
|
||||
* $ make -j8 o//examples/thread.com
|
||||
* $ o//examples/thread.com
|
||||
* hi there
|
||||
*
|
||||
*/
|
||||
|
||||
void *worker(void *arg) {
|
||||
fputs(arg, stdout);
|
||||
return "there\n";
|
||||
}
|
||||
|
||||
int main() {
|
||||
void *result;
|
||||
pthread_t id;
|
||||
pthread_create(&id, 0, worker, "hi ");
|
||||
pthread_join(id, &result);
|
||||
fputs(result, stdout);
|
||||
}
|
||||
+2
-1
@@ -12,10 +12,11 @@
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xspawn.h"
|
||||
|
||||
/**
|
||||
* @fileoverview command for showing how long a command takes
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/append.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
|
||||
+5
-5
@@ -24,7 +24,7 @@
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/x/xsigaction.h"
|
||||
|
||||
#define CTRL(C) ((C) ^ 0b01000000)
|
||||
#define WRITE(FD, SLIT) write(FD, SLIT, strlen(SLIT))
|
||||
@@ -80,7 +80,7 @@ int rawmode(void) {
|
||||
}
|
||||
|
||||
void getsize(void) {
|
||||
if (getttysize(1, &wsize) != -1) {
|
||||
if (_getttysize(1, &wsize) != -1) {
|
||||
printf("termios says terminal size is %hu×%hu\r\n", wsize.ws_col,
|
||||
wsize.ws_row);
|
||||
} else {
|
||||
@@ -148,12 +148,12 @@ int main(int argc, char *argv[]) {
|
||||
if (iscntrl(code[0]) && !code[1]) {
|
||||
printf("is CTRL-%c a.k.a. ^%c\r\n", CTRL(code[0]), CTRL(code[0]));
|
||||
if (code[0] == CTRL('C') || code[0] == CTRL('D')) break;
|
||||
} else if (startswith(code, "\e[") && endswith(code, "R")) {
|
||||
} else if (_startswith(code, "\e[") && _endswith(code, "R")) {
|
||||
yn = 1, xn = 1;
|
||||
sscanf(code, "\e[%d;%dR", &yn, &xn);
|
||||
printf("inband signalling says terminal size is %d×%d\r\n", xn, yn);
|
||||
} else if (startswith(code, "\e[<") &&
|
||||
(endswith(code, "m") || endswith(code, "M"))) {
|
||||
} else if (_startswith(code, "\e[<") &&
|
||||
(_endswith(code, "m") || _endswith(code, "M"))) {
|
||||
e = 0, y = 1, x = 1;
|
||||
sscanf(code, "\e[<%d;%d;%d%c", &e, &y, &x, &c);
|
||||
printf("mouse %s at %d×%d\r\n", describemouseevent(e | (c == 'm') << 2),
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
* and this example should work on all supported platforms even Windows
|
||||
*/
|
||||
|
||||
void handler(int sig, siginfo_t *si, ucontext_t *ctx) {
|
||||
void handler(int sig, siginfo_t *si, void *vctx) {
|
||||
struct XedDecodedInst xedd;
|
||||
struct ucontext *ctx = vctx;
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64);
|
||||
xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15);
|
||||
ctx->uc_mcontext.rip += xedd.length;
|
||||
|
||||
+6
-6
@@ -14,11 +14,11 @@
|
||||
int main(int argc, char *argv[]) {
|
||||
struct utsname names;
|
||||
if (uname(&names)) return 1;
|
||||
printf("%-10s %s\n", "sysname", names.sysname);
|
||||
printf("%-10s %s\n", "nodename", names.nodename);
|
||||
printf("%-10s %s\n", "release", names.release);
|
||||
printf("%-10s %s\n", "version", names.version);
|
||||
printf("%-10s %s\n", "machine", names.machine);
|
||||
printf("%-10s %s\n", "domainname", names.domainname);
|
||||
printf("%-10s %`'s\n", "sysname", names.sysname);
|
||||
printf("%-10s %`'s\n", "release", names.release);
|
||||
printf("%-10s %`'s\n", "version", names.version);
|
||||
printf("%-10s %`'s\n", "machine", names.machine);
|
||||
printf("%-10s %`'s\n", "nodename", names.nodename);
|
||||
printf("%-10s %`'s\n", "domainname", names.domainname);
|
||||
return 0;
|
||||
}
|
||||
+3
-2
@@ -110,12 +110,11 @@
|
||||
│ cosmopolitan § the unbourne shell » macros ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/tms.h"
|
||||
@@ -124,9 +123,11 @@
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/paths.h"
|
||||
|
||||
@@ -1,143 +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/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/calls/ttydefaults.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/consts/w.h"
|
||||
|
||||
#define STR(s) s, strlen(s)
|
||||
|
||||
struct termios tio;
|
||||
struct winsize wsz;
|
||||
sigset_t chldmask, savemask;
|
||||
struct sigaction ignore, saveint, savequit;
|
||||
char databuf[512];
|
||||
char pathbuf[PATH_MAX];
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
ssize_t rc;
|
||||
const char *prog;
|
||||
size_t i, got, wrote;
|
||||
int ws, mfd, sfd, pid;
|
||||
|
||||
if (argc < 2) {
|
||||
write(2, STR("usage: "));
|
||||
if (argc > 0) write(2, argv[0], strlen(argv[0]));
|
||||
write(2, STR(" prog [argv₁...]\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(prog = commandv(argv[1], pathbuf, sizeof(pathbuf)))) {
|
||||
write(2, STR("error: "));
|
||||
write(2, argv[1], strlen(argv[1]));
|
||||
write(2, STR(" not found\n"));
|
||||
return 2;
|
||||
}
|
||||
|
||||
bzero(&wsz, sizeof(wsz));
|
||||
wsz.ws_col = 80;
|
||||
wsz.ws_row = 45;
|
||||
|
||||
bzero(&tio, sizeof(tio));
|
||||
tio.c_iflag = ICRNL | IXON | IUTF8;
|
||||
tio.c_oflag = OPOST | ONLCR;
|
||||
tio.c_cflag = CREAD | CS8;
|
||||
tio.c_lflag =
|
||||
ISIG | ICANON | ECHO | ECHOE | ECHOK | IEXTEN | ECHOCTL | ECHOKE;
|
||||
tio.c_cc[VMIN] = 1;
|
||||
tio.c_cc[VINTR] = CTRL('C');
|
||||
tio.c_cc[VQUIT] = CTRL('\\');
|
||||
tio.c_cc[VERASE] = CTRL('?');
|
||||
tio.c_cc[VKILL] = CTRL('U');
|
||||
tio.c_cc[VEOF] = CTRL('D');
|
||||
tio.c_cc[VSTART] = CTRL('Q');
|
||||
tio.c_cc[VSTOP] = CTRL('S');
|
||||
tio.c_cc[VSUSP] = CTRL('Z');
|
||||
tio.c_cc[VREPRINT] = CTRL('R');
|
||||
tio.c_cc[VDISCARD] = CTRL('O');
|
||||
tio.c_cc[VWERASE] = CTRL('W');
|
||||
tio.c_cc[VLNEXT] = CTRL('V');
|
||||
|
||||
if (openpty(&mfd, &sfd, 0, &tio, &wsz)) {
|
||||
write(2, STR("error: openpty() failed\n"));
|
||||
return 3;
|
||||
}
|
||||
|
||||
ignore.sa_flags = 0;
|
||||
ignore.sa_handler = SIG_IGN;
|
||||
sigemptyset(&ignore.sa_mask);
|
||||
sigaction(SIGINT, &ignore, &saveint);
|
||||
sigaction(SIGQUIT, &ignore, &savequit);
|
||||
sigemptyset(&chldmask);
|
||||
sigaddset(&chldmask, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
|
||||
|
||||
if ((pid = vfork()) == -1) {
|
||||
write(2, STR("error: vfork() failed\n"));
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (!pid) {
|
||||
close(0);
|
||||
dup(sfd);
|
||||
close(1);
|
||||
dup(sfd);
|
||||
close(2);
|
||||
dup(sfd);
|
||||
close(mfd);
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
sigaction(SIGQUIT, &savequit, 0);
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
execv(prog, argv + 1);
|
||||
return 127;
|
||||
}
|
||||
close(sfd);
|
||||
|
||||
for (;;) {
|
||||
if (waitpid(pid, &ws, WNOHANG) == pid) {
|
||||
break;
|
||||
}
|
||||
rc = read(mfd, databuf, sizeof(databuf));
|
||||
if (rc == -1) {
|
||||
perror("read");
|
||||
return 5;
|
||||
}
|
||||
if (!(got = rc)) {
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < got; i += wrote) {
|
||||
rc = write(1, databuf + i, got - i);
|
||||
if (rc != -1) {
|
||||
wrote = rc;
|
||||
} else {
|
||||
write(2, STR("error: read() failed\n"));
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
sigaction(SIGQUIT, &savequit, 0);
|
||||
sigprocmask(SIG_SETMASK, &savemask, 0);
|
||||
|
||||
if (WIFEXITED(ws)) {
|
||||
return WEXITSTATUS(ws);
|
||||
} else {
|
||||
return 128 + WTERMSIG(ws);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#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/calls/termios.h"
|
||||
#include "libc/isystem/unistd.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Bare Metal VGA TTY demo.
|
||||
*
|
||||
* This program can boot as an operating system. Try it out:
|
||||
*
|
||||
* make -j8 o//examples/vga.com
|
||||
* qemu-system-x86_64 -hda o//examples/vga.com -serial stdio
|
||||
*
|
||||
* Please note that, by default, APE binaries only use the serial port
|
||||
* for stdio. To get the VGA console as an added bonus:
|
||||
*
|
||||
* STATIC_YOINK("vga_console");
|
||||
*
|
||||
* Should be added to the top of your main() program source file.
|
||||
*/
|
||||
|
||||
STATIC_YOINK("vga_console");
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
volatile long double x = -.5;
|
||||
volatile long double y = 1.5;
|
||||
struct termios tio;
|
||||
char buf[16];
|
||||
ssize_t res;
|
||||
if (tcgetattr(0, &tio) != -1) {
|
||||
tio.c_lflag &= ~(ECHO | ICANON);
|
||||
tcsetattr(0, TCSANOW, &tio);
|
||||
}
|
||||
write(1, "\e[5n", 4);
|
||||
res = read(0, buf, 4);
|
||||
if (res != 4 || memcmp(buf, "\e[0n", 4) != 0) {
|
||||
printf("res = %d?\n", res);
|
||||
return -1;
|
||||
}
|
||||
printf("Hello World! %.19Lg\n", atan2l(x, y));
|
||||
|
||||
// read/print loop so machine doesn't reset on metal
|
||||
for (;;) {
|
||||
if ((res = readansi(0, buf, 16)) > 0) {
|
||||
printf("got %`'.*s\r\n", res, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,12 @@
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/musl/ftw.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,20 @@ void __assert_fail(const char *, const char *, int) hidden relegated;
|
||||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
#define _unassert(x) \
|
||||
do { \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
unreachable; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _npassert(x) \
|
||||
do { \
|
||||
if (__builtin_expect(!(x), 0)) { \
|
||||
notpossible; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_ASSERT_H_ */
|
||||
+24
-39
@@ -1,21 +1,8 @@
|
||||
#ifndef COSMOPOLITAN_LIBC_ATOMIC_H_
|
||||
#define COSMOPOLITAN_LIBC_ATOMIC_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* @fileoverview C11 Atomic Types
|
||||
*
|
||||
* We supoprt C++ and old C compilers. It's recommended you use macros
|
||||
* like `_Atomic(int)` rather than `_Atomic int` or `atomic_int` since
|
||||
* we only define a portability macro for the syntax `_Atomic(T)`.
|
||||
*
|
||||
* @see libc/integral/c.inc
|
||||
* @see libc/intrin/atomic.h
|
||||
*/
|
||||
|
||||
#define atomic_bool _Atomic(_Bool)
|
||||
#define atomic_bool32 atomic_int32
|
||||
#define atomic_bool32 _Atomic(__INT32_TYPE__)
|
||||
#define atomic_char _Atomic(char)
|
||||
#define atomic_schar _Atomic(signed char)
|
||||
#define atomic_uchar _Atomic(unsigned char)
|
||||
@@ -27,29 +14,29 @@ COSMOPOLITAN_C_START_
|
||||
#define atomic_ulong _Atomic(unsigned long)
|
||||
#define atomic_llong _Atomic(long long)
|
||||
#define atomic_ullong _Atomic(unsigned long long)
|
||||
#define atomic_char16_t _Atomic(char16_t)
|
||||
#define atomic_char32_t _Atomic(char32_t)
|
||||
#define atomic_wchar_t _Atomic(wchar_t)
|
||||
#define atomic_intptr_t _Atomic(intptr_t)
|
||||
#define atomic_uintptr_t _Atomic(uintptr_t)
|
||||
#define atomic_size_t _Atomic(size_t)
|
||||
#define atomic_ptrdiff_t _Atomic(ptrdiff_t)
|
||||
#define atomic_int_fast8_t _Atomic(int_fast8_t)
|
||||
#define atomic_uint_fast8_t _Atomic(uint_fast8_t)
|
||||
#define atomic_int_fast16_t _Atomic(int_fast16_t)
|
||||
#define atomic_uint_fast16_t _Atomic(uint_fast16_t)
|
||||
#define atomic_int_fast32_t _Atomic(int_fast32_t)
|
||||
#define atomic_uint_fast32_t _Atomic(uint_fast32_t)
|
||||
#define atomic_int_fast64_t _Atomic(int_fast64_t)
|
||||
#define atomic_uint_fast64_t _Atomic(uint_fast64_t)
|
||||
#define atomic_int_least8_t _Atomic(int_least8_t)
|
||||
#define atomic_uint_least8_t _Atomic(uint_least8_t)
|
||||
#define atomic_int_least16_t _Atomic(int_least16_t)
|
||||
#define atomic_uint_least16_t _Atomic(uint_least16_t)
|
||||
#define atomic_int_least32_t _Atomic(int_least32_t)
|
||||
#define atomic_uint_least32_t _Atomic(uint_least32_t)
|
||||
#define atomic_int_least64_t _Atomic(int_least64_t)
|
||||
#define atomic_uint_least64_t _Atomic(uint_least64_t)
|
||||
#define atomic_char16_t _Atomic(__CHAR16_TYPE__)
|
||||
#define atomic_char32_t _Atomic(__CHAR32_TYPE__)
|
||||
#define atomic_wchar_t _Atomic(__WCHAR_TYPE__)
|
||||
#define atomic_intptr_t _Atomic(__INTPTR_TYPE__)
|
||||
#define atomic_uintptr_t _Atomic(__UINTPTR_TYPE__)
|
||||
#define atomic_size_t _Atomic(__SIZE_TYPE__)
|
||||
#define atomic_ptrdiff_t _Atomic(__PTRDIFF_TYPE__)
|
||||
#define atomic_int_fast8_t _Atomic(__INT_FAST8_TYPE__)
|
||||
#define atomic_uint_fast8_t _Atomic(__UINT_FAST8_TYPE__)
|
||||
#define atomic_int_fast16_t _Atomic(__INT_FAST16_TYPE__)
|
||||
#define atomic_uint_fast16_t _Atomic(__UINT_FAST16_TYPE__)
|
||||
#define atomic_int_fast32_t _Atomic(__INT_FAST32_TYPE__)
|
||||
#define atomic_uint_fast32_t _Atomic(__UINT_FAST32_TYPE__)
|
||||
#define atomic_int_fast64_t _Atomic(__INT_FAST64_TYPE__)
|
||||
#define atomic_uint_fast64_t _Atomic(__UINT_FAST64_TYPE__)
|
||||
#define atomic_int_least8_t _Atomic(__INT_LEAST8_TYPE__)
|
||||
#define atomic_uint_least8_t _Atomic(__UINT_LEAST8_TYPE__)
|
||||
#define atomic_int_least16_t _Atomic(__INT_LEAST16_TYPE__)
|
||||
#define atomic_uint_least16_t _Atomic(__UINT_LEAST16_TYPE__)
|
||||
#define atomic_int_least32_t _Atomic(__INT_LEAST32_TYPE__)
|
||||
#define atomic_uint_least32_t _Atomic(__UINT_LEAST32_TYPE__)
|
||||
#define atomic_int_least64_t _Atomic(__INT_LEAST64_TYPE__)
|
||||
#define atomic_uint_least64_t _Atomic(__UINT_LEAST64_TYPE__)
|
||||
|
||||
#ifdef __CLANG_ATOMIC_BOOL_LOCK_FREE
|
||||
#define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
|
||||
@@ -75,6 +62,4 @@ COSMOPOLITAN_C_START_
|
||||
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_ATOMIC_H_ */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void CPU_AND(cpu_set_t *d, cpu_set_t *x, cpu_set_t *y) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(d->__bits); ++i) {
|
||||
d->__bits[i] = x->__bits[i] & y->__bits[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/intrin/popcnt.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
int CPU_COUNT(cpu_set_t *set) {
|
||||
int i, c;
|
||||
for (c = i = 0; i < ARRAYLEN(set->__bits); ++i) {
|
||||
c += popcnt(set->__bits[i]);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
int CPU_EQUAL(cpu_set_t *x, cpu_set_t *y) {
|
||||
return !memcmp(x, y, sizeof(*x));
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void CPU_OR(cpu_set_t *d, cpu_set_t *x, cpu_set_t *y) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(d->__bits); ++i) {
|
||||
d->__bits[i] = x->__bits[i] | y->__bits[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
void CPU_XOR(cpu_set_t *d, cpu_set_t *x, cpu_set_t *y) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(d->__bits); ++i) {
|
||||
d->__bits[i] = x->__bits[i] ^ y->__bits[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*-*- 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/cpuset.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
void CPU_ZERO(cpu_set_t *set) {
|
||||
bzero(set, sizeof(*set));
|
||||
}
|
||||
File renamed without changes.
@@ -16,16 +16,15 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/futex.internal.h"
|
||||
#include "libc/intrin/pthread.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
|
||||
int _pthread_mutex_wake(pthread_mutex_t *mutex) {
|
||||
if ((IsLinux() || IsOpenbsd()) &&
|
||||
atomic_load_explicit(&mutex->waits, memory_order_relaxed)) {
|
||||
return _futex_wake(&mutex->lock, 1);
|
||||
} else {
|
||||
return 0;
|
||||
/**
|
||||
* Compares two nanosecond timestamps.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*-*- 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"
|
||||
|
||||
/**
|
||||
* Converts timespec interval from nanoseconds.
|
||||
*/
|
||||
struct timespec _timespec_fromnanos(int64_t x) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = x / 1000000000;
|
||||
ts.tv_nsec = x % 1000000000;
|
||||
return ts;
|
||||
}
|
||||
@@ -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 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"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns high-precision timestamp, the C11 way.
|
||||
*
|
||||
* @param ts receives `CLOCK_REALTIME` timestamp
|
||||
* @param base must be `TIME_UTC`
|
||||
* @return `base` on success, or `0` on failure
|
||||
*/
|
||||
int timespec_get(struct timespec *ts, int base) {
|
||||
if (base == TIME_UTC && !clock_gettime(CLOCK_REALTIME, ts)) {
|
||||
return base;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -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 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"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns high-precision timestamp granularity, the C23 way.
|
||||
*
|
||||
* @param ts receives granularity as a relative timestamp
|
||||
* @param base must be `TIME_UTC`
|
||||
* @return `base` on success, or `0` on failure
|
||||
*/
|
||||
int timespec_getres(struct timespec *ts, int base) {
|
||||
if (base == TIME_UTC && !clock_getres(CLOCK_REALTIME, ts)) {
|
||||
return base;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -16,7 +16,6 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
@@ -26,6 +25,6 @@ struct timespec _timespec_real(void) {
|
||||
int ax, dx;
|
||||
struct timespec ts;
|
||||
ax = clock_gettime(CLOCK_REALTIME_FAST, &ts);
|
||||
assert(!ax);
|
||||
if (ax) notpossible;
|
||||
return ts;
|
||||
}
|
||||
@@ -21,12 +21,12 @@
|
||||
/**
|
||||
* Subtracts two nanosecond timestamps.
|
||||
*/
|
||||
struct timespec _timespec_sub(struct timespec x, struct timespec y) {
|
||||
x.tv_sec -= y.tv_sec;
|
||||
x.tv_nsec -= y.tv_nsec;
|
||||
if (x.tv_nsec < 0) {
|
||||
x.tv_nsec += 1000000000;
|
||||
x.tv_sec -= 1;
|
||||
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;
|
||||
a.tv_sec--;
|
||||
}
|
||||
return x;
|
||||
a.tv_nsec -= b.tv_nsec;
|
||||
return a;
|
||||
}
|
||||
File renamed without changes.
+19
-18
@@ -17,8 +17,8 @@
|
||||
#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
|
||||
|
||||
#define SIG_ERR ((void (*)(int))(-1))
|
||||
#define SIG_DFL ((void *)0)
|
||||
#define SIG_IGN ((void *)1)
|
||||
#define SIG_DFL ((void (*)(int))0)
|
||||
#define SIG_IGN ((void (*)(int))1)
|
||||
|
||||
#define MAP_FAILED ((void *)-1)
|
||||
|
||||
@@ -68,7 +68,6 @@ int chdir(const char *);
|
||||
int chmod(const char *, uint32_t);
|
||||
int chown(const char *, uint32_t, uint32_t);
|
||||
int chroot(const char *);
|
||||
int clone(void *, void *, size_t, int, void *, int *, void *, int *);
|
||||
int close(int);
|
||||
int close_range(unsigned, unsigned, unsigned);
|
||||
int closefrom(int);
|
||||
@@ -94,16 +93,15 @@ 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 filecmp(const char *, const char *);
|
||||
int flock(int, int);
|
||||
int fork(void);
|
||||
int fsync(int);
|
||||
int ftruncate(int, int64_t);
|
||||
int getdents(unsigned, void *, unsigned, long *);
|
||||
int getdomainname(char *, size_t);
|
||||
int getegid(void) nosideeffect;
|
||||
int geteuid(void) nosideeffect;
|
||||
int getgid(void) nosideeffect;
|
||||
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;
|
||||
@@ -115,13 +113,15 @@ 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;
|
||||
int getuid(void) libcesque;
|
||||
int iopl(int);
|
||||
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 *, 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);
|
||||
@@ -133,11 +133,11 @@ 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 mlock(const void *, size_t);
|
||||
int mlock2(const void *, size_t, int);
|
||||
int mlockall(int);
|
||||
int munlock(const void *, size_t);
|
||||
int munlockall(void);
|
||||
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, ...);
|
||||
@@ -157,8 +157,6 @@ int rename(const char *, const char *);
|
||||
int renameat(int, const char *, int, const char *);
|
||||
int renameat2(long, const char *, long, const char *, int);
|
||||
int rmdir(const char *);
|
||||
int sched_getaffinity(int, uint64_t, void *);
|
||||
int sched_setaffinity(int, uint64_t, const void *);
|
||||
int sched_yield(void);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
int setegid(uint32_t);
|
||||
@@ -166,6 +164,7 @@ int seteuid(uint32_t);
|
||||
int setfsgid(int);
|
||||
int setfsuid(int);
|
||||
int setgid(int);
|
||||
int setgroups(size_t size, const uint32_t list[]);
|
||||
int setpgid(int, int);
|
||||
int setpgrp(void);
|
||||
int setpriority(int, unsigned, int);
|
||||
@@ -181,7 +180,8 @@ 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_ptrace(int, ...);
|
||||
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||
int sys_sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||
int tcsetpgrp(int, int32_t);
|
||||
int tgkill(int, int, int);
|
||||
int tkill(int, int);
|
||||
int tmpfd(void);
|
||||
@@ -197,6 +197,7 @@ 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, uint32_t);
|
||||
|
||||
+4
-15
@@ -79,14 +79,6 @@ o/$(MODE)/libc/calls/vdsofunc.greg.o: private \
|
||||
-ffreestanding \
|
||||
-fno-sanitize=address
|
||||
|
||||
# we can't use asan because:
|
||||
# asan guard pages haven't been allocated yet
|
||||
o/$(MODE)/libc/calls/directmap.o \
|
||||
o/$(MODE)/libc/calls/directmap-nt.o: private \
|
||||
OVERRIDE_COPTS += \
|
||||
-ffreestanding \
|
||||
-fno-sanitize=address
|
||||
|
||||
# we can't use asan because:
|
||||
# ntspawn allocates 128kb of heap memory via win32
|
||||
o/$(MODE)/libc/calls/ntspawn.o \
|
||||
@@ -144,12 +136,6 @@ o/$(MODE)/libc/calls/ioctl-siocgifconf-nt.o: private \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
# we want small code size because:
|
||||
# to keep .text.head under 4096 bytes
|
||||
o/$(MODE)/libc/calls/mman.greg.o: private \
|
||||
OVERRIDE_COPTS += \
|
||||
-Os
|
||||
|
||||
# we always want -Os because:
|
||||
# va_arg codegen is very bloated in default mode
|
||||
o//libc/calls/open.o \
|
||||
@@ -177,15 +163,18 @@ o//libc/calls/fcntl.o: private \
|
||||
# it's early runtime mandatory and quite huge without it
|
||||
o//libc/calls/getcwd.greg.o \
|
||||
o//libc/calls/getcwd-nt.greg.o \
|
||||
o//libc/calls/getcwd-xnu.greg.o: private \
|
||||
o//libc/calls/getcwd-xnu.greg.o \
|
||||
o//libc/calls/statfs2cosmo.o: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
# 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: private \
|
||||
OVERRIDE_CFLAGS += \
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
|
||||
/**
|
||||
|
||||
+36
-21
@@ -16,36 +16,51 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/rusage.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
/**
|
||||
* Returns how much CPU program has consumed on time-sharing system.
|
||||
* Returns sum of CPU time consumed by current process since birth.
|
||||
*
|
||||
* @return value that can be divided by CLOCKS_PER_SEC, or -1 w/ errno
|
||||
* @see clock_gettime()
|
||||
* This function provides a basic idea of how computationally expensive
|
||||
* your program is, in terms of both the userspace and kernel processor
|
||||
* resources it's hitherto consumed. Here's an example of how you might
|
||||
* display this information:
|
||||
*
|
||||
* printf("consumed %g seconds of cpu time\n",
|
||||
* (double)clock() / CLOCKS_PER_SEC);
|
||||
*
|
||||
* This function offers at best microsecond accuracy on all supported
|
||||
* platforms. Please note the reported values might be a bit chunkier
|
||||
* depending on the kernel scheduler sampling interval see `CLK_TCK`.
|
||||
*
|
||||
* @return units of CPU time consumed, where each unit's time length
|
||||
* should be `1./CLOCKS_PER_SEC` seconds; Cosmopolitan currently
|
||||
* returns the unit count in microseconds, i.e. `CLOCKS_PER_SEC`
|
||||
* is hard-coded as 1000000. On failure this returns -1 / errno.
|
||||
* @raise ENOSYS should be returned currently if run on Bare Metal
|
||||
* @see clock_gettime() which polyfills this on Linux and BSDs
|
||||
* @see getrusage() which polyfills this on XNU and NT
|
||||
*/
|
||||
int64_t clock(void) {
|
||||
int e;
|
||||
struct rusage ru;
|
||||
struct timespec ts;
|
||||
struct NtFileTime creation_time, exit_time, kernel_time, user_time;
|
||||
int64_t proc, total;
|
||||
// polyfill on Windows where CLOCK_PROCESS_CPUTIME_ID may be not available
|
||||
if (IsWindows() && CLOCK_PROCESS_CPUTIME_ID == -1) {
|
||||
proc = GetCurrentProcess();
|
||||
if (!GetProcessTimes(proc, &creation_time, &exit_time, &kernel_time,
|
||||
&user_time))
|
||||
e = errno;
|
||||
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));
|
||||
} else {
|
||||
return -1;
|
||||
total = ReadFileTime(kernel_time) + ReadFileTime(user_time);
|
||||
ts = WindowsDurationToTimeSpec(total);
|
||||
} else if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return ts.tv_sec * CLOCKS_PER_SEC +
|
||||
ts.tv_nsec / (1000000000 / CLOCKS_PER_SEC);
|
||||
// convert nanoseconds to microseconds w/ ceil rounding
|
||||
// this would need roughly ~7,019,309 years to overflow
|
||||
return ts.tv_sec * 1000000 + (ts.tv_nsec + 999) / 1000;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/asan.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
@@ -25,8 +25,6 @@
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
int sys_clock_getres(int, struct timespec *) hidden;
|
||||
|
||||
static int sys_clock_getres_poly(int clock, struct timespec *ts, int64_t real) {
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
ts->tv_sec = 0;
|
||||
@@ -65,6 +63,7 @@ int clock_getres(int clock, struct timespec *ts) {
|
||||
} else {
|
||||
rc = sys_clock_getres(clock, ts);
|
||||
}
|
||||
STRACE("clock_getres(%d, [%s]) → %d% m", clock, DescribeTimespec(rc, ts), rc);
|
||||
STRACE("clock_getres(%s, [%s]) → %d% m", DescribeClockName(clock),
|
||||
DescribeTimespec(rc, ts), rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -16,43 +16,33 @@
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/clockstonanos.internal.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static struct {
|
||||
bool once;
|
||||
char lock;
|
||||
uint64_t base;
|
||||
struct timespec mono;
|
||||
pthread_once_t once;
|
||||
struct timespec base_wall;
|
||||
uint64_t base_tick;
|
||||
} g_mono;
|
||||
|
||||
int sys_clock_gettime_mono(struct timespec *ts) {
|
||||
// this routine stops being monotonic after 194 years of uptime
|
||||
static void sys_clock_gettime_mono_init(void) {
|
||||
g_mono.base_wall = _timespec_real();
|
||||
g_mono.base_tick = rdtsc();
|
||||
}
|
||||
|
||||
int sys_clock_gettime_mono(struct timespec *time) {
|
||||
uint64_t nanos;
|
||||
uint64_t cycles;
|
||||
struct timespec res;
|
||||
if (X86_HAVE(INVTSC)) {
|
||||
if (__threaded) {
|
||||
_spinlock(&g_mono.lock);
|
||||
}
|
||||
if (UNLIKELY(!g_mono.once)) {
|
||||
clock_gettime(CLOCK_REALTIME, &g_mono.mono);
|
||||
g_mono.base = rdtsc();
|
||||
g_mono.once = true;
|
||||
}
|
||||
nanos = ClocksToNanos(rdtsc(), g_mono.base);
|
||||
res = g_mono.mono;
|
||||
res.tv_sec += nanos / 1000000000;
|
||||
res.tv_nsec += nanos % 1000000000;
|
||||
_spunlock(&g_mono.lock);
|
||||
*ts = res;
|
||||
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));
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "libc/calls/asan.internal.h"
|
||||
#include "libc/calls/clock_gettime.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
@@ -66,8 +66,8 @@ int clock_gettime(int clock, struct timespec *ts) {
|
||||
}
|
||||
#if SYSDEBUG
|
||||
if (!__time_critical) {
|
||||
STRACE("clock_gettime(%d, [%s]) → %d% m", clock, DescribeTimespec(rc, ts),
|
||||
rc);
|
||||
STRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock),
|
||||
DescribeTimespec(rc, ts), rc);
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
|
||||
+4
-5
@@ -20,11 +20,10 @@
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
@@ -60,7 +59,7 @@ int close(int fd) {
|
||||
// file descriptors the way __zipos_open() does need to retry if
|
||||
// there's indication this race condition happened.
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
rc = weaken(__zipos_close)(fd);
|
||||
rc = _weaken(__zipos_close)(fd);
|
||||
} else {
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
rc = sys_close(fd);
|
||||
@@ -68,9 +67,9 @@ int close(int fd) {
|
||||
rc = 0;
|
||||
} else {
|
||||
if (__isfdkind(fd, kFdEpoll)) {
|
||||
rc = weaken(sys_close_epoll_nt)(fd);
|
||||
rc = _weaken(sys_close_epoll_nt)(fd);
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = weaken(sys_closesocket_nt)(g_fds.p + fd);
|
||||
rc = _weaken(sys_closesocket_nt)(g_fds.p + fd);
|
||||
} else if (__isfdkind(fd, kFdFile) || //
|
||||
__isfdkind(fd, kFdConsole) || //
|
||||
__isfdkind(fd, kFdProcess)) { //
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
|
||||
File renamed without changes.
@@ -21,7 +21,6 @@
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
@@ -111,8 +110,8 @@ static int sys_copyfile(const char *src, const char *dst, int flags) {
|
||||
* @param flags may have COPYFILE_PRESERVE_TIMESTAMPS, COPYFILE_NOCLOBBER
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int copyfile(const char *src, const char *dst, int flags) {
|
||||
if (!IsWindows() || startswith(src, "/zip/") || startswith(dst, "/zip/")) {
|
||||
int _copyfile(const char *src, const char *dst, int flags) {
|
||||
if (!IsWindows() || _startswith(src, "/zip/") || _startswith(dst, "/zip/")) {
|
||||
return sys_copyfile(src, dst, flags);
|
||||
} else {
|
||||
return sys_copyfile_nt(src, dst, flags);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int copyfile(const char *, const char *, int) paramsnonnull();
|
||||
int _copyfile(const char *, const char *, int) paramsnonnull();
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
@@ -17,25 +17,94 @@
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
.privileged
|
||||
|
||||
// Compares 64-bit signed integers.
|
||||
//
|
||||
// @param rdi points to left integer
|
||||
// @param rsi points to right integer
|
||||
// @return <0, 0, or >0 based on comparison
|
||||
.align 16
|
||||
cmpsq: .leafprologue
|
||||
.profilable
|
||||
xor %eax,%eax
|
||||
cmpsq
|
||||
cmovl .Lone(%rip),%eax
|
||||
cmovg .Lneg1(%rip),%eax
|
||||
.leafepilogue
|
||||
.endfn cmpsq,globl
|
||||
diagnose_syscall:
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
push %rbx
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
|
||||
.rodata.cst4
|
||||
.Lone: .long 1
|
||||
.endobj .Lone
|
||||
.Lneg1: .long -1
|
||||
.endobj .Lneg1
|
||||
.previous
|
||||
mov $0x7fffffff,%eax
|
||||
add $4,%eax # set sf/of/pf
|
||||
|
||||
mov %rdi,%rax # nr
|
||||
mov %rsi,%rdi # arg 1
|
||||
mov %rdx,%rsi # arg 2
|
||||
mov %rcx,%rdx # arg 3
|
||||
mov %r8,%r10 # arg 4
|
||||
mov %r9,%r8 # arg 5
|
||||
mov 16(%rbp),%r9 # arg 6
|
||||
push 24(%rbp) # arg 7
|
||||
push %rax # fake ret addr
|
||||
mov 32(%rbp),%r12 # ucontext before
|
||||
mov 40(%rbp),%r13 # ucontext after
|
||||
xor %ecx,%ecx
|
||||
xor %r11d,%r11d
|
||||
mov $0x5555555555555555,%r11
|
||||
mov $0x5555555555555555,%r14
|
||||
mov $0x5555555555555555,%r15
|
||||
mov $0x5555555555555555,%rbx
|
||||
|
||||
// save machine state before system call
|
||||
pushf
|
||||
pop 176(%r12)
|
||||
mov %r8,40(%r12)
|
||||
mov %r9,48(%r12)
|
||||
mov %r10,56(%r12)
|
||||
mov %r11,64(%r12)
|
||||
mov %r12,72(%r12)
|
||||
mov %r13,80(%r12)
|
||||
mov %r14,88(%r12)
|
||||
mov %r15,96(%r12)
|
||||
mov %rdi,104(%r12)
|
||||
mov %rsi,112(%r12)
|
||||
mov %rbp,120(%r12)
|
||||
mov %rbx,128(%r12)
|
||||
mov %rdx,136(%r12)
|
||||
mov %rax,144(%r12)
|
||||
mov %rcx,152(%r12)
|
||||
push %rbx
|
||||
lea 320(%r12),%rbx
|
||||
mov %rbx,224(%r12) # set fpregs ptr
|
||||
pop %rbx
|
||||
|
||||
syscall
|
||||
|
||||
// save machine state after system call
|
||||
pushf
|
||||
pop 176(%r13)
|
||||
mov %r8,40(%r13)
|
||||
mov %r9,48(%r13)
|
||||
mov %r10,56(%r13)
|
||||
mov %r11,64(%r13)
|
||||
mov %r12,72(%r13)
|
||||
mov %r13,80(%r13)
|
||||
mov %r14,88(%r13)
|
||||
mov %r15,96(%r13)
|
||||
mov %rdi,104(%r13)
|
||||
mov %rsi,112(%r13)
|
||||
mov %rbp,120(%r13)
|
||||
mov %rbx,128(%r13)
|
||||
mov %rdx,136(%r13)
|
||||
mov %rax,144(%r13)
|
||||
mov %rcx,152(%r13)
|
||||
push %rbx
|
||||
lea 320(%r13),%rbx
|
||||
mov %rbx,224(%r13) # set fpregs ptr
|
||||
pop %rbx
|
||||
|
||||
pop %r13
|
||||
pop %r13
|
||||
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
pop %rbx
|
||||
pop %rbp
|
||||
ret
|
||||
.endfn diagnose_syscall,globl
|
||||
+2
-3
@@ -20,7 +20,6 @@
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
@@ -81,9 +80,9 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags, int start) {
|
||||
g_fds.p[newfd].mode = g_fds.p[oldfd].mode;
|
||||
g_fds.p[newfd].flags = g_fds.p[oldfd].flags & ~O_CLOEXEC;
|
||||
if (flags & O_CLOEXEC) g_fds.p[newfd].flags |= O_CLOEXEC;
|
||||
if (g_fds.p[oldfd].kind == kFdSocket && weaken(_dupsockfd)) {
|
||||
if (g_fds.p[oldfd].kind == kFdSocket && _weaken(_dupsockfd)) {
|
||||
g_fds.p[newfd].extra =
|
||||
(intptr_t)weaken(_dupsockfd)((struct SockFd *)g_fds.p[oldfd].extra);
|
||||
(intptr_t)_weaken(_dupsockfd)((struct SockFd *)g_fds.p[oldfd].extra);
|
||||
} else {
|
||||
g_fds.p[newfd].extra = g_fds.p[oldfd].extra;
|
||||
}
|
||||
|
||||
Loaded 100 of 2627 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user