Make improvements

- Improved async signal safety of read() particularly for longjmp()
- Started adding cancel cleanup handlers for locks / etc on Windows
- Make /dev/tty work better particularly for uses like `foo | less`
- Eagerly read console input into a linked list, so poll can signal
- Fix some libc definitional bugs, which configure scripts detected
This commit is contained in:
Justine Tunney 2023-09-21 07:30:39 -07:00
parent d6c2830850
commit 0c5dd7b342
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
85 changed files with 1062 additions and 671 deletions

View file

@ -17,7 +17,6 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "ape/sections.internal.h"
#include "libc/assert.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -120,8 +119,8 @@ textstartup void __enable_tls(void) {
// _tbss_start + _tbss_size:
// _tdata_start + _tls_size:
//
unassert(_tbss_start == _tdata_start + I(_tbss_offset));
unassert(_tbss_start + I(_tbss_size) == _tdata_start + I(_tls_size));
// unassert(_tbss_start == _tdata_start + I(_tbss_offset));
// unassert(_tbss_start + I(_tbss_size) == _tdata_start + I(_tls_size));
#ifdef __x86_64__
@ -136,10 +135,7 @@ textstartup void __enable_tls(void) {
// malloc() being linked, which links _mapanon(). otherwise
// if you exceed this, you need to __static_yoink("_mapanon").
// please note that it's probably too early to call calloc()
npassert(_weaken(_mapanon));
siz = ROUNDUP(siz, FRAMESIZE);
mem = _weaken(_mapanon)(siz);
npassert(mem);
}
if (IsAsan()) {
@ -158,10 +154,7 @@ textstartup void __enable_tls(void) {
if (siz <= sizeof(__static_tls)) {
mem = __static_tls;
} else {
npassert(_weaken(_mapanon));
siz = ROUNDUP(siz, FRAMESIZE);
mem = _weaken(_mapanon)(siz);
npassert(mem);
}
if (IsAsan()) {
@ -221,7 +214,9 @@ textstartup void __enable_tls(void) {
_pthread_list = &_pthread_static.list;
atomic_store_explicit(&_pthread_static.ptid, tid, memory_order_relaxed);
if (IsWindows()) {
npassert((_pthread_static.semaphore = CreateSemaphore(0, 0, 1, 0)));
if (!(_pthread_static.semaphore = CreateSemaphore(0, 0, 1, 0))) {
notpossible;
}
}
// copy in initialized data section

View file

@ -18,6 +18,7 @@
*/
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/symbols.internal.h"
#include "libc/str/str.h"
#include "libc/thread/tls.h"
@ -36,6 +37,9 @@ __static_yoink("zipos");
* @see libc/runtime/_init.S for documentation
*/
textstartup int ftrace_init(void) {
if (strace_enabled(0) > 0) {
GetSymbolTable();
}
if (__intercept_flag(&__argc, __argv, "--ftrace")) {
ftrace_install();
ftrace_enabled(+1);

View file

@ -87,8 +87,8 @@ static textwindows int Count(int c, struct DosArgv *st) {
// @see test/libc/dosarg_test.c
// @see libc/runtime/ntspawn.c
// @note kudos to Simon Tatham for figuring out quoting behavior
textwindows int GetDosArgv(const char16_t *cmdline, char *buf,
size_t size, char **argv, size_t max) {
textwindows int GetDosArgv(const char16_t *cmdline, char *buf, size_t size,
char **argv, size_t max) {
bool inquote;
int i, argc, slashes, quotes, ignore;
static struct DosArgv st_;
@ -107,32 +107,6 @@ textwindows int GetDosArgv(const char16_t *cmdline, char *buf,
if (!st->wc) break;
if (++argc < max) {
argv[argc - 1] = st->p < st->pe ? st->p : NULL;
if (argc == 1) {
// windows lets you run "foo.com" without saying "./foo.com"
// which caused emacs to crash after searching for itself :(
char16_t cmd[256];
uint32_t i, j, attr;
i = j = 0;
cmd[j++] = st->wc;
for (; st->s[i]; ++i) {
if (i == 255 || st->s[i] == '/' || st->s[i] == '\\') {
goto GiveUpAddingDotSlash;
}
if (st->s[i] == ' ' || st->s[i] == '\t') {
break;
}
cmd[j++] = st->s[i];
}
cmd[j] = 0;
if (IsWindows() && //
(attr = __imp_GetFileAttributesW(cmd)) != -1u && //
!(attr & kNtFileAttributeDirectory)) {
AppendDosArgv('.', st);
AppendDosArgv('\\', st);
}
GiveUpAddingDotSlash:
donothing;
}
}
inquote = false;
while (st->wc) {

View file

@ -157,9 +157,9 @@ static bool __auto_map(int count, int align, int *res) {
*res + count <= FRAME(kAutomapStart + (kAutomapSize - 1));
}
static void *__finish_memory(void *addr, size_t size, int prot,
int flags, int fd, int64_t off, int f,
int x, int n, struct DirectMap dm) {
static void *__finish_memory(void *addr, size_t size, int prot, int flags,
int fd, int64_t off, int f, int x, int n,
struct DirectMap dm) {
if (!IsWindows() && (flags & MAP_FIXED)) {
if (__untrack_memories(addr, size)) {
__mmap_die("FIXED UNTRACK FAILED");
@ -178,8 +178,8 @@ static void *__finish_memory(void *addr, size_t size, int prot,
return addr;
}
static void *__map_memory(void *addr, size_t size, int prot, int flags,
int fd, int64_t off, int f, int x, int n) {
static void *__map_memory(void *addr, size_t size, int prot, int flags, int fd,
int64_t off, int f, int x, int n) {
struct DirectMap dm;
dm = sys_mmap(addr, size, prot, f, fd, off);
if (VERY_UNLIKELY(dm.addr == MAP_FAILED)) {
@ -200,9 +200,10 @@ static void *__map_memory(void *addr, size_t size, int prot, int flags,
* This is useful on Windows since it allows us to partially unmap or
* punch holes into existing mappings.
*/
static textwindows dontinline void *__map_memories(
char *addr, size_t size, int prot, int flags, int fd, int64_t off, int f,
int x, int n) {
static textwindows dontinline void *__map_memories(char *addr, size_t size,
int prot, int flags, int fd,
int64_t off, int f, int x,
int n) {
size_t i, m;
int64_t oi, sz;
struct DirectMap dm;
@ -238,8 +239,8 @@ static textwindows dontinline void *__map_memories(
return addr;
}
inline void *__mmap_unlocked(void *addr, size_t size, int prot,
int flags, int fd, int64_t off) {
inline void *__mmap_unlocked(void *addr, size_t size, int prot, int flags,
int fd, int64_t off) {
char *p = addr;
struct DirectMap dm;
size_t requested_size;
@ -480,3 +481,5 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) {
toto);
return res;
}
__strong_reference(mmap, mmap64);

View file

@ -93,6 +93,7 @@ void __printargs(const char *);
int ftrace_install(void);
int ftrace_enabled(int);
int strace_enabled(int);
bool strace_enter(void);
void _bt(const char *, ...);
void __print_maps(void);
long _GetMaxFd(void);
@ -141,6 +142,15 @@ long __get_minsigstksz(void) pureconst;
void __get_main_stack(void **, size_t *, int *);
long __get_safe_size(long, long);
char *__get_tmpdir(void);
__funline int __trace_disabled(int x) {
return 0;
}
#ifndef FTRACE
#define ftrace_enabled __trace_disabled
#endif
#ifndef SYSDEBUG
#define strace_enabled __trace_disabled
#endif
#endif /* _COSMO_SOURCE */
COSMOPOLITAN_C_END_

View file

@ -20,7 +20,6 @@
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nexgen32e/msr.internal.h"
#include "libc/nt/thread.h"
#include "libc/sysv/consts/arch.h"
@ -49,9 +48,7 @@ textstartup void __set_tls(struct CosmoTib *tib) {
sys_set_tls(tib);
} else if (IsXnu()) {
// thread_fast_set_cthread_self has a weird ABI
int e = errno;
sys_set_tls((intptr_t)tib - 0x30);
errno = e;
} else {
uint64_t val = (uint64_t)tib;
asm volatile("wrmsr"

View file

@ -12,7 +12,7 @@ COSMOPOLITAN_C_START_
*/
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 3
#define SYSLIB_VERSION 4
typedef uint64_t dispatch_time_t;
typedef uint64_t dispatch_semaphore_t;
@ -49,6 +49,16 @@ struct Syslib {
int (*__pthread_attr_destroy)(void *);
int (*__pthread_attr_setstacksize)(void *, size_t);
int (*__pthread_attr_setguardsize)(void *, size_t);
/* v4 (2023-09-19) */
void (*__exit)(int);
long (*__close)(int);
long (*__munmap)(void *, size_t);
long (*__openat)(int, const void *, int, int);
long (*__write)(int, const void *, size_t);
long (*__read)(int, void *, size_t);
long (*__sigaction)(int, const void *, void *);
long (*__pselect)(int, void *, void *, void *, const void *, const void *);
long (*__mprotect)(void *, size_t, int);
};
extern struct Syslib *__syslib;

View file

@ -6,10 +6,11 @@ COSMOPOLITAN_C_START_
struct WinArgs {
char *argv[4096];
char *envp[4092];
char *envp[4060];
intptr_t auxv[2][2];
char argblock[ARG_MAX / 2];
char envblock[ARG_MAX / 2];
char argv0buf[256];
};
COSMOPOLITAN_C_END_

View file

@ -19,6 +19,7 @@
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/log/libfatal.internal.h"
@ -145,6 +146,12 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
}
}
// avoid programs like emacs nagging the user to define this
char16_t var[8];
if (!__imp_GetEnvironmentVariableW(u"TERM", var, 8)) {
__imp_SetEnvironmentVariableW(u"TERM", u"xterm-256color");
}
// allocate memory for stack and argument block
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
_mmi.p = _mmi.s;
@ -173,6 +180,21 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
int count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock),
wa->argv, ARRAYLEN(wa->argv));
// normalize executable path
if (wa->argv[0] && !WinFileExists(wa->argv[0])) {
unsigned i, n = 0;
while (wa->argv[0][n]) ++n;
if (n + 4 < sizeof(wa->argv0buf)) {
for (i = 0; i < n; ++i) {
wa->argv0buf[i] = wa->argv[0][i];
}
WRITE32LE(wa->argv0buf + i, READ32LE(".com"));
if (WinFileExists(wa->argv0buf)) {
wa->argv[0] = wa->argv0buf;
}
}
}
// munge argv so dos paths become cosmo paths
for (int i = 0; wa->argv[i]; ++i) {
if (wa->argv[i][0] == '\\' && //