Make improvements

- This change fixes a bug that allowed unbuffered printf() output (to
  streams like stderr) to be truncated. This regression was introduced
  some time between now and the last release.

- POSIX specifies all functions as thread safe by default. This change
  works towards cleaning up our use of the @threadsafe / @threadunsafe
  documentation annotations to reflect that. The goal is (1) to use
  @threadunsafe to document functions which POSIX say needn't be thread
  safe, and (2) use @threadsafe to document functions that we chose to
  implement as thread safe even though POSIX didn't mandate it.

- Tidy up the clock_gettime() implementation. We're now trying out a
  cleaner approach to system call support that aims to maintain the
  Linux errno convention as long as possible. This also fixes bugs that
  existed previously, where the vDSO errno wasn't being translated
  properly. The gettimeofday() system call is now a wrapper for
  clock_gettime(), which reduces bloat in apps that use both.

- The recently-introduced improvements to the execute bit on Windows has
  had bugs fixed. access(X_OK) on a directory on Windows now succeeds.
  fstat() will now perform the MZ/#! ReadFile() operation correctly.

- Windows.h is no longer included in libc/isystem/, because it confused
  PCRE's build system into thinking Cosmopolitan is a WIN32 platform.
  Cosmo's Windows.h polyfill was never even really that good, since it
  only defines a subset of the subset of WIN32 APIs that Cosmo defines.

- The setlongerjmp() / longerjmp() APIs are removed. While they're nice
  APIs that are superior to the standardized setjmp / longjmp functions,
  they weren't superior enough to not be dead code in the monorepo. If
  you use these APIs, please file an issue and they'll be restored.

- The .com appending magic has now been removed from APE Loader.
This commit is contained in:
Justine Tunney 2023-10-02 19:25:19 -07:00
parent b99512ac58
commit ff77f2a6af
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
226 changed files with 708 additions and 2657 deletions

View file

@ -1,68 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/weaken.h"
#include "libc/log/backtrace.internal.h"
#include "libc/runtime/symbols.internal.h"
static _Thread_local bool noreentry;
/**
* Shows backtrace if crash reporting facilities are linked.
*/
void _bt(const char *fmt, ...) {
int e;
va_list va;
if (!noreentry) {
noreentry = true;
} else {
return;
}
if (fmt) {
va_start(va, fmt);
kvprintf(fmt, va);
va_end(va);
}
if (_weaken(ShowBacktrace) && _weaken(GetSymbolTable)) {
e = errno;
_weaken(ShowBacktrace)(2, __builtin_frame_address(0));
errno = e;
} else {
kprintf("_bt() can't show backtrace because you need:\n"
"\t__static_yoink(\"ShowBacktrace\");\n"
"to be linked.\n");
if (_weaken(PrintBacktraceUsingSymbols) && _weaken(GetSymbolTable)) {
e = errno;
_weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0),
_weaken(GetSymbolTable)());
errno = e;
} else {
kprintf("_bt() can't show backtrace because you need:\n"
"\t__static_yoink(\"PrintBacktraceUsingSymbols\");\n"
"\t__static_yoink(\"GetSymbolTable\");\n"
"to be linked.\n");
}
}
noreentry = false;
}

View file

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

View file

@ -51,9 +51,7 @@ void end_cancellation_point(int state) {
}
void report_cancellation_point(void) {
BLOCK_CANCELLATIONS;
_bt("error: need BEGIN/END_CANCELLATION_POINT\n");
ALLOW_CANCELLATIONS;
__builtin_trap();
}
#endif /* MODE_DBG */

View file

