Make improvements

- Expand redbean UNIX module
- Expand redbean documentation
- Ensure Lua copyright is embedded in binary
- Increase the PATH_MAX limit especially on NT
- Use column major sorting for linenoise completions
- Fix some suboptimalities in redbean's new UNIX API
- Figured out right flags for Multics newline in raw mode
This commit is contained in:
Justine Tunney 2022-04-24 09:59:22 -07:00
parent cf3174dc74
commit 2046c0d2ae
305 changed files with 6602 additions and 4221 deletions

View file

@ -59,7 +59,7 @@ STATIC_YOINK("_init_asan");
#define ASAN_MORGUE_ITEMS 512
#define ASAN_MORGUE_THRESHOLD 65536 // morgue memory O(ITEMS*THRESHOLD)
#define ASAN_TRACE_ITEMS 16 // backtrace limit on malloc origin
#define ASAN_TRACE_ITEMS 16 // backtrace limit on malloc origin
/**
* @fileoverview Cosmopolitan Address Sanitizer Runtime.
@ -102,7 +102,7 @@ STATIC_YOINK("_init_asan");
#define REQUIRE(FUNC) \
do { \
if (!weaken(FUNC)) { \
kprintf("error: asan needs %s%n", #FUNC); \
kprintf("error: asan needs %s\n", #FUNC); \
__asan_die()(); \
__asan_unreachable(); \
} \
@ -179,8 +179,7 @@ static uint64_t __asan_roundup2pow(uint64_t x) {
static char *__asan_utf8cpy(char *p, unsigned c) {
uint64_t z;
z = tpenc(c);
do
*p++ = z;
do *p++ = z;
while ((z >>= 8));
return p;
}
@ -322,9 +321,9 @@ static char *__asan_hexcpy(char *p, uint64_t x, uint8_t k) {
}
static void __asan_exit(void) {
kprintf("your asan runtime needs%n"
"\tSTATIC_YOINK(\"__die\");%n"
"in order to show you backtraces%n");
kprintf("your asan runtime needs\n"
"\tSTATIC_YOINK(\"__die\");\n"
"in order to show you backtraces\n");
__restorewintty();
_Exit(99);
}
@ -373,6 +372,7 @@ void __asan_unpoison(long p, long n) {
}
static bool __asan_is_mapped(int x) {
// xxx: we can't lock because no reentrant locks yet
int i;
struct MemoryIntervals *m;
m = weaken(_mmi);
@ -609,7 +609,7 @@ const char *__asan_describe_access_poison(signed char kind) {
dontdiscard static __asan_die_f *__asan_report_invalid_pointer(
const void *addr) {
kprintf("%n\e[J\e[1;31masan error\e[0m: this corruption at %p shadow %p%n",
kprintf("\n\e[J\e[1;31masan error\e[0m: this corruption at %p shadow %p\n",
addr, SHADOW(addr));
return __asan_die();
}
@ -629,7 +629,6 @@ static char *__asan_format_section(char *p, const void *p1, const void *p2,
if (a <= (intptr_t)addr && (intptr_t)addr <= b) {
p = __stpcpy(p, " ←address");
}
if (__nomultics) *p++ = '\r';
*p++ = '\n';
}
return p;
@ -638,7 +637,7 @@ static char *__asan_format_section(char *p, const void *p1, const void *p2,
static void __asan_report_memory_origin_image(intptr_t a, int z) {
unsigned l, m, r, n, k;
struct SymbolTable *st;
kprintf("%nthe memory belongs to image symbols%n");
kprintf("\nthe memory belongs to image symbols\n");
if (weaken(GetSymbolTable)) {
if ((st = weaken(GetSymbolTable)())) {
l = 0;
@ -656,7 +655,7 @@ static void __asan_report_memory_origin_image(intptr_t a, int z) {
if ((st->symbols[l].x <= k && k <= st->symbols[l].y) ||
(st->symbols[l].x <= k + z && k + z <= st->symbols[l].y) ||
(k < st->symbols[l].x && st->symbols[l].y < k + z)) {
kprintf("\t%s [%#x,%#x] size %'d%n", st->name_base + st->names[l],
kprintf("\t%s [%#x,%#x] size %'d\n", st->name_base + st->names[l],
st->addr_base + st->symbols[l].x,
st->addr_base + st->symbols[l].y,
st->symbols[l].y - st->symbols[l].x + 1);
@ -665,10 +664,10 @@ static void __asan_report_memory_origin_image(intptr_t a, int z) {
}
}
} else {
kprintf("\tunknown please supply .com.dbg symbols or set COMDBG%n");
kprintf("\tunknown please supply .com.dbg symbols or set COMDBG\n");
}
} else {
kprintf("\tunknown please STATIC_YOINK(\"GetSymbolTable\");%n");
kprintf("\tunknown please STATIC_YOINK(\"GetSymbolTable\");\n");
}
}
@ -686,13 +685,13 @@ static noasan void OnMemory(void *x, void *y, size_t n, void *a) {
static void __asan_report_memory_origin_heap(const unsigned char *a, int z) {
struct ReportOriginHeap t;
kprintf("%nthe memory was allocated by%n");
kprintf("\nthe memory was allocated by\n");
if (weaken(malloc_inspect_all)) {
t.a = a;
t.z = z;
weaken(malloc_inspect_all)(OnMemory, &t);
} else {
kprintf("\tunknown please STATIC_YOINK(\"malloc_inspect_all\");%n");
kprintf("\tunknown please STATIC_YOINK(\"malloc_inspect_all\");\n");
}
}
@ -737,7 +736,7 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
struct MemoryIntervals *m;
++g_ftrace;
p = __fatalbuf;
kprintf("%n\e[J\e[1;31masan error\e[0m: %s %d-byte %s at %p shadow %p%n%s%n",
kprintf("\n\e[J\e[1;31masan error\e[0m: %s %d-byte %s at %p shadow %p\n%s\n",
__asan_describe_access_poison(kind), size, message, addr,
SHADOW(addr), __argv[0]);
if (0 < size && size < 80) {
@ -753,7 +752,6 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
*p++ = ' ';
}
}
if (__nomultics) *p++ = '\r';
*p++ = '\n';
for (c = i = 0; i < 80; ++i) {
if (!(t = __asan_check(base + i, 1).kind)) {
@ -771,7 +769,6 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
}
}
p = __stpcpy(p, "\e[39m");
if (__nomultics) *p++ = '\r';
*p++ = '\n';
for (i = 0; (intptr_t)(base + i) & 7; ++i) *p++ = ' ';
for (; i + 8 <= 80; i += 8) {
@ -788,19 +785,18 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
}
}
for (; i < 80; ++i) *p++ = ' ';
if (__nomultics) *p++ = '\r';
*p++ = '\n';
for (i = 0; i < 80; ++i) {
p = __asan_utf8cpy(p, __asan_exists(base + i)
? kCp437[((unsigned char *)base)[i]]
: L'');
}
if (__nomultics) *p++ = '\r';
*p++ = '\n';
}
p = __asan_format_section(p, _base, _etext, ".text", addr);
p = __asan_format_section(p, _etext, _edata, ".data", addr);
p = __asan_format_section(p, _end, _edata, ".bss", addr);
// xxx: we can't lock because no reentrant locks yet
for (m = weaken(_mmi), i = 0; i < m->i; ++i) {
x = m->p[i].x;
y = m->p[i].y;
@ -809,13 +805,12 @@ dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
if (x <= z && z <= y) p = __stpcpy(p, " ←address");
z = (((intptr_t)addr >> 3) + 0x7fff8000) >> 16;
if (x <= z && z <= y) p = __stpcpy(p, " ←shadow");
if (__nomultics) *p++ = '\r';
*p++ = '\n';
}
*p = 0;
kprintf("%s", __fatalbuf);
__asan_report_memory_origin(addr, size, kind);
kprintf("%nthe crash was caused by%n");
kprintf("\nthe crash was caused by\n");
--g_ftrace;
return __asan_die();
}
@ -924,8 +919,7 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) {
if (!__asan_checka(SHADOW(bp), sizeof(*bp) >> 3).kind) {
addr = bp->addr;
if (addr == weakaddr("__gc") && weakaddr("__gc")) {
do
--gi;
do --gi;
while ((addr = garbage->p[gi].ret) == weakaddr("__gc"));
}
bt->p[i] = addr;
@ -1018,12 +1012,12 @@ int __asan_print_trace(void *p) {
kprintf(" bad cookie");
return -1;
}
kprintf("%n%p %,lu bytes [asan]", (char *)p, n);
kprintf("\n%p %,lu bytes [asan]", (char *)p, n);
if (!__asan_is_mapped((((intptr_t)p >> 3) + 0x7fff8000) >> 16)) {
kprintf(" (shadow not mapped?!)");
}
for (i = 0; i < ARRAYLEN(e->bt.p) && e->bt.p[i]; ++i) {
kprintf("%n%*lx %s", 12, e->bt.p[i],
kprintf("\n%*lx %s", 12, e->bt.p[i],
weaken(__get_symbol_by_addr)
? weaken(__get_symbol_by_addr)(e->bt.p[i])
: "please STATIC_YOINK(\"__get_symbol_by_addr\")");
@ -1203,7 +1197,7 @@ void __asan_evil(uint8_t *addr, int size, const char *s1, const char *s2) {
struct AsanTrace tr;
__asan_rawtrace(&tr, __builtin_frame_address(0));
kprintf(
"WARNING: ASAN error during %s bad %d byte %s at %x bt %x %x %x %x %x%n",
"WARNING: ASAN error during %s bad %d byte %s at %x bt %x %x %x %x %x\n",
s1, size, s2, addr, tr.p[0], tr.p[1], tr.p[2], tr.p[3], tr.p[4], tr.p[5]);
}
@ -1281,6 +1275,7 @@ void __asan_install_malloc_hooks(void) {
}
void __asan_map_shadow(uintptr_t p, size_t n) {
// assume _mmi.lock is held
void *addr;
int i, a, b;
size_t size;
@ -1311,7 +1306,7 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE,
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED, false, false, 0,
size) == -1) {
kprintf("error: could not map asan shadow memory%n");
kprintf("error: could not map asan shadow memory\n");
__asan_die()();
__asan_unreachable();
}

View file

@ -35,12 +35,12 @@ relegated wontreturn void __assert_fail(const char *expr, const char *file,
static bool noreentry;
__strace = 0;
g_ftrace = 0;
kprintf("%s:%d: assert(%s) failed%n", file, line, expr);
kprintf("%s:%d: assert(%s) failed\n", file, line, expr);
if (_lockcmpxchg(&noreentry, false, true)) {
if (weaken(__die)) {
weaken(__die)();
} else {
kprintf("can't backtrace b/c `__die` not linked%n");
kprintf("can't backtrace b/c `__die` not linked\n");
}
rc = 23;
} else {

View file

@ -26,7 +26,7 @@
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
typedef long long xmm_a __attribute__((__vector_size__(16), __aligned__(16)));
noasan static dontinline antiquity void bzero_sse(char *p, size_t n) {
static dontinline antiquity void bzero_sse(char *p, size_t n) {
xmm_t v = {0};
if (IsAsan()) __asan_verify(p, n);
if (n <= 32) {
@ -43,7 +43,7 @@ noasan static dontinline antiquity void bzero_sse(char *p, size_t n) {
}
}
noasan microarchitecture("avx") static void bzero_avx(char *p, size_t n) {
microarchitecture("avx") static void bzero_avx(char *p, size_t n) {
xmm_t v = {0};
if (IsAsan()) __asan_verify(p, n);
if (n <= 32) {

View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/nt/accounting.h"
#include "libc/nt/thunk/msabi.h"
__msabi extern typeof(GetExitCodeProcess) *const __imp_GetExitCodeProcess;
/**
* Obtains exit code for process.
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
textwindows int32_t GetExitCodeProcess(int64_t hProcess, uint32_t *lpExitCode) {
int32_t rc;
rc = __imp_GetExitCodeProcess(hProcess, lpExitCode);
if (!rc) __winerr();
NTTRACE("GetExitCodeProcess(%ld, [%u]) → %u% m", hProcess, *lpExitCode, rc);
return rc;
}

View file

@ -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/fmt/magnumstrs.internal.h"
const char *GetMagnumStr(const struct MagnumStr *ms, int x) {
int i;
for (i = 0; ms[i].x != -123; ++i) {
if (x == *(const int *)((uintptr_t)ms + ms[i].x)) {
return (const char *)((uintptr_t)ms + ms[i].s);
}
}
return 0;
}

View file

@ -89,9 +89,12 @@ o/$(MODE)/libc/intrin/flushfilebuffers.greg.o \
o/$(MODE)/libc/intrin/terminateprocess.greg.o \
o/$(MODE)/libc/intrin/describemapflags.greg.o \
o/$(MODE)/libc/intrin/getfileattributes.greg.o \
o/$(MODE)/libc/intrin/getexitcodeprocess.greg.o \
o/$(MODE)/libc/intrin/waitforsingleobject.greg.o \
o/$(MODE)/libc/intrin/setcurrentdirectory.greg.o \
o/$(MODE)/libc/intrin/mapviewoffileexnuma.greg.o \
o/$(MODE)/libc/intrin/createfilemappingnuma.greg.o \
o/$(MODE)/libc/intrin/waitformultipleobjects.greg.o \
o/$(MODE)/libc/intrin/generateconsolectrlevent.greg.o \
o/$(MODE)/libc/intrin/kstarttsc.o \
o/$(MODE)/libc/intrin/nomultics.o \

View file

@ -114,7 +114,7 @@ kDos2Errno:
.e kNtErrorCrc,EACCES
.e kNtErrorDirNotEmpty,ENOTEMPTY
.e kNtErrorDupName,EADDRINUSE
.e kNtErrorFilenameExcedRange,ENOENT
.e kNtErrorFilenameExcedRange,ENAMETOOLONG
.e kNtErrorGenFailure,EACCES
.e kNtErrorGracefulDisconnect,EPIPE
.e kNtErrorHostDown,EHOSTUNREACH

View file

@ -32,6 +32,7 @@
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/spinlock.h"
#include "libc/limits.h"
#include "libc/log/internal.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/uart.internal.h"
@ -174,6 +175,7 @@ privileged static inline bool kismemtrackhosed(void) {
}
privileged static bool kismapped(int x) {
// xxx: we can't lock because no reentrant locks yet
size_t m, r, l = 0;
if (!weaken(_mmi)) return true;
if (kismemtrackhosed()) return false;
@ -450,8 +452,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
i = 0;
m = (1 << base) - 1;
if (hash && x) sign = hash;
do
z[i++ & 127] = abet[x & m];
do z[i++ & 127] = abet[x & m];
while ((x >>= base) || (pdot && i < prec));
goto EmitNumber;
@ -556,11 +557,6 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
case 'n':
// nonstandard %n specifier
// used to print newlines that work in raw terminal modes
if (__nomultics) {
if (p < e) *p = '\r';
++p;
}
if (p < e) *p = '\n';
++p;
break;
@ -569,7 +565,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va,
// undocumented %r specifier
// used for good carriage return
// helps integrate loggers with repls
if (!__replmode) {
if (!__replmode || __nocolor) {
break;
} else {
s = "\r\033[K";
@ -845,12 +841,12 @@ privileged size_t kvsnprintf(char *b, size_t n, const char *fmt, va_list v) {
*/
privileged void kvprintf(const char *fmt, va_list v) {
size_t n;
char b[2048];
char b[4000];
struct Timestamps t;
if (!v) return;
t = kenter();
n = kformat(b, sizeof(b), fmt, v, t);
klog(b, MIN(n, sizeof(b)));
klog(b, MIN(n, sizeof(b) - 1));
kleave(t);
}

