Do code cleanup use duff device linenoise i/o

This commit is contained in:
Justine Tunney 2022-04-22 18:55:28 -07:00
parent 6ff46ca373
commit 2f56ebfe78
79 changed files with 1393 additions and 1484 deletions

View file

@ -28,31 +28,30 @@
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/errfuns.h"
static noasan bool IsExePath(const char *s, size_t n) {
static bool IsExePath(const char *s, size_t n) {
return n >= 4 && (READ32LE(s + n - 4) == READ32LE(".exe") ||
READ32LE(s + n - 4) == READ32LE(".EXE"));
}
static noasan bool IsComPath(const char *s, size_t n) {
static bool IsComPath(const char *s, size_t n) {
return n >= 4 && (READ32LE(s + n - 4) == READ32LE(".com") ||
READ32LE(s + n - 4) == READ32LE(".COM"));
}
static noasan bool IsComDbgPath(const char *s, size_t n) {
static bool IsComDbgPath(const char *s, size_t n) {
return n >= 8 && (READ64LE(s + n - 8) == READ64LE(".com.dbg") ||
READ64LE(s + n - 8) == READ64LE(".COM.DBG"));
}
static noasan bool AccessCommand(const char *name,
char path[hasatleast PATH_MAX], size_t namelen,
int *err, const char *suffix, size_t pathlen) {
static bool AccessCommand(const char *name, char path[hasatleast PATH_MAX],
size_t namelen, int *err, const char *suffix,
size_t pathlen) {
size_t suffixlen;
suffixlen = strlen(suffix);
if (pathlen + 1 + namelen + suffixlen + 1 > PATH_MAX) return false;
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
path[pathlen] = !IsWindows() ? '/'
: memchr(path, '\\', pathlen) ? '\\'
: '/';
path[pathlen] =
!IsWindows() ? '/' : memchr(path, '\\', pathlen) ? '\\' : '/';
pathlen++;
}
memcpy(path + pathlen, name, namelen);
@ -62,8 +61,8 @@ static noasan bool AccessCommand(const char *name,
return false;
}
static noasan bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
size_t namelen, int *err, const char *suffix) {
static bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
size_t namelen, int *err, const char *suffix) {
char sep;
size_t i;
const char *p;
@ -87,10 +86,9 @@ static noasan bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
return false;
}
static noasan bool FindCommand(const char *name,
char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly,
const char *suffix, int *err) {
static bool FindCommand(const char *name, char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly, const char *suffix,
int *err) {
if (priorityonly &&
(memchr(name, '/', namelen) || memchr(name, '\\', namelen))) {
pathbuf[0] = 0;
@ -107,15 +105,13 @@ static noasan bool FindCommand(const char *name,
SearchPath(name, pathbuf, namelen, err, suffix);
}
static noasan bool FindVerbatim(const char *name,
char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly, int *err) {
static bool FindVerbatim(const char *name, char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly, int *err) {
return FindCommand(name, pathbuf, namelen, priorityonly, "", err);
}
static noasan bool FindSuffixed(const char *name,
char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly, int *err) {
static bool FindSuffixed(const char *name, char pathbuf[hasatleast PATH_MAX],
size_t namelen, bool priorityonly, int *err) {
return !IsExePath(name, namelen) && !IsComPath(name, namelen) &&
!IsComDbgPath(name, namelen) &&
(FindCommand(name, pathbuf, namelen, priorityonly, ".com", err) ||
@ -131,7 +127,7 @@ static noasan bool FindSuffixed(const char *name,
* @asyncsignalsafe
* @vforksafe
*/
noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
int e, f;
char *res;
size_t namelen;

View file

@ -73,7 +73,7 @@ int ioctl_tcgets(int fd, ...) {
tio = va_arg(va, struct termios *);
va_end(va);
if (fd >= 0) {
if (!tio) {
if (!tio || (IsAsan() && !__asan_is_valid(tio, sizeof(*tio)))) {
rc = efault();
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
rc = enotty();

View file

@ -68,7 +68,7 @@ int ioctl_tcsets(int fd, uint64_t request, ...) {
va_start(va, request);
tio = va_arg(va, const struct termios *);
va_end(va);
if (!tio) {
if (!tio || (IsAsan() && !__asan_is_valid(tio, sizeof(*tio)))) {
rc = efault();
} else if (fd >= 0) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {

View file

@ -29,7 +29,7 @@ errno_t ptsname_r(int fd, char *buf, size_t size) {
if (size) {
if (!buf) return einval();
if (ioctl(fd, TIOCGPTN, &pty) == -1) return errno;
int64toarray_radix10(pty, stpcpy(tb, "/dev/pts/"));
FormatInt32(stpcpy(tb, "/dev/pts/"), pty);
if (strlen(tb) + 1 >= size) return (errno = ERANGE);
stpcpy(buf, tb);
/* TODO(jart): OpenBSD OMG */

View file

@ -5,10 +5,10 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/struct/stat.h"
#define _KERNTRACE 0 /* not configurable w/ flag yet */
#define _POLLTRACE 0 /* not configurable w/ flag yet */
#define _KERNTRACE 1 /* not configurable w/ flag yet */
#define _POLLTRACE 1 /* not configurable w/ flag yet */
#define _DATATRACE 1 /* not configurable w/ flag yet */
#define _NTTRACE 0 /* not configurable w/ flag yet */
#define _NTTRACE 1 /* not configurable w/ flag yet */
#define STRACE_PROLOGUE "%rSYS %5P %'18T "

View file

@ -64,7 +64,7 @@ static int ttyname_linux(int fd, char *buf, size_t size) {
struct stat st1, st2;
if (!isatty(fd)) return errno;
char name[PATH_MAX];
int64toarray_radix10(fd, stpcpy(name, "/proc/self/fd/"));
FormatInt32(stpcpy(name, "/proc/self/fd/"), fd);
ssize_t got;
got = readlink(name, buf, size);
if (got == -1) return errno;

View file

@ -73,10 +73,10 @@ int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
ip = (uint8_t *)&(((struct sockaddr_in *)addr)->sin_addr);
p = rdomain;
p += int64toarray_radix10(ip[3], p), *p++ = '.';
p += int64toarray_radix10(ip[2], p), *p++ = '.';
p += int64toarray_radix10(ip[1], p), *p++ = '.';
p += int64toarray_radix10(ip[0], p), stpcpy(p, ".in-addr.arpa");
p = FormatUint32(p, ip[3]), *p++ = '.';
p = FormatUint32(p, ip[2]), *p++ = '.';
p = FormatUint32(p, ip[1]), *p++ = '.';
p = FormatUint32(p, ip[0]), stpcpy(p, ".in-addr.arpa");
info[0] = '\0';
if (name != NULL && namelen != 0) {
if ((flags & NI_NUMERICHOST) && (flags & NI_NAMEREQD)) return EAI_NONAME;

View file

@ -147,12 +147,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
continue;
} else if (format[1] == 'd') { /* FAST PATH: PLAIN INTEGER */
d = va_arg(va, int);
if (out(ibuf, arg, int64toarray_radix10(d, ibuf)) == -1) return -1;
if (out(ibuf, arg, FormatInt64(ibuf, d) - ibuf) == -1) return -1;
format += 2;
continue;
} else if (format[1] == 'u') { /* FAST PATH: PLAIN UNSIGNED */
u = va_arg(va, unsigned);
if (out(ibuf, arg, uint64toarray_radix10(u, ibuf)) == -1) return -1;
if (out(ibuf, arg, FormatUint64(ibuf, u) - ibuf) == -1) return -1;
format += 2;
continue;
} else if (format[1] == 'x') { /* FAST PATH: PLAIN HEX */
@ -167,12 +167,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
continue;
} else if (format[1] == 'l' && format[2] == 'd') {
ld = va_arg(va, long); /* FAST PATH: PLAIN LONG */
if (out(ibuf, arg, int64toarray_radix10(ld, ibuf)) == -1) return -1;
if (out(ibuf, arg, FormatInt64(ibuf, ld) - ibuf) == -1) return -1;
format += 3;
continue;
} else if (format[1] == 'l' && format[2] == 'u') {
lu = va_arg(va, unsigned long); /* FAST PATH: PLAIN UNSIGNED LONG */
if (out(ibuf, arg, uint64toarray_radix10(lu, ibuf)) == -1) return -1;
if (out(ibuf, arg, FormatUint64(ibuf, lu) - ibuf) == -1) return -1;
format += 3;
continue;
} else if (format[1] == '.' && format[2] == '*' && format[3] == 's') {

View file

@ -24,7 +24,7 @@
* @param p needs at least 12 bytes
* @return pointer to nul byte
*/
dontinline char *FormatUint32(char p[static 12], uint32_t x) {
dontinline char *FormatUint32(char p[hasatleast 12], uint32_t x) {
char t;
size_t i, a, b;
i = 0;
@ -49,7 +49,7 @@ dontinline char *FormatUint32(char p[static 12], uint32_t x) {
* @param p needs at least 12 bytes
* @return pointer to nul byte
*/
char *FormatInt32(char p[static 12], int32_t x) {
char *FormatInt32(char p[hasatleast 12], int32_t x) {
if (x < 0) *p++ = '-', x = -(uint32_t)x;
return FormatUint32(p, x);
}

View file

@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
@ -16,34 +16,32 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/alg/reverse.internal.h"
#include "libc/fmt/conv.h"
#include "libc/fmt/itoa.h"
#include "libc/limits.h"
/**
* Converts unsigned 64-bit integer to string.
* @param a needs at least 21 bytes
* @return bytes written w/o nul
* Converts unsigned 32-bit integer to octal string.
*
* @param p needs at least 12 bytes
* @param z ensures it starts with zero
* @return pointer to nul byte
*/
dontinline size_t uint64toarray_radix10(uint64_t i, char a[hasatleast 21]) {
size_t j = 0;
char *FormatOctal32(char p[hasatleast 13], uint32_t x, bool z) {
char t;
size_t i, a, b;
i = 0;
z = x && z;
do {
a[j++] = i % 10 + '0';
i = i / 10;
} while (i > 0);
a[j] = '\0';
reverse(a, j);
return j;
}
/**
* Converts signed 64-bit integer to string.
* @param a needs at least 21 bytes
* @return bytes written w/o nul
*/
size_t int64toarray_radix10(int64_t i, char a[hasatleast 21]) {
if (i >= 0) return uint64toarray_radix10(i, a);
*a++ = '-';
return 1 + uint64toarray_radix10(-(uint64_t)i, a);
p[i++] = x % 8 + '0';
x = x / 8;
} while (x > 0);
if (z) p[i++] = '0';
p[i] = '\0';
if (i) {
for (a = 0, b = i - 1; a < b; ++a, --b) {
t = p[a];
p[a] = p[b];
p[b] = t;
}
}
return p + i;
}

47
libc/fmt/formatoctal64.c Normal file
View file

@ -0,0 +1,47 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
/**
* Converts unsigned 64-bit integer to octal string.
*
* @param p needs at least 12 bytes
* @param z ensures it starts with zero
* @return pointer to nul byte
*/
char *FormatOctal64(char p[hasatleast 24], uint64_t x, bool z) {
char t;
size_t i, a, b;
i = 0;
z = x && z;
do {
p[i++] = x % 8 + '0';
x = x / 8;
} while (x > 0);
if (z) p[i++] = '0';
p[i] = '\0';
if (i) {
for (a = 0, b = i - 1; a < b; ++a, --b) {
t = p[a];
p[a] = p[b];
p[b] = t;
}
}
return p + i;
}

View file

@ -2,19 +2,6 @@
#define COSMOPOLITAN_LIBC_FMT_ITOA_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § integer conversion
FASTEST + TINY
- uint64toarray_radix10(0x31337, a) l: 68 (20ns) m: 112 (33ns)
- int64toarray_radix10(0x31337, a) l: 69 (20ns) m: 134 (39ns)
FAST + AWESOME
- snprintf(a, sizeof(a), "%d", 0x31337) l: 199 (58ns) m: 421 (123ns)
- uint128toarray_radix10(0x31337, a) l: 93 (27ns) m: 141 (41ns)
- int128toarray_radix10(0x31337, a) l: 96 (28ns) m: 173 (51ns) */
unsigned LengthInt64(int64_t) pureconst;
unsigned LengthUint64(uint64_t) pureconst;
@ -26,8 +13,8 @@ char *FormatInt64(char[hasatleast 21], int64_t);
char *FormatUint64(char[hasatleast 21], uint64_t);
char *FormatInt64Thousands(char[hasatleast 27], int64_t);
char *FormatUint64Thousands(char[hasatleast 27], uint64_t);
size_t int64toarray_radix10(int64_t, char[hasatleast 21]);
size_t uint64toarray_radix10(uint64_t, char[hasatleast 21]);
char *FormatOctal32(char[hasatleast 13], uint32_t, bool);
char *FormatOctal64(char[hasatleast 24], uint64_t, bool);
size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]);
size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t);
size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]);

View file

@ -722,7 +722,7 @@ static void __asan_report_memory_origin(const unsigned char *addr, int size,
if (_base <= addr && addr < _end) {
__asan_report_memory_origin_image((intptr_t)addr, size);
} else if (IsAutoFrame((intptr_t)addr >> 16)) {
__asan_report_memory_origin_heap(addr, size);
/* __asan_report_memory_origin_heap(addr, size); */
}
}
@ -1202,8 +1202,9 @@ void __asan_unregister_globals(struct AsanGlobal g[], int n) {
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 %p bt %p %p %p %p%n",
s1, size, s2, addr, tr.p[0], tr.p[1], tr.p[2], tr.p[3]);
kprintf(
"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]);
}
void __asan_report_load(uint8_t *addr, int size) {

View file

@ -149,7 +149,7 @@ void(bzero)(void *p, size_t n) {
} while (n);
}
} else if (IsTiny()) {
asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "0"(p), "a"(0));
asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "a"(0));
return;
} else if (X86_HAVE(AVX)) {
bzero_avx(b, n);

View file

@ -116,7 +116,7 @@ o//libc/intrin/memcmp.o \
o//libc/intrin/memset.o \
o//libc/intrin/memmove.o: \
OVERRIDE_CFLAGS += \
-O2
-O2 -finline
o/$(MODE)/libc/intrin/bzero.o \
o/$(MODE)/libc/intrin/memcmp.o \

View file

@ -56,11 +56,11 @@ relegated int(AttachDebugger)(intptr_t continuetoaddr) {
struct StackFrame *bp;
char pidstr[11], breakcmd[40];
const char *se, *elf, *gdb, *rewind, *layout;
__restore_tty();
if (IsGenuineCosmo() || !(gdb = GetGdbPath()) || !isatty(0) || !isatty(1) ||
(ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) == -1) {
return -1;
}
__restore_tty(ttyfd);
ksnprintf(pidstr, sizeof(pidstr), "%u", getpid());
layout = "layout asm";
if ((elf = FindDebugBinary())) {

View file

@ -59,11 +59,12 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
size_t i, j, gi;
int ws, pid, pipefds[2];
struct Garbages *garbage;
sigset_t chldmask, savemask;
const struct StackFrame *frame;
char *debugbin, *p1, *p2, *p3, *addr2line;
char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames];
return -1;
if (!(debugbin = FindDebugBinary())) {
return -1;
}
@ -105,19 +106,15 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
argv[i++] = buf + j;
buf[j++] = '0';
buf[j++] = 'x';
j += uint64toarray_radix16(addr, buf + j) + 1;
j += uint64toarray_radix16(addr - 1, buf + j) + 1;
}
argv[i++] = NULL;
sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &chldmask, &savemask);
pipe(pipefds);
if (!(pid = vfork())) {
sigprocmask(SIG_SETMASK, &savemask, NULL);
dup2(pipefds[1], 1);
if (pipefds[0] != 1) close(pipefds[0]);
if (pipefds[1] != 1) close(pipefds[1]);
execvp(addr2line, argv);
execve(addr2line, argv, environ);
_exit(127);
}
close(pipefds[1]);
@ -150,7 +147,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
if (errno == EINTR) continue;
return -1;
}
sigprocmask(SIG_SETMASK, &savemask, NULL);
if (WIFEXITED(ws) && !WEXITSTATUS(ws)) {
return 0;
} else {

View file

@ -35,7 +35,7 @@
*/
relegated void ___check_fail_ndebug(uint64_t want, uint64_t got,
const char *opchar) {
__restore_tty(1);
__restore_tty();
kprintf("%n%serror: %s: check failed: 0x%x %s 0x%x (%s)%n",
!__nocolor ? "\e[J" : "", program_invocation_name, want, opchar, got,
strerror(errno));

View file

@ -35,7 +35,7 @@ relegated wontreturn void __die(void) {
int rc;
static bool once;
if (_lockcmpxchg(&once, false, true)) {
__restore_tty(1);
__restore_tty();
if (IsDebuggerPresent(false)) {
DebugBreak();
}

View file

@ -10,12 +10,11 @@ COSMOPOLITAN_C_START_
extern hidden bool __nocolor;
extern hidden int kCrashSigs[7];
extern hidden bool g_isrunningundermake;
extern hidden struct termios g_oldtermios;
extern hidden struct sigaction g_oldcrashacts[7];
void __start_fatal(const char *, int) hidden;
void __oncrash(int, struct siginfo *, struct ucontext *) relegated;
void __restore_tty(int);
void __restore_tty(void);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -77,15 +77,15 @@ extern unsigned __log_level; /* log level for runtime check */
// log a message with the specified log level (not checking if LOGGABLE)
#define LOGF(LEVEL, FMT, ...) \
do { \
++g_ftrace; \
flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(LEVEL, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} while (0)
// die with an error message without backtrace and debugger invocation
#define DIEF(FMT, ...) \
do { \
++g_ftrace; \
--g_ftrace; \
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
exit(1); \
unreachable; \
@ -93,7 +93,7 @@ extern unsigned __log_level; /* log level for runtime check */
#define FATALF(FMT, ...) \
do { \
++g_ftrace; \
--g_ftrace; \
ffatalf(kLogFatal, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
unreachable; \
} while (0)
@ -101,78 +101,78 @@ extern unsigned __log_level; /* log level for runtime check */
#define ERRORF(FMT, ...) \
do { \
if (LOGGABLE(kLogError)) { \
++g_ftrace; \
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(kLogError, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define WARNF(FMT, ...) \
do { \
if (LOGGABLE(kLogWarn)) { \
++g_ftrace; \
flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(kLogWarn, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define INFOF(FMT, ...) \
do { \
if (LOGGABLE(kLogInfo)) { \
++g_ftrace; \
flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(kLogInfo, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define VERBOSEF(FMT, ...) \
do { \
if (LOGGABLE(kLogVerbose)) { \
++g_ftrace; \
fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
fverbosef(kLogVerbose, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define DEBUGF(FMT, ...) \
do { \
if (UNLIKELY(LOGGABLE(kLogDebug))) { \
++g_ftrace; \
fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
fdebugf(kLogDebug, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define NOISEF(FMT, ...) \
do { \
if (UNLIKELY(LOGGABLE(kLogNoise))) { \
++g_ftrace; \
fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
--g_ftrace; \
fnoisef(kLogNoise, __FILE__, __LINE__, NULL, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define FLOGF(F, FMT, ...) \
do { \
if (LOGGABLE(kLogInfo)) { \
++g_ftrace; \
flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(kLogInfo, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define FWARNF(F, FMT, ...) \
do { \
if (LOGGABLE(kLogWarn)) { \
++g_ftrace; \
flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
--g_ftrace; \
flogf(kLogWarn, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define FFATALF(F, FMT, ...) \
do { \
++g_ftrace; \
--g_ftrace; \
ffatalf(kLogFatal, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
unreachable; \
} while (0)
@ -180,18 +180,18 @@ extern unsigned __log_level; /* log level for runtime check */
#define FDEBUGF(F, FMT, ...) \
do { \
if (UNLIKELY(LOGGABLE(kLogDebug))) { \
++g_ftrace; \
fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
--g_ftrace; \
fdebugf(kLogDebug, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
#define FNOISEF(F, FMT, ...) \
do { \
if (UNLIKELY(LOGGABLE(kLogNoise))) { \
++g_ftrace; \
fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
--g_ftrace; \
fnoisef(kLogNoise, __FILE__, __LINE__, F, FMT, ##__VA_ARGS__); \
++g_ftrace; \
} \
} while (0)
@ -204,9 +204,9 @@ extern unsigned __log_level; /* log level for runtime check */
int e = errno; \
autotype(FORM) Ax = (FORM); \
if (UNLIKELY(Ax == (typeof(Ax))(-1)) && LOGGABLE(kLogWarn)) { \
++g_ftrace; \
__logerrno(__FILE__, __LINE__, #FORM); \
--g_ftrace; \
__logerrno(__FILE__, __LINE__, #FORM); \
++g_ftrace; \
errno = e; \
} \
Ax; \
@ -217,9 +217,9 @@ extern unsigned __log_level; /* log level for runtime check */
int e = errno; \
autotype(FORM) Ax = (FORM); \
if (Ax == NULL && LOGGABLE(kLogWarn)) { \
++g_ftrace; \
__logerrno(__FILE__, __LINE__, #FORM); \
--g_ftrace; \
__logerrno(__FILE__, __LINE__, #FORM); \
++g_ftrace; \
errno = e; \
} \
Ax; \

View file

@ -41,6 +41,7 @@ LIBC_LOG_A_DIRECTDEPS = \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_TIME \
LIBC_TINYMATH \
LIBC_UNICODE \
@ -58,8 +59,8 @@ $(LIBC_LOG_A).pkg: \
$(LIBC_LOG_A_OBJS) \
$(foreach x,$(LIBC_LOG_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/libc/log/backtrace2.o \
o/$(MODE)/libc/log/backtrace3.o: \
o/$(MODE)/libc/log/backtrace2.greg.o \
o/$(MODE)/libc/log/backtrace3.greg.o: \
OVERRIDE_CFLAGS += \
-fno-sanitize=all
@ -67,6 +68,7 @@ o/$(MODE)/libc/log/checkfail.o: \
OVERRIDE_CFLAGS += \
-mgeneral-regs-only
o/$(MODE)/libc/log/restoretty.greg.o \
o/$(MODE)/libc/log/attachdebugger.o \
o/$(MODE)/libc/log/backtrace2.o \
o/$(MODE)/libc/log/backtrace3.o \

View file

@ -296,7 +296,7 @@ relegated noinstrument void __oncrash(int sig, struct siginfo *si,
: 0);
}
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
__restore_tty(1);
__restore_tty();
ShowCrashReport(err, sig, si, ctx);
__restorewintty();
_Exit(128 + sig);

View file

@ -17,8 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/metatermios.internal.h"
#include "libc/calls/struct/termios.h"
#include "libc/calls/termios.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/log/color.internal.h"
#include "libc/log/internal.h"
@ -26,7 +29,7 @@
#include "libc/sysv/consts/termios.h"
/**
* @fileoverview Terminal Restoration Helper
* @fileoverview Terminal Restoration Helper for System Five.
*
* This is used by the crash reporting functions, e.g. __die(), to help
* ensure the terminal is in an unborked state after a crash happens.
@ -37,26 +40,28 @@
#define DISABLE_MOUSE "\e[?1000;1002;1015;1006l"
#define ANSI_RESTORE RESET_COLOR SHOW_CURSOR DISABLE_MOUSE
struct termios g_oldtermios;
static bool __isrestorable;
static union metatermios __oldtermios;
static textstartup void g_oldtermios_init() {
int e = errno;
tcgetattr(1, &g_oldtermios);
static textstartup void __oldtermios_init() {
int e;
e = errno;
if (sys_ioctl(0, TCGETS, &__oldtermios) != -1) {
__isrestorable = true;
}
errno = e;
}
const void *const g_oldtermios_ctor[] initarray = {
g_oldtermios_init,
const void *const __oldtermios_ctor[] initarray = {
__oldtermios_init,
};
void __restore_tty(int fd) {
void __restore_tty(void) {
int e;
if (!__isworker) {
if (__isrestorable && !__isworker && !__nocolor) {
e = errno;
if (g_oldtermios.c_lflag && !__nocolor && isatty(fd)) {
write(fd, ANSI_RESTORE, strlen(ANSI_RESTORE));
tcsetattr(fd, TCSAFLUSH, &g_oldtermios);
}
sys_write(0, ANSI_RESTORE, strlen(ANSI_RESTORE));
sys_ioctl(0, TCSETSF, &__oldtermios);
errno = e;
}
}

View file

@ -27,7 +27,7 @@
* @note this is support code for __check_fail(), __assert_fail(), etc.
*/
relegated void __start_fatal(const char *file, int line) {
__restore_tty(1);
__restore_tty();
kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
!__nocolor ? "\e[94;49m" : "", file, line,
program_invocation_short_name, !__nocolor ? "\e[0m" : "");

View file

@ -249,7 +249,7 @@ textwindows int sys_fork_nt(void) {
kNtFileFlagOverlapped, 0);
if (pid != -1 && reader != -1 && writer != -1) {
p = stpcpy(forkvar, "_FORK=");
p += uint64toarray_radix10(reader, p);
p = FormatUint64(p, reader);
bzero(&startinfo, sizeof(startinfo));
startinfo.cb = sizeof(struct NtStartupInfo);
startinfo.dwFlags = kNtStartfUsestdhandles;

View file

@ -31,6 +31,7 @@
#include "libc/stdio/stdio.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/time/clockstonanos.internal.h"
#pragma weak stderr
@ -89,7 +90,7 @@ privileged noinstrument noasan noubsan void ftracer(void) {
frame = frame->next;
if (frame->addr != g_lastaddr) {
kprintf("+ %*s%t %d\r\n", GetNestingLevel(frame) * 2, "", frame->addr,
(long)(unsignedsubtract(stamp, g_laststamp) / 3.3));
ClocksToNanos(stamp, g_laststamp));
g_laststamp = X86_HAVE(RDTSCP) ? rdtscp(0) : rdtsc();
g_lastaddr = frame->addr;
}
@ -97,14 +98,15 @@ privileged noinstrument noasan noubsan void ftracer(void) {
noreentry = 0;
}
textstartup void ftrace_install(void) {
textstartup int ftrace_install(void) {
if (GetSymbolTable()) {
g_lastaddr = -1;
g_laststamp = kStartTsc;
g_skew = GetNestingLevelImpl(__builtin_frame_address(0));
ftrace_enabled = 1;
__hook(ftrace_hook, GetSymbolTable());
return __hook(ftrace_hook, GetSymbolTable());
} else {
kprintf("error: --ftrace failed to open symbol table\r\n");
return -1;
}
}

View file

@ -0,0 +1,31 @@
/*-*- 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/runtime/memtrack.internal.h"
bool IsMemtracked(int x, int y) {
unsigned i;
i = FindMemoryInterval(&_mmi, x);
if (i == _mmi.i) return false;
if (x < _mmi.p[i].x) return false;
for (;;) {
if (y <= _mmi.p[i].y) return true;
if (++i == _mmi.i) return false;
if (_mmi.p[i].x != _mmi.p[i - 1].y + 1) return false;
}
}

View file

@ -36,8 +36,8 @@
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/errfuns.h"
static noasan void *MoveMemoryIntervals(struct MemoryInterval *d,
const struct MemoryInterval *s, int n) {
static void *MoveMemoryIntervals(struct MemoryInterval *d,
const struct MemoryInterval *s, int n) {
/* asan runtime depends on this function */
int i;
assert(n >= 0);
@ -53,8 +53,7 @@ static noasan void *MoveMemoryIntervals(struct MemoryInterval *d,
return d;
}
static noasan void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i,
int n) {
static void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, int n) {
/* asan runtime depends on this function */
assert(i >= 0);
assert(i + n <= mm->i);
@ -62,7 +61,7 @@ static noasan void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i,
mm->i -= n;
}
static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
static bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
int prot, flags;
char *base, *shad;
size_t gran, size;
@ -99,7 +98,7 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
return true;
}
noasan int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
/* asan runtime depends on this function */
int rc;
rc = 0;
@ -111,15 +110,15 @@ noasan int CreateMemoryInterval(struct MemoryIntervals *mm, int i) {
return 0;
}
static noasan int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) {
static int PunchHole(struct MemoryIntervals *mm, int x, int y, int i) {
if (CreateMemoryInterval(mm, i) == -1) return -1;
mm->p[i].y = x - 1;
mm->p[i + 1].x = y + 1;
return 0;
}
noasan int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
void wf(struct MemoryIntervals *, int, int)) {
int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
void wf(struct MemoryIntervals *, int, int)) {
unsigned l, r;
assert(y >= x);
assert(AreMemoryIntervalsOk(mm));
@ -158,9 +157,9 @@ noasan int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y,
return 0;
}
noasan int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
int prot, int flags, bool readonlyfile,
bool iscow, long offset, long size) {
int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h,
int prot, int flags, bool readonlyfile, bool iscow,
long offset, long size) {
/* asan runtime depends on this function */
unsigned i;
assert(y >= x);

View file

@ -50,8 +50,9 @@ struct MemoryIntervals {
extern hidden struct MemoryIntervals _mmi;
const char *DescribeFrame(int);
bool IsMemtracked(int, int) hidden;
void PrintSystemMappings(int) hidden;
const char *DescribeFrame(int) hidden;
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
@ -175,18 +176,6 @@ forceinline unsigned FindMemoryInterval(const struct MemoryIntervals *mm,
return l;
}
forceinline bool IsMemtracked(int x, int y) {
unsigned i;
i = FindMemoryInterval(&_mmi, x);
if (i == _mmi.i) return false;
if (x < _mmi.p[i].x) return false;
for (;;) {
if (y <= _mmi.p[i].y) return true;
if (++i == _mmi.i) return false;
if (_mmi.p[i].x != _mmi.p[i - 1].y + 1) return false;
}
}
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_ */

View file

@ -203,9 +203,8 @@ textstartup void __printargs(const char *prologue) {
PRINT(" L%d%s%s %u-way %,u byte cache w/%s "
"%,u sets of %,u byte lines shared across %u threads%s",
CPUID4_CACHE_LEVEL,
CPUID4_CACHE_TYPE == 1 ? " data"
: CPUID4_CACHE_TYPE == 2 ? " code"
: "",
CPUID4_CACHE_TYPE == 1 ? " data"
: CPUID4_CACHE_TYPE == 2 ? " code" : "",
CPUID4_IS_FULLY_ASSOCIATIVE ? " fully-associative" : "",
CPUID4_WAYS_OF_ASSOCIATIVITY, CPUID4_CACHE_SIZE_IN_BYTES,
CPUID4_PHYSICAL_LINE_PARTITIONS > 1 ? " physically partitioned" : "",
@ -245,8 +244,8 @@ textstartup void __printargs(const char *prologue) {
if ((n = poll(pfds, ARRAYLEN(pfds), 0)) != -1) {
for (i = 0; i < ARRAYLEN(pfds); ++i) {
if (i && (pfds[i].revents & POLLNVAL)) continue;
PRINT(" ☼ %d (revents=%#hx F_GETFL=%#x)", i, pfds[i].revents,
fcntl(i, F_GETFL));
PRINT(" ☼ %d (revents=%#hx fcntl(F_GETFL)=%#x isatty()=%hhhd)", i,
pfds[i].revents, fcntl(i, F_GETFL), isatty(i));
}
} else {
PRINT(" poll() returned %d %m", n);

View file

@ -98,7 +98,7 @@ void _weakfree(void *);
void free_s(void *) paramsnonnull() libcesque;
int close_s(int *) paramsnonnull() libcesque;
int OpenExecutable(void);
void ftrace_install(void);
int ftrace_install(void);
long GetResourceLimit(int);
long GetMaxFd(void);
char *GetProgramExecutableName(void);

View file

@ -70,8 +70,9 @@ o/$(MODE)/libc/runtime/getdosargv.o \
o/$(MODE)/libc/runtime/getdosenviron.o \
o/$(MODE)/libc/runtime/hook.greg.o \
o/$(MODE)/libc/runtime/isheap.o \
o/$(MODE)/libc/runtime/memtrack.o \
o/$(MODE)/libc/runtime/memtracknt.o \
o/$(MODE)/libc/runtime/memtrack.greg.o \
o/$(MODE)/libc/runtime/ismemtracked.greg.o \
o/$(MODE)/libc/runtime/metalprintf.greg.o \
o/$(MODE)/libc/runtime/printargs.greg.o \
o/$(MODE)/libc/runtime/mman.greg.o \

View file

@ -25,12 +25,12 @@
char *inet_ntoa(struct in_addr in) {
static char buf[16];
char *p = buf;
p += int64toarray_radix10((in.s_addr >> 000) & 255, p);
p = FormatUint32(p, (in.s_addr >> 000) & 255);
*p++ = '.';
p += int64toarray_radix10((in.s_addr >> 010) & 255, p);
p = FormatUint32(p, (in.s_addr >> 010) & 255);
*p++ = '.';
p += int64toarray_radix10((in.s_addr >> 020) & 255, p);
p = FormatUint32(p, (in.s_addr >> 020) & 255);
*p++ = '.';
p += int64toarray_radix10((in.s_addr >> 030) & 255, p);
p = FormatUint32(p, (in.s_addr >> 030) & 255);
return buf;
}

View file

@ -53,19 +53,19 @@ static relegated void DieBecauseOfQuota(int rc, const char *message) {
}
static relegated void OnXcpu(int sig) {
__restore_tty(2);
__restore_tty();
DieBecauseOfQuota(23, "\n\nSIGXCPU: ran out of cpu");
}
static relegated void OnXfsz(int sig) {
__restore_tty(2);
__restore_tty();
DieBecauseOfQuota(25, "\n\nSIGXFSZ: exceeded maximum file size");
}
relegated void __oom_hook(size_t request) {
int e;
uint64_t toto, newlim;
__restore_tty(2);
__restore_tty();
e = errno;
toto = CountMappedBytes();
kprintf("\n\nWE REQUIRE MORE VESPENE GAS");

View file

@ -48,7 +48,7 @@ static char *strftime_secs(char *p, const char *pe, const struct tm *t) {
int64_t s;
tmp = *t; /* Make a copy, mktime(3) modifies the tm struct. */
s = mktime(&tmp);
int64toarray_radix10(s, ibuf);
FormatInt64(ibuf, s);
return strftime_add(p, pe, ibuf);
}
@ -329,13 +329,13 @@ static char *strftime_timefmt(char *p, const char *pe, const char *format,
if (t->tm_isdst == 0)
#ifdef USG_COMPAT
diff = -timezone;
#else /* !defined USG_COMPAT */
#else /* !defined USG_COMPAT */
continue;
#endif /* !defined USG_COMPAT */
else
#ifdef ALTZONE
diff = -altzone;
#else /* !defined ALTZONE */
#else /* !defined ALTZONE */
continue;
#endif /* !defined ALTZONE */
#endif /* !defined TM_GMTOFF */