@ -33,7 +33,6 @@
* for passing the magic memory handle on Windows NT to CloseHandle().
*
* @asyncsignalsafe
* @threadsafe
*/
struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
int64_t off) {

View file

@ -40,7 +40,6 @@
* by hosing the interrupt descriptors and triple faulting the system.
*
* @asyncsignalsafe
* @threadsafe
* @vforksafe
* @noreturn
*/

View file

@ -40,7 +40,6 @@ __msabi extern typeof(ExitThread) *const __imp_ExitThread;
*
* @param rc only works on Linux and Windows
* @see cthread_exit()
* @threadsafe
* @noreturn
*/
privileged wontreturn void _Exit1(int rc) {

View file

@ -28,6 +28,8 @@
#include "libc/sysv/consts/rlim.h"
#include "libc/sysv/consts/rlimit.h"
// Hack for guessing boundaries of _start()'s stack
//
// Every UNIX system in our support vector creates arg blocks like:
//
// <HIGHEST-STACK-ADDRESS>
@ -53,6 +55,11 @@
// up to the microprocessor page size (this computes the top addr)
// and the bottom is computed by subtracting RLIMIT_STACK rlim_cur
// It's simple but gets tricky if we consider environ can be empty
//
// This code always guesses correctly on Windows because WinMain()
// is written to allocate a stack ourself. Local testing on Linux,
// XNU, FreeBSD, OpenBSD, and NetBSD says that accuracy is ±1 page
// and that error rate applies to both beginning and end addresses
static char *__get_last(char **list) {
char *res = 0;

View file

@ -38,7 +38,6 @@
*
* @return process id (always successful)
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int getpid(void) {

View file

@ -34,7 +34,6 @@
*
* @return thread id greater than zero or -1 w/ errno
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int gettid(void) {

View file

@ -43,7 +43,6 @@ static struct {
* @note this function is not intended for cryptography
* @note this function passes bigcrush and practrand
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
uint64_t _rand64(void) {

View file

@ -3,12 +3,13 @@
#include "libc/intrin/likely.h"
#include "libc/runtime/runtime.h"
#define _KERNTRACE 0 /* not configurable w/ flag yet */
#define _NTTRACE 1 /* not configurable w/ flag yet */
#define _POLLTRACE 0 /* not configurable w/ flag yet */
#define _DATATRACE 1 /* not configurable w/ flag yet */
#define _STDIOTRACE 0 /* not configurable w/ flag yet */
#define _LOCKTRACE 0 /* not configurable w/ flag yet */
#define _NTTRACE 0 /* not configurable w/ flag yet */
#define _STDIOTRACE 0 /* not configurable w/ flag yet */
#define _KERNTRACE 0 /* not configurable w/ flag yet */
#define _TIMETRACE 0 /* not configurable w/ flag yet */
#define STRACE_PROLOGUE "%rSYS %6P %'18T "
@ -63,6 +64,12 @@ COSMOPOLITAN_C_START_
#define LOCKTRACE(FMT, ...) (void)0
#endif
#if defined(SYSDEBUG) && _TIMETRACE
#define TIMETRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__)
#else
#define TIMETRACE(FMT, ...) (void)0
#endif
void __stracef(const char *, ...);
COSMOPOLITAN_C_END_

View file

@ -33,8 +33,9 @@ static char g_strsignal[21];
*
* @param sig is signal number which should be in range 1 through 128
* @return string which is valid code describing signal
* @see strsignal_r() for better thread safety
* @see strsignal_r()
* @see sigaction()
* @threadunsafe
*/
char *strsignal(int sig) {
return strsignal_r(sig, g_strsignal);

View file

@ -34,7 +34,6 @@
* @return pointer to .rodata string, or to `buf` after mutating
* @see sigaction()
* @asyncsignalsafe
* @threadsafe
*/
privileged char *strsignal_r(int sig, char buf[21]) {
const char *s;

View file

@ -19,6 +19,7 @@
#include "libc/dce.h"
#include "libc/intrin/getenv.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
/**
@ -27,15 +28,12 @@
* @param s is non-empty environment key which can't contain `'='`
* @return 0 on success, or -1 w/ errno and environment is unchanged
* @raise EINVAL if `s` is an empty string or has a `'='` character
* @threadunsafe
*/
int unsetenv(const char *s) {
char **p;
struct Env e;
const char *t;
if (!s || !*s) return einval();
for (t = s; *t; ++t) {
if (*t == '=') return einval();
}
if (!s || !*s || strchr(s, '=')) return einval();
if ((p = environ)) {
e = __getenv(p, s);
while (p[e.i]) {