View file

@ -26,7 +26,7 @@
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
typedef long long xmm_a __attribute__((__vector_size__(16), __aligned__(16)));
noasan static dontinline antiquity void *memset_sse(char *p, char c, size_t n) {
static dontinline antiquity void *memset_sse(char *p, char c, size_t n) {
xmm_t v = {c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c};
if (IsAsan()) __asan_verify(p, n);
if (n <= 32) {
@ -44,8 +44,7 @@ noasan static dontinline antiquity void *memset_sse(char *p, char c, size_t n) {
return p;
}
noasan microarchitecture("avx") static void *memset_avx(char *p, char c,
size_t n) {
microarchitecture("avx") static void *memset_avx(char *p, char c, size_t n) {
char *t;
xmm_t v = {c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c};
if (IsAsan()) __asan_verify(p, n);

View file

@ -17,17 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
/**
* Controls disablement of MULTICS newlines.
*
* Normally we use `\n` for newlines. If this is `true` then we'll try
* our best to use `\r\n`. This is toggled automatically on Windows or
* when `ioctl(TCSETS)` disables `OPOST`.
*
* @see kprintf()
*/
char __nomultics;
/**
* Controls ANSI prefix for log emissions.
*

View file

@ -3,7 +3,6 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern bool __nomultics;
extern bool __replmode;
COSMOPOLITAN_C_END_

View file

@ -25,5 +25,6 @@ __on_arithmetic_overflow:
push %rbp
mov %rsp,%rbp
int3
call abort
0: ud2
jmp 0b
.endfn __on_arithmetic_overflow,weak

View file

@ -197,9 +197,9 @@ static wontreturn void __ubsan_unreachable(void) {
}
static void __ubsan_exit(void) {
kprintf("your ubsan runtime needs%n"
"\tSTATIC_YOINK(\"__die\");%n"
"in order to show you backtraces%n");
kprintf("your ubsan runtime needs\n"
"\tSTATIC_YOINK(\"__die\");\n"
"in order to show you backtraces\n");
__restorewintty();
_Exit(99);
}
@ -214,13 +214,13 @@ dontdiscard static __ubsan_die_f *__ubsan_die(void) {
static void __ubsan_warning(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%s:%d: %subsan warning: %s is undefined behavior%s%n", loc->file,
kprintf("%s:%d: %subsan warning: %s is undefined behavior%s\n", loc->file,
loc->line, SUBTLE, description, RESET);
}
dontdiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%n%s:%d: %subsan error%s: %s%n", loc->file, loc->line, RED2, RESET,
kprintf("\n%s:%d: %subsan error%s: %s\n", loc->file, loc->line, RED2, RESET,
description);
return __ubsan_die();
}

View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/nt/synchronization.h"
#include "libc/nt/thunk/msabi.h"
__msabi extern typeof(WaitForMultipleObjects) *const
__imp_WaitForMultipleObjects;
/**
* Waits for handles to change status.
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
uint32_t WaitForMultipleObjects(uint32_t nCount, const int64_t *lpHandles,
bool32 bWaitAll, uint32_t dwMilliseconds) {
uint32_t x;
x = __imp_WaitForMultipleObjects(nCount, lpHandles, bWaitAll, dwMilliseconds);
if (x == -1u) __winerr();
POLLTRACE("WaitForMultipleObjects(%ld, %p, %hhhd, %'d) → %d% m", nCount,
lpHandles, bWaitAll, dwMilliseconds, x);
return x;
}

View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/nt/synchronization.h"
#include "libc/nt/thunk/msabi.h"
__msabi extern typeof(WaitForSingleObject) *const __imp_WaitForSingleObject;
/**
* Waits for handle to change status.
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds) {
uint32_t rc;
rc = __imp_WaitForSingleObject(hHandle, dwMilliseconds);
if (rc == -1u) __winerr();
POLLTRACE("WaitForSingleObject(%ld, %'d) → %d% m", hHandle, dwMilliseconds,
rc);
return rc;
}