Compare commits

...
20 Commits
Author SHA1 Message Date
Justine Tunney ce9aeb2aed Release Cosmopolitan v3.3.7 2024-05-24 19:37:21 -07:00
Justine Tunney ed93fc3dd7 Fix fread() with 2gb+ sizes 2024-05-24 19:28:23 -07:00
Justine Tunney 5f61d273e4 Add hwap constants to sys/auxv.h 2024-05-24 11:44:44 -07:00
Justine Tunney bf3531de81 Make crash reports reliable in multithreaded case 2024-05-24 11:44:44 -07:00
Justine Tunney 3b0ea2db4d Remove -fno-schedule-insns2
This was originally added when we were using the mcount hooking
technique, to prevent the nop from floating above the frame pointer
creation. Now we use a better codegen technique for hooking so it's no
longer needed to sacrifice performance by using this flag.
2024-05-24 11:44:44 -07:00
Justine Tunney f029375d39 Introduce MAP_HUGETLB 2024-05-24 11:44:44 -07:00
Justine Tunney 9b87dd2b87 Refactor some code 2024-05-24 11:44:44 -07:00
Jōshin 787b04f752 Run all BLAKE2B256 test vectors (#1185) 2024-05-24 10:59:23 -07:00
Jōshin 0768807935 Rename python -> python3 (closes #1144) (#1187)
When we removed the com suffix from ape binaries, we broke the build for
ape's python for any case-insensitive file system, i.e. Windows and XNU,
because there is a third_party/python/Python that gets mirrored in the o
directory with the python object files and clashes with the binary name.
This patch hacks around this by renaming the binary to "python3" so that
it no longer clashes with that directory.
2024-05-24 10:56:33 -07:00
Justine Tunney 0b59f01b43 Put confstr() in unistd.h
Fixes #1184
2024-05-21 15:35:06 -07:00
Justine Tunney cf70a44756 Support shebang on Windows
Fixes #1010
2024-05-20 22:11:42 -07:00
Justine Tunney a52792c59f Add some missing build dependencies 2024-05-20 17:23:25 -07:00
Jōshin 65c9b28e99 Fix buffer overflow in os.tmpname (#1180)
At least on macOS, `strlen(getenv("TMPDIR"))` is 50. We now allow a /tmp
that takes up to 120 or so bytes to spell. Instead of overflowing, we do
a bounds check and the function fails successfully on even longer /tmps.

Fixes #1108 (os.tmpname crashes redbean)
2024-05-20 03:46:27 -04:00
Jōshin 4292348707 Import libbsd readpassphrase (#1182)
Included from:

https://gitlab.freedesktop.org/libbsd/libbsd

At commit 04a24db27ad1572f766bad772cdd9c146e6d9cf0.
2024-05-20 03:37:30 -04:00
Jōshin 2ec20b6c4c Fix #922 (Duplicated line) (#1178) 2024-05-20 00:33:50 -07:00
Jōshin 47183551d6 Fix sleb64 (#1179)
Fixes #920
2024-05-20 00:33:17 -07:00
Jōshin 42891e82bb Fix #959 (typo in cosmocc --version) 2024-05-18 15:20:27 -07:00
Gavin Hayes 624119ea38 Fix NT accept/connect not initializing with SO_UPDATE_*_CONTEXT (#1164) 2024-05-17 02:45:30 -07:00
Justine Tunney 2f3c6e7cc3 Revert "Remove zlib namespacing (#1142)"
This reverts commit 5488f0b2ca which was a
good experiment to try, that didn't work out due to #1176

Fixes #1176
2024-05-14 20:45:23 -07:00
Justine Tunney 13b9ecd537 Remove outdated restriction on -Werror on cosmocc
This was a good idea back when we were only using it to build various
open source projects. However it no longer makes sense that many more
people are depending on cosmocc, to develop new software. Our tooling
shouldn't be making these kinds of decisions for the user.
2024-05-09 14:03:51 -07:00
65 changed files with 1056 additions and 319 deletions

No files matched your search

+18 -1
View File
@@ -254,7 +254,24 @@ o/$(MODE)/ape: $(APE_CHECKS) \
endif
# these assembly files are safe to build on aarch64
o/$(MODE)/ape/ape.o: ape/ape.S
o/$(MODE)/ape/ape.o: \
ape/ape.S \
ape/ape.h \
libc/dce.h \
libc/elf/def.h \
ape/relocations.h \
libc/thread/tls.h \
ape/ape.internal.h \
ape/macros.internal.h \
libc/macho.internal.h \
libc/macros.internal.h \
libc/sysv/consts/prot.h \
libc/nt/pedef.internal.h \
libc/runtime/pc.internal.h \
libc/runtime/e820.internal.h \
libc/runtime/mman.internal.h \
libc/nexgen32e/uart.internal.h \
libc/calls/metalfile.internal.h
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/ape/ape.lds: \
-4
View File
@@ -63,10 +63,6 @@ BACKTRACES = \
-fno-optimize-sibling-calls \
-mno-omit-leaf-frame-pointer
ifneq ($(ARCH), aarch64)
BACKTRACES += -fno-schedule-insns2
endif
SANITIZER = \
-fsanitize=address
+16
View File
@@ -0,0 +1,16 @@
#include <stdlib.h>
__static_yoink("__die");
__static_yoink("GetSymbolByAddr");
__static_yoink("malloc_inspect_all");
char *lol(int n) {
return malloc(n);
}
char *(*pLol)(int) = lol;
int main(int argc, char *argv[]) {
char *s = pLol(4);
s[4] = 1;
}
+18 -21
View File
@@ -23,6 +23,7 @@
#include "libc/mem/mem.h"
#include "libc/nt/files.h"
#include "libc/proc/ntspawn.h"
#include "libc/stdio/sysparam.h"
#include "libc/str/str.h"
#include "libc/str/thompike.h"
#include "libc/str/utf16.h"
@@ -31,16 +32,14 @@
#define APPEND(c) \
do { \
if (k == 32766) { \
return e2big(); \
} \
cmdline[k++] = c; \
if (k < size) \
cmdline[k] = c; \
++k; \
} while (0)
static bool NeedsQuotes(const char *s) {
if (!*s) {
static textwindows bool NeedsQuotes(const char *s) {
if (!*s)
return true;
}
do {
switch (*s) {
case '"':
@@ -60,7 +59,7 @@ static inline int IsAlpha(int c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
}
static bool LooksLikeCosmoDrivePath(const char *s) {
static textwindows bool LooksLikeCosmoDrivePath(const char *s) {
return s[0] == '/' && //
IsAlpha(s[1]) && //
s[2] == '/';
@@ -74,12 +73,13 @@ static bool LooksLikeCosmoDrivePath(const char *s) {
//
// @param cmdline is output buffer
// @param argv is an a NULL-terminated array of UTF-8 strings
// @return 0 on success, or -1 w/ errno
// @raise E2BIG if everything is too huge
// @param size is number of characters in cmdline buffer
// @return length on success, which is >=size on truncation
// @see "Everyone quotes command line arguments the wrong way" MSDN
// @see libc/runtime/getdosargv.c
// @asyncsignalsafe
textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
textwindows size_t mkntcmdline(char16_t *cmdline, char *const argv[],
size_t size) {
char *arg;
int slashes, n;
bool needsquote;
@@ -95,9 +95,8 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
} else {
arg = argv[i];
}
if ((needsquote = NeedsQuotes(arg))) {
if ((needsquote = NeedsQuotes(arg)))
APPEND(u'"');
}
for (slashes = j = 0;;) {
wint_t x = arg[j++] & 255;
if (x >= 0300) {
@@ -122,9 +121,8 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
APPEND(u'"');
APPEND(u'"');
} else {
for (s = 0; s < slashes; ++s) {
for (s = 0; s < slashes; ++s)
APPEND(u'\\');
}
slashes = 0;
uint32_t w = EncodeUtf16(x);
do
@@ -132,13 +130,12 @@ textwindows int mkntcmdline(char16_t cmdline[32767], char *const argv[]) {
while ((w >>= 16));
}
}
for (s = 0; s < (slashes << needsquote); ++s) {
for (s = 0; s < (slashes << needsquote); ++s)
APPEND(u'\\');
}
if (needsquote) {
if (needsquote)
APPEND(u'"');
}
}
cmdline[k] = 0;
return 0;
if (size)
cmdline[MIN(k, size - 1)] = 0;
return k;
}
+168 -86
View File
@@ -20,9 +20,15 @@
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/processaccess.h"
#include "libc/nt/enum/processcreationflags.h"
#include "libc/nt/errors.h"
#include "libc/nt/events.h"
#include "libc/nt/files.h"
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
@@ -33,6 +39,7 @@
#include "libc/nt/struct/startupinfo.h"
#include "libc/nt/struct/startupinfoex.h"
#include "libc/proc/ntspawn.h"
#include "libc/stdalign.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#ifdef __x86_64__
@@ -44,14 +51,167 @@ struct SpawnBlock {
char envbuf[32767];
};
static void *ntspawn_malloc(size_t size) {
static textwindows void *ntspawn_malloc(size_t size) {
return HeapAlloc(GetProcessHeap(), 0, size);
}
static void ntspawn_free(void *ptr) {
static textwindows void ntspawn_free(void *ptr) {
HeapFree(GetProcessHeap(), 0, ptr);
}
static textwindows ssize_t ntspawn_read(intptr_t fh, char *buf, size_t len) {
bool ok;
uint32_t got;
struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)};
ok = (ReadFile(fh, buf, len, 0, &overlap) ||
GetLastError() == kNtErrorIoPending) &&
GetOverlappedResult(fh, &overlap, &got, true);
CloseHandle(overlap.hEvent);
return ok ? got : -1;
}
static textwindows int ntspawn2(struct NtSpawnArgs *a, struct SpawnBlock *sb) {
// make executable path
if (__mkntpathath(a->dirhand, a->prog, 0, sb->path) == -1)
return -1;
// open executable
char *p = sb->envbuf;
char *pe = p + sizeof(sb->envbuf);
intptr_t fh = CreateFile(
sb->path, kNtFileGenericRead,
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, 0,
kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0);
if (fh == -1)
return -1;
ssize_t got = ntspawn_read(fh, p, pe - p);
CloseHandle(fh);
if (got < 3)
return enoexec();
pe = p + got;
// handle shebang
size_t i = 0; // represents space of sb->cmdline consumed
if (p[0] == 'M' && p[1] == 'Z') {
// it's a windows executable
} else if (p[0] == '#' && p[1] == '!') {
p += 2;
// make sure we got a complete first line
pe = memchr(p, '\n', pe - p);
if (!pe)
return enoexec();
*pe = 0;
int argc = 0;
char *argv[4];
// it's legal to say "#! /bin/sh"
while (p < pe && (*p == ' ' || *p == '\t'))
++p;
if (p == pe)
return enoexec();
argv[argc++] = p;
// find the optional argument
while (p < pe && !(*p == ' ' || *p == '\t'))
++p;
if (p < pe) {
*p++ = 0;
while (p < pe && (*p == ' ' || *p == '\t'))
++p;
if (p < pe) {
argv[argc++] = p;
}
}
// now add the prog
argv[argc++] = (char *)a->prog;
argv[argc] = 0;
// ignore argv[0]
if (*a->argv)
++a->argv;
// prepend arguments
if ((i += mkntcmdline(sb->cmdline + i, argv, 32767 - i)) >= 32767 - 1)
return e2big();
sb->cmdline[i++] = ' ';
sb->cmdline[i] = 0;
// setup the true executable path
if (__mkntpathath(a->dirhand, argv[0], 0, sb->path) == -1)
return -1;
} else {
// it's something else
return enoexec();
}
// setup arguments and environment
if ((i += mkntcmdline(sb->cmdline + i, a->argv, 32767 - i)) >= 32767)
return e2big();
if (mkntenvblock(sb->envblock, a->envp, a->extravars, sb->envbuf) == -1)
return -1;
// create attribute list
// this code won't call malloc in practice
bool32 ok;
void *freeme = 0;
alignas(16) char memory[128];
size_t size = sizeof(memory);
struct NtProcThreadAttributeList *alist = (void *)memory;
uint32_t items = !!a->opt_hParentProcess + !!a->opt_lpExplicitHandleList;
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
if (!ok && GetLastError() == kNtErrorInsufficientBuffer) {
ok = !!(alist = freeme = ntspawn_malloc(size));
if (ok) {
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
}
}
if (ok && a->opt_hParentProcess) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeParentProcess, &a->opt_hParentProcess,
sizeof(a->opt_hParentProcess), 0, 0);
}
if (ok && a->opt_lpExplicitHandleList) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeHandleList, a->opt_lpExplicitHandleList,
a->dwExplicitHandleCount * sizeof(*a->opt_lpExplicitHandleList), 0, 0);
}
// create the process
int rc;
if (ok) {
struct NtStartupInfoEx info = {
.StartupInfo = *a->lpStartupInfo,
.StartupInfo.cb = sizeof(info),
.lpAttributeList = alist,
};
if (ok) {
if (CreateProcess(sb->path, sb->cmdline, 0, 0, true,
a->dwCreationFlags | kNtCreateUnicodeEnvironment |
kNtExtendedStartupinfoPresent |
kNtInheritParentAffinity |
GetPriorityClass(GetCurrentProcess()),
sb->envblock, a->opt_lpCurrentDirectory,
&info.StartupInfo, a->opt_out_lpProcessInformation)) {
rc = 0;
} else {
rc = -1;
STRACE("CreateProcess() failed w/ %d", GetLastError());
if (GetLastError() == kNtErrorSharingViolation) {
etxtbsy();
} else if (GetLastError() == kNtErrorInvalidName) {
enoent();
}
}
rc = __fix_enotdir(rc, sb->path);
}
} else {
rc = __winerr();
}
// clean up resources
if (alist)
DeleteProcThreadAttributeList(alist);
if (freeme)
ntspawn_free(freeme);
return rc;
}
/**
* Spawns process on Windows NT.
*
@@ -72,93 +232,15 @@ static void ntspawn_free(void *ptr) {
* @see spawnve() which abstracts this function
* @asyncsignalsafe
*/
textwindows int ntspawn(
int64_t dirhand, const char *prog, char *const argv[], char *const envp[],
char *const extravars[], uint32_t dwCreationFlags,
const char16_t *opt_lpCurrentDirectory, int64_t opt_hParentProcess,
int64_t *opt_lpExplicitHandleList, uint32_t dwExplicitHandleCount,
const struct NtStartupInfo *lpStartupInfo,
struct NtProcessInformation *opt_out_lpProcessInformation) {
int rc = -1;
textwindows int ntspawn(struct NtSpawnArgs *args) {
int rc;
struct SpawnBlock *sb;
BLOCK_SIGNALS;
if ((sb = ntspawn_malloc(sizeof(*sb))) &&
__mkntpathath(dirhand, prog, 0, sb->path) != -1) {
if (!mkntcmdline(sb->cmdline, argv) &&
!mkntenvblock(sb->envblock, envp, extravars, sb->envbuf)) {
bool32 ok;
int64_t dp = GetCurrentProcess();
// create attribute list
// this code won't call malloc in practice
void *freeme = 0;
_Alignas(16) char memory[128];
size_t size = sizeof(memory);
struct NtProcThreadAttributeList *alist = (void *)memory;
uint32_t items = !!opt_hParentProcess + !!opt_lpExplicitHandleList;
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
if (!ok && GetLastError() == kNtErrorInsufficientBuffer) {
ok = !!(alist = freeme = ntspawn_malloc(size));
if (ok) {
ok = InitializeProcThreadAttributeList(alist, items, 0, &size);
}
}
if (ok && opt_hParentProcess) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeParentProcess, &opt_hParentProcess,
sizeof(opt_hParentProcess), 0, 0);
}
if (ok && opt_lpExplicitHandleList) {
ok = UpdateProcThreadAttribute(
alist, 0, kNtProcThreadAttributeHandleList,
opt_lpExplicitHandleList,
dwExplicitHandleCount * sizeof(*opt_lpExplicitHandleList), 0, 0);
}
// create the process
if (ok) {
struct NtStartupInfoEx info;
bzero(&info, sizeof(info));
info.StartupInfo = *lpStartupInfo;
info.StartupInfo.cb = sizeof(info);
info.lpAttributeList = alist;
if (ok) {
if (CreateProcess(sb->path, sb->cmdline, 0, 0, true,
dwCreationFlags | kNtCreateUnicodeEnvironment |
kNtExtendedStartupinfoPresent |
kNtInheritParentAffinity |
GetPriorityClass(GetCurrentProcess()),
sb->envblock, opt_lpCurrentDirectory,
&info.StartupInfo, opt_out_lpProcessInformation)) {
rc = 0;
} else {
STRACE("CreateProcess() failed w/ %d", GetLastError());
if (GetLastError() == kNtErrorSharingViolation) {
etxtbsy();
} else if (GetLastError() == kNtErrorInvalidName) {
enoent();
}
}
rc = __fix_enotdir(rc, sb->path);
}
} else {
rc = __winerr();
}
// clean up resources
if (alist) {
DeleteProcThreadAttributeList(alist);
}
if (freeme) {
ntspawn_free(freeme);
}
if (dp && dp != GetCurrentProcess()) {
CloseHandle(dp);
}
}
if ((sb = ntspawn_malloc(sizeof(*sb)))) {
rc = ntspawn2(args, sb);
} else {
rc = -1;
}
if (sb)
ntspawn_free(sb);
ALLOW_SIGNALS;
return rc;
}
+1 -2
View File
@@ -1641,7 +1641,6 @@ static privileged void AllowMmapExec(struct Filter *f) {
//
// - MAP_LOCKED (0x02000)
// - MAP_NONBLOCK (0x10000)
// - MAP_HUGETLB (0x40000)
//
static privileged void AllowMmapNoexec(struct Filter *f) {
static const struct sock_filter fragment[] = {
@@ -1650,7 +1649,7 @@ static privileged void AllowMmapNoexec(struct Filter *f) {
/*L2*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(PROT_READ | PROT_WRITE)),
/*L3*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 8 - 4),
/*L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[3])), // flags
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x52000),
/*L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 0x12000),
/*L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, 1),
/*L7*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
/*L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
-1
View File
@@ -5,7 +5,6 @@
#include "libc/mem/alloca.h"
COSMOPOLITAN_C_START_
ssize_t __robust_writev(int, struct iovec *, int);
int64_t sys_preadv(int, struct iovec *, int, int64_t, int64_t);
int64_t sys_pwritev(int, const struct iovec *, int, int64_t, int64_t);
int64_t sys_readv(int32_t, const struct iovec *, int32_t);
+1 -1
View File
@@ -45,7 +45,7 @@ char *sleb64(char *p, int64_t x) {
*p++ = c;
return p;
} else {
*p++ = c | 64;
*p++ = c | 128;
}
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
#define __COSMOPOLITAN_MAJOR__ 3
#define __COSMOPOLITAN_MINOR__ 3
#define __COSMOPOLITAN_PATCH__ 6
#define __COSMOPOLITAN_PATCH__ 7
#define __COSMOPOLITAN__ \
(100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \
__COSMOPOLITAN_PATCH__)
+10 -1
View File
@@ -82,7 +82,16 @@ o//libc/intrin/memcmp.o \
o//libc/intrin/memset.o \
o//libc/intrin/memmove.o: private \
CFLAGS += \
-O2 -finline -foptimize-sibling-calls
-O2 \
-finline \
-foptimize-sibling-calls
# make asan stack traces shorter
o/$(MODE)/libc/intrin/asanthunk.o: private \
CFLAGS += \
-Os \
$(NO_MAGIC) \
-foptimize-sibling-calls
o/$(MODE)/libc/intrin/bzero.o \
o/$(MODE)/libc/intrin/memcmp.o \
+1
View File
@@ -30,6 +30,7 @@ const char *(DescribeMapFlags)(char buf[64], int x) {
{MAP_SHARED, "SHARED"}, //
{MAP_FIXED, "FIXED"}, //
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
{MAP_HUGETLB, "HUGETLB"}, //
{MAP_CONCEAL, "CONCEAL"}, //
{MAP_LOCKED, "LOCKED"}, //
{MAP_NORESERVE, "NORESERVE"}, //
+2 -1
View File
@@ -18,9 +18,10 @@
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/stdalign.internal.h"
#include "libc/str/str.h"
_Alignas(1) static char strerror_buf[128];
alignas(1) static char strerror_buf[128];
/**
* Returns string describing `err`.
+1
View File
@@ -2,4 +2,5 @@
#define COSMOPOLITAN_LIBC_ISYSTEM_SYS_AUXV_H_
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/hwcap.h"
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_SYS_AUXV_H_ */
+2
View File
@@ -192,6 +192,8 @@ void ShowCrashReportHook(int, int, int, struct siginfo *, ucontext_t *);
static relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
ucontext_t *ctx) {
if (sig != SIGTRAP && sig != SIGQUIT)
sigaddset(&ctx->uc_sigmask, sig);
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Walloca-larger-than="
long size = __get_safe_size(8192, 4096);
+2
View File
@@ -191,6 +191,8 @@ static relegated char *GetSymbolName(struct SymbolTable *st, int symbol) {
static relegated void __oncrash_impl(int sig, struct siginfo *si,
ucontext_t *ctx) {
if (sig != SIGTRAP && sig != SIGQUIT)
sigaddset(&ctx->uc_sigmask, sig);
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Walloca-larger-than="
long size = __get_safe_size(10000, 4096);
+6 -6
View File
@@ -85,13 +85,13 @@ void ShowCrashReports(void) {
#ifdef __x86_64__
InstallCrashHandler(SIGTRAP, 0);
#else
InstallCrashHandler(SIGTRAP, SA_RESETHAND);
InstallCrashHandler(SIGTRAP, 0);
#endif
InstallCrashHandler(SIGFPE, SA_RESETHAND);
InstallCrashHandler(SIGILL, SA_RESETHAND);
InstallCrashHandler(SIGBUS, SA_RESETHAND);
InstallCrashHandler(SIGABRT, SA_RESETHAND);
InstallCrashHandler(SIGSEGV, SA_RESETHAND | SA_ONSTACK);
InstallCrashHandler(SIGFPE, 0);
InstallCrashHandler(SIGILL, 0);
InstallCrashHandler(SIGBUS, 0);
InstallCrashHandler(SIGABRT, 0);
InstallCrashHandler(SIGSEGV, SA_ONSTACK);
}
IGNORE_LEAKS(ShowCrashReports)
+2 -1
View File
@@ -16,6 +16,7 @@
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/stdalign.internal.h"
#include "libc/stdckdint.h"
#include "libc/str/str.h"
@@ -29,7 +30,7 @@
#ifndef MODE_DBG /* don't interfere with asan dlmalloc hooking */
_Alignas(TINYMALLOC_MAX_ALIGN) static struct {
alignas(TINYMALLOC_MAX_ALIGN) static struct {
char memory[TINYMALLOC_MAX_BYTES];
unsigned used, last, free;
} heap;
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kBase36[256] = {
alignas(uint8_t) const uint8_t kBase36[256] = {
['0'] = 1, //
['1'] = 2, //
['2'] = 3, //
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kToLower[256] = {
alignas(uint8_t) const uint8_t kToLower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(uint8_t) const uint8_t kToUpper[256] = {
alignas(uint8_t) const uint8_t kToUpper[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, ' ', '!', '\"', '#', '$', '%', '&', '\'', '(', ')',
+3 -3
View File
@@ -91,9 +91,9 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
// launch the process
struct NtProcessInformation pi;
int rc = ntspawn(AT_FDCWD, program, argv, envp,
(char *[]){fdspec, maskvar, 0}, 0, 0, hParentProcess,
lpExplicitHandles, dwExplicitHandleCount, &si, &pi);
int rc = ntspawn(&(struct NtSpawnArgs){
AT_FDCWD, program, argv, envp, (char *[]){fdspec, maskvar, 0}, 0, 0,
hParentProcess, lpExplicitHandles, dwExplicitHandleCount, &si, &pi});
__undescribe_fds(hParentProcess, lpExplicitHandles, dwExplicitHandleCount);
if (rc == -1) {
free(fdspec);
+4 -3
View File
@@ -344,9 +344,10 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) {
}
#endif
NTTRACE("STARTING SPAWN");
int spawnrc = ntspawn(AT_FDCWD, GetProgramExecutableName(), args, environ,
(char *[]){forkvar, 0}, dwCreationFlags, 0, 0, 0, 0,
&startinfo, &procinfo);
int spawnrc = ntspawn(&(struct NtSpawnArgs){
AT_FDCWD, GetProgramExecutableName(), args, environ,
(char *[]){forkvar, 0}, dwCreationFlags, 0, 0, 0, 0, &startinfo,
&procinfo});
if (spawnrc != -1) {
CloseHandle(procinfo.hThread);
ok = WriteAll(writer, jb, sizeof(jb)) &&
+18 -5
View File
@@ -4,12 +4,25 @@
#include "libc/nt/struct/startupinfo.h"
COSMOPOLITAN_C_START_
void mungentpath(char *);
int mkntcmdline(char16_t[32767], char *const[]);
struct NtSpawnArgs {
int64_t dirhand;
const char *prog;
char *const *argv;
char *const *envp;
char *const *extravars;
uint32_t dwCreationFlags;
const char16_t *opt_lpCurrentDirectory;
int64_t opt_hParentProcess;
int64_t *opt_lpExplicitHandleList;
uint32_t dwExplicitHandleCount;
const struct NtStartupInfo *lpStartupInfo;
struct NtProcessInformation *opt_out_lpProcessInformation;
};
int mkntenvblock(char16_t[32767], char *const[], char *const[], char[32767]);
int ntspawn(int64_t, const char *, char *const[], char *const[], char *const[],
uint32_t, const char16_t *, int64_t, int64_t *, uint32_t,
const struct NtStartupInfo *, struct NtProcessInformation *);
int ntspawn(struct NtSpawnArgs *);
size_t mkntcmdline(char16_t *, char *const[], size_t);
void mungentpath(char *);
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_NTSPAWN_H_ */
+4 -3
View File
@@ -382,9 +382,10 @@ static textwindows errno_t posix_spawn_nt_impl(
envp = environ;
if ((fdspec = __describe_fds(fds.p, fds.n, &startinfo, hCreatorProcess,
&lpExplicitHandles, &dwExplicitHandleCount))) {
rc = ntspawn(dirhand, path, argv, envp, (char *[]){fdspec, maskvar, 0},
dwCreationFlags, lpCurrentDirectory, 0, lpExplicitHandles,
dwExplicitHandleCount, &startinfo, &procinfo);
rc = ntspawn(&(struct NtSpawnArgs){
dirhand, path, argv, envp, (char *[]){fdspec, maskvar, 0},
dwCreationFlags, lpCurrentDirectory, 0, lpExplicitHandles,
dwExplicitHandleCount, &startinfo, &procinfo});
}
if (rc == -1) {
err = errno;
+1 -1
View File
@@ -78,7 +78,7 @@
#define LWP_SUSPENDED 0x00000080
struct CloneArgs {
_Alignas(16) union {
alignas(16) union {
struct {
int tid;
int this;
+2 -1
View File
@@ -35,6 +35,7 @@
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/stdalign.internal.h"
#include "libc/str/locale.h"
#include "libc/str/str.h"
#include "libc/thread/posixthread.internal.h"
@@ -47,7 +48,7 @@
extern unsigned char __tls_mov_nt_rax[];
extern unsigned char __tls_add_nt_rax[];
_Alignas(TLS_ALIGNMENT) static char __static_tls[6016];
alignas(TLS_ALIGNMENT) static char __static_tls[6016];
static unsigned long ParseMask(const char *str) {
int c;
+7 -4
View File
@@ -87,10 +87,6 @@ static int sys_accept_nt_start(int64_t handle, struct NtOverlapped *overlap,
if (g_acceptex.lpAcceptEx(args->listensock, handle, args->buffer, 0,
sizeof(args->buffer->local),
sizeof(args->buffer->remote), 0, overlap)) {
// inherit properties of listening socket
unassert(!__imp_setsockopt(args->listensock, SOL_SOCKET,
kNtSoUpdateAcceptContext, &handle,
sizeof(handle)));
return 0;
} else {
return -1;
@@ -123,6 +119,13 @@ textwindows int sys_accept_nt(struct Fd *f, struct sockaddr_storage *addr,
goto Finish;
}
// inherit properties of listening socket
// errors ignored as if f->handle was created before forking
// this fails with WSAENOTSOCK, see
// https://github.com/jart/cosmopolitan/issues/1174
__imp_setsockopt(resources.handle, SOL_SOCKET, kNtSoUpdateAcceptContext,
&f->handle, sizeof(f->handle));
// create file descriptor for new socket
// don't inherit the file open mode bits
int oflags = 0;
+10 -1
View File
@@ -35,11 +35,14 @@
#include "libc/sock/syscall_fd.internal.h"
#include "libc/sock/wsaid.internal.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sol.h"
#include "libc/sysv/errfuns.h"
#ifdef __x86_64__
#include "libc/sock/yoink.inc"
__msabi extern typeof(__sys_setsockopt_nt) *const __imp_setsockopt;
struct ConnectArgs {
const void *addr;
uint32_t addrsize;
@@ -113,6 +116,8 @@ static textwindows int sys_connect_nt_impl(struct Fd *f, const void *addr,
// return ETIMEDOUT if SO_SNDTIMEO elapsed
// note that Linux will return EINPROGRESS
errno = etimedout();
} else if (!rc) {
__imp_setsockopt(f->handle, SOL_SOCKET, kNtSoUpdateConnectContext, 0, 0);
}
return rc;
}
@@ -131,7 +136,11 @@ static textwindows int sys_connect_nt_impl(struct Fd *f, const void *addr,
ok = WSAGetOverlappedResult(f->handle, overlap, &dwBytes, false, &dwFlags);
WSACloseEvent(overlap->hEvent);
free(overlap);
return ok ? 0 : __winsockerr();
if (!ok) {
return __winsockerr();
}
__imp_setsockopt(f->handle, SOL_SOCKET, kNtSoUpdateConnectContext, 0, 0);
return 0;
} else if (WSAGetLastError() == kNtErrorIoPending) {
f->connect_op = overlap;
return einprogress();
-1
View File
@@ -17,7 +17,6 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/paths.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#include "libc/unistd.h"
+89 -32
View File
@@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/errno.h"
@@ -25,6 +26,41 @@
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
static ssize_t readvall(int fd, struct iovec *iov, int iovlen) {
int olde;
ssize_t rc;
size_t got, toto;
toto = 0;
olde = errno;
do {
if ((rc = readv(fd, iov, iovlen)) == -1) {
if (toto && errno == EINTR) {
errno = olde;
continue;
}
return -1;
}
got = rc;
toto += got;
for (;;) {
if (!iov->iov_len) {
--iovlen;
++iov;
} else if (got >= iov->iov_len) {
got -= iov->iov_len;
--iovlen;
++iov;
} else {
iov->iov_base += got;
iov->iov_len -= got;
break;
}
}
} while (got && iovlen);
return toto;
}
/**
* Reads data from stream.
@@ -36,11 +72,10 @@
size_t fread_unlocked(void *buf, size_t stride, size_t count, FILE *f) {
char *p;
ssize_t rc;
size_t n, m;
struct iovec iov[2];
if (!stride) {
return 0;
}
size_t n, m, got, need;
// check state and parameters
if ((f->iomode & O_ACCMODE) == O_WRONLY) {
f->state = errno = EBADF;
return 0;
@@ -53,52 +88,74 @@ size_t fread_unlocked(void *buf, size_t stride, size_t count, FILE *f) {
f->state = errno = EOVERFLOW;
return 0;
}
if (!n)
return 0;
// try to fulfill request from buffer if possible
p = buf;
m = f->end - f->beg;
if (MIN(n, m)) {
memcpy(p, f->buf + f->beg, MIN(n, m));
}
if (n < m) {
f->beg += n;
return count;
}
if (n == m) {
f->beg = f->end = 0;
if (n <= m) {
memcpy(p, f->buf + f->beg, n);
if ((f->beg += n) == f->end) {
f->beg = 0;
f->end = 0;
}
return count;
}
// handle end-of-file condition in fileless mode
if (f->fd == -1) {
f->beg = 0;
f->end = 0;
f->state = -1;
m /= stride;
m *= stride;
if (m)
memcpy(p, f->buf + f->beg, m);
if ((f->beg += m) == f->end) {
f->state = EOF;
f->beg = 0;
f->end = 0;
}
return m / stride;
}
// `n` is number of bytes requested by caller
// `m` is how much of `n` came from existing buffer
// `iov[0]` reads remainder of the caller request
// `iov[1]` reads ahead extra content into buffer
if (m)
memcpy(p, f->buf + f->beg, m);
iov[0].iov_base = p + m;
iov[0].iov_len = n - m;
iov[0].iov_len = need = n - m;
if (f->bufmode != _IONBF && n < f->size) {
iov[1].iov_base = f->buf;
if (f->size > PUSHBACK) {
if (f->size > PUSHBACK)
iov[1].iov_len = f->size - PUSHBACK;
} else {
else
iov[1].iov_len = f->size;
}
} else {
iov[1].iov_base = NULL;
iov[1].iov_len = 0;
}
if ((rc = readv(f->fd, iov, 2)) == -1) {
if ((rc = readvall(f->fd, iov, 2)) == -1) {
f->state = errno;
return 0;
}
n = rc;
f->beg = 0;
f->end = 0;
if (n > iov[0].iov_len) {
f->end += n - iov[0].iov_len;
return count;
} else {
n = (m + n) / stride;
if (n < count)
f->state = -1;
return n;
got = rc;
// handle partial fulfillment
if (got < need) {
got += m;
if (got % stride) {
f->state = eio();
return 0;
}
f->beg = 0;
f->end = 0;
f->state = EOF;
return got / stride;
}
// handle overfulfillment
f->beg = 0;
f->end = got - need;
return count;
}
+35 -1
View File
@@ -27,6 +27,40 @@
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
static ssize_t writevall(int fd, struct iovec *iov, int iovlen) {
int olde;
ssize_t rc;
size_t got, toto;
toto = 0;
olde = errno;
do {
if ((rc = writev(fd, iov, iovlen)) == -1) {
if (toto && errno == EINTR) {
errno = olde;
continue;
}
return -1;
}
got = rc;
toto += got;
for (;;) {
if (!iov->iov_len) {
--iovlen;
++iov;
} else if (got >= iov->iov_len) {
got -= iov->iov_len;
--iovlen;
++iov;
} else {
iov->iov_base += got;
iov->iov_len -= got;
break;
}
}
} while (got && iovlen);
return toto;
}
/**
* Writes data to stream.
*
@@ -104,7 +138,7 @@ size_t fwrite_unlocked(const void *data, size_t stride, size_t count, FILE *f) {
iov[1].iov_base = (void *)data;
iov[1].iov_len = n;
n += f->beg;
if (__robust_writev(f->fd, iov, 2) == -1) {
if ((rc = writevall(f->fd, iov, 2)) == -1) {
f->state = errno;
return 0;
}
+212
View File
@@ -0,0 +1,212 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set noet ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ │
│ │
│ Copyright (c) 2000-2002, 2007, 2010 │
│ Todd C. Miller <[email protected]> │
│ │
│ Permission to use, copy, modify, and 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. │
│ │
│ Sponsored in part by the Defense Advanced Research Projects │
│ Agency (DARPA) and Air Force Research Laboratory, Air Force │
│ Materiel Command, USAF, under agreement number F39502-99-1-0512. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdio/readpassphrase.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/termios.h"
#include "libc/errno.h"
#include "libc/paths.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/termios.h"
#include "libc/unistd.h"
__notice(readpassphrase_notice, "\
libbsd readpassphrase (ISC)\n\
Copyright (c) 2000-2002, 2007, 2010 Todd C. Miller <[email protected]>");
// clang-format off
#ifndef TCSASOFT
#define TCSASOFT 0
#endif
#ifndef _NSIG
#if defined(NSIG)
#define _NSIG NSIG
#else
/* The SIGRTMAX define might be set to a function such as sysconf(). */
#define _NSIG (SIGRTMAX + 1)
#endif
#endif
static volatile sig_atomic_t signo[_NSIG];
static void handler(int);
char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
{
ssize_t nr;
int input, output, save_errno, i, need_restart;
char ch, *p, *end;
struct termios term, oterm;
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
struct sigaction savetstp, savettin, savettou, savepipe;
/* I suppose we could alloc on demand in this case (XXX). */
if (bufsiz == 0) {
errno = EINVAL;
return(NULL);
}
restart:
for (i = 0; i < _NSIG; i++)
signo[i] = 0;
nr = -1;
save_errno = 0;
need_restart = 0;
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
*/
if ((flags & RPP_STDIN) ||
(input = output = open(_PATH_TTY, O_RDWR)) == -1) {
if (flags & RPP_REQUIRE_TTY) {
errno = ENOTTY;
return(NULL);
}
input = STDIN_FILENO;
output = STDERR_FILENO;
}
/*
* Turn off echo if possible.
* If we are using a tty but are not the foreground pgrp this will
* generate SIGTTOU, so do it *before* installing the signal handlers.
*/
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
memcpy(&term, &oterm, sizeof(term));
if (!(flags & RPP_ECHO_ON))
term.c_lflag &= ~(ECHO | ECHONL);
#ifdef VSTATUS
if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
term.c_cc[VSTATUS] = _POSIX_VDISABLE;
#endif
(void)tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
} else {
memset(&term, 0, sizeof(term));
term.c_lflag |= ECHO;
memset(&oterm, 0, sizeof(oterm));
oterm.c_lflag |= ECHO;
}
/*
* Catch signals that would otherwise cause the user to end
* up with echo turned off in the shell. Don't worry about
* things like SIGXCPU and SIGVTALRM for now.
*/
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0; /* don't restart system calls */
sa.sa_handler = handler;
(void)sigaction(SIGALRM, &sa, &savealrm);
(void)sigaction(SIGHUP, &sa, &savehup);
(void)sigaction(SIGINT, &sa, &saveint);
(void)sigaction(SIGPIPE, &sa, &savepipe);
(void)sigaction(SIGQUIT, &sa, &savequit);
(void)sigaction(SIGTERM, &sa, &saveterm);
(void)sigaction(SIGTSTP, &sa, &savetstp);
(void)sigaction(SIGTTIN, &sa, &savettin);
(void)sigaction(SIGTTOU, &sa, &savettou);
if (!(flags & RPP_STDIN))
(void)write(output, prompt, strlen(prompt));
end = buf + bufsiz - 1;
p = buf;
while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
if (p < end) {
if ((flags & RPP_SEVENBIT))
ch &= 0x7f;
if (isalpha((unsigned char)ch)) {
if ((flags & RPP_FORCELOWER))
ch = (char)tolower((unsigned char)ch);
if ((flags & RPP_FORCEUPPER))
ch = (char)toupper((unsigned char)ch);
}
*p++ = ch;
}
}
*p = '\0';
save_errno = errno;
if (!(term.c_lflag & ECHO))
(void)write(output, "\n", 1);
/* Restore old terminal settings and signals. */
if (memcmp(&term, &oterm, sizeof(term)) != 0) {
const int sigttou = signo[SIGTTOU];
/* Ignore SIGTTOU generated when we are not the fg pgrp. */
while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
errno == EINTR && !signo[SIGTTOU])
continue;
signo[SIGTTOU] = sigttou;
}
(void)sigaction(SIGALRM, &savealrm, NULL);
(void)sigaction(SIGHUP, &savehup, NULL);
(void)sigaction(SIGINT, &saveint, NULL);
(void)sigaction(SIGQUIT, &savequit, NULL);
(void)sigaction(SIGPIPE, &savepipe, NULL);
(void)sigaction(SIGTERM, &saveterm, NULL);
(void)sigaction(SIGTSTP, &savetstp, NULL);
(void)sigaction(SIGTTIN, &savettin, NULL);
(void)sigaction(SIGTTOU, &savettou, NULL);
if (input != STDIN_FILENO)
(void)close(input);
/*
* If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers.
*/
for (i = 0; i < _NSIG; i++) {
if (signo[i]) {
kill(getpid(), i);
if (i == SIGTSTP || i == SIGTTIN || i == SIGTTOU) {
need_restart = 1;
}
}
}
if (need_restart)
goto restart;
if (save_errno)
errno = save_errno;
return(nr == -1 ? NULL : buf);
}
#if 0
char *
getpass(const char *prompt)
{
static char buf[_PASSWORD_LEN + 1];
return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF));
}
#endif
static void handler(int s)
{
signo[s] = 1;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef COSMOPOLITAN_LIBC_STDIO_READPASSPHRASE_H_
#define COSMOPOLITAN_LIBC_STDIO_READPASSPHRASE_H_
#define RPP_ECHO_OFF 0x00
#define RPP_ECHO_ON 0x01
#define RPP_REQUIRE_TTY 0x02
#define RPP_FORCELOWER 0x04
#define RPP_FORCEUPPER 0x08
#define RPP_SEVENBIT 0x10
#define RPP_STDIN 0x20
COSMOPOLITAN_C_START_
char *readpassphrase(const char *, char *, size_t, int) libcesque;
COSMOPOLITAN_C_END_
#endif /* COSMOPOLITAN_LIBC_STDIO_READPASSPHRASE_H_ */
-1
View File
@@ -79,7 +79,6 @@ int setvbuf(FILE *, char *, int, size_t) libcesque;
int pclose(FILE *) libcesque;
char *ctermid(char *) libcesque;
void perror(const char *) libcesque relegated;
size_t confstr(int, char *, size_t) libcesque;
typedef uint64_t fpos_t;
char *gets(char *) libcesque paramsnonnull();
+3 -3
View File
@@ -16,7 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/iovec.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h"
#include "libc/fmt/internal.h"
#include "libc/limits.h"
@@ -42,7 +42,7 @@ static int vdprintf_putc(const char *s, struct VdprintfState *t, size_t n) {
iov[0].iov_len = t->n;
iov[1].iov_base = (void *)s;
iov[1].iov_len = n;
if (__robust_writev(t->fd, iov, 2) == -1) {
if (writev(t->fd, iov, 2) == -1) {
return -1;
}
t->t += t->n;
@@ -68,7 +68,7 @@ int vdprintf(int fd, const char *fmt, va_list va) {
if (t.n) {
iov[0].iov_base = t.b;
iov[0].iov_len = t.n;
if (__robust_writev(t.fd, iov, 1) == -1) {
if (writev(t.fd, iov, 1) == -1) {
return -1;
}
t.t += t.n;
+2 -1
View File
@@ -16,9 +16,10 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdalign.internal.h"
#include "libc/str/tab.internal.h"
_Alignas(int8_t) const int8_t kHexToInt[256] = {
alignas(int8_t) const int8_t kHexToInt[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x20
+1
View File
@@ -230,6 +230,7 @@ syscon mmap MAP_NORESERVE 0x00004000 0x00004000 0x00000040 0x00000040 0
syscon mmap MAP_POPULATE 0x00008000 0x00008000 0 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping
syscon mmap MAP_NONBLOCK 0x00010000 0x00010000 0 0 0 0 0 0
syscon mmap MAP_SYNC 0x00080000 0x00080000 0 0 0 0 0 0 # perform synchronous page faults for mapping (Linux 4.15+)
syscon mmap MAP_HUGETLB 0x00040000 -1 -1 -1 -1 -1 -1 -1 # make it inherit across execve()
syscon mmap MAP_INHERIT -1 -1 -1 -1 -1 -1 0x00000080 -1 # make it inherit across execve()
syscon mmap MAP_HASSEMAPHORE 0 0 0x00000200 0x00000200 0x00000200 0 0x00000200 0 # does it matter on x86?
syscon mmap MAP_NOSYNC 0 0 0 0 0x00000800 0 0 0 # flush to physical media only when necessary rather than gratuitously; be sure to use write() rather than ftruncate() with this!
+2
View File
@@ -0,0 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon mmap,MAP_HUGETLB,0x00040000,-1,-1,-1,-1,-1,-1,-1
+1
View File
@@ -13,6 +13,7 @@ extern const int MAP_FILE;
extern const int MAP_FIXED;
extern const int MAP_FIXED_NOREPLACE;
extern const int MAP_HASSEMAPHORE;
extern const int MAP_HUGETLB;
extern const int MAP_INHERIT;
extern const int MAP_JIT;
extern const int MAP_LOCKED;
+5
View File
@@ -13,6 +13,7 @@ LIBC_TESTLIB_A = o/$(MODE)/libc/testlib/testlib.a
LIBC_TESTLIB_A_CHECKS = $(LIBC_TESTLIB_A).pkg
LIBC_TESTLIB_A_ASSETS = \
libc/testlib/blake2b256_tests.txt \
libc/testlib/blocktronics.txt \
libc/testlib/viewables.txt \
libc/testlib/hyperion.txt \
@@ -32,6 +33,7 @@ LIBC_TESTLIB_A_HDRS = \
LIBC_TESTLIB_A_SRCS_S = \
libc/testlib/bench.S \
libc/testlib/blake2b256_tests.S \
libc/testlib/blocktronics.S \
libc/testlib/fixture.S \
libc/testlib/hyperion.S \
@@ -124,6 +126,7 @@ $(LIBC_TESTLIB_A).pkg: \
$(LIBC_TESTLIB_A_OBJS) \
$(foreach x,$(LIBC_TESTLIB_A_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/libc/testlib/blake2b256_tests.o: libc/testlib/blake2b256_tests.txt
o/$(MODE)/libc/testlib/blocktronics.o: libc/testlib/blocktronics.txt
o/$(MODE)/libc/testlib/viewables.o: libc/testlib/viewables.txt
o/$(MODE)/libc/testlib/hyperion.o: libc/testlib/hyperion.txt
@@ -132,6 +135,8 @@ o/$(MODE)/libc/testlib/moby.o: libc/testlib/moby.txt
# these assembly files are safe to build on aarch64
o/$(MODE)/libc/testlib/bench.o: libc/testlib/bench.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/testlib/blake2b256_tests.o: libc/testlib/blake2b256_tests.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/testlib/blocktronics.o: libc/testlib/blocktronics.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/testlib/fixture.o: libc/testlib/fixture.S
@@ -1,7 +1,7 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ Copyright 2024 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,30 +16,18 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/iovec.internal.h"
#include "libc/errno.h"
#include "libc/macros.internal.h"
.rodata
ssize_t __robust_writev(int fd, struct iovec *iov, int iovlen) {
ssize_t rc;
size_t wrote;
do {
if ((rc = writev(fd, iov, iovlen)) != -1) {
wrote = rc;
do {
if (wrote >= iov->iov_len) {
wrote -= iov->iov_len;
++iov;
--iovlen;
} else {
iov->iov_base = (char *)iov->iov_base + wrote;
iov->iov_len -= wrote;
wrote = 0;
}
} while (wrote);
} else if (errno != EINTR) {
return -1;
}
} while (iovlen);
return 0;
}
// Blake2B256 test vectors.
.underrun
kBlake2b256Tests:
0: .incbin "libc/testlib/blake2b256_tests.txt"
1: .byte 0
.endobj kBlake2b256Tests,globl
.overrun
.balign 8
kBlake2b256TestsSize:
.quad 1b-0b
.endobj kBlake2b256TestsSize,globl
File renamed without changes.
+2 -1
View File
@@ -17,6 +17,7 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/kprintf.h"
#include "libc/intrin/safemacros.internal.h"
#include "libc/math.h"
#include "libc/runtime/runtime.h"
@@ -32,7 +33,7 @@ void __testlib_ezbenchreport_n(const char *form, char z, size_t n, double c) {
char msg[128];
__warn_if_powersave();
ksnprintf(msg, sizeof(msg), "%s %c=%d", form, z, n);
cn = lrint(c / 3);
cn = max(lrint(c / 3), 1);
if (!n) {
kprintf("\n");
kprintf(" * %-28s", msg);
+2
View File
@@ -4,6 +4,8 @@ COSMOPOLITAN_C_START_
#define _CS_PATH 0
size_t confstr(int, char *, size_t) libcesque;
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || \
defined(_COSMO_SOURCE)
void encrypt(char *, int) libcesque;
-1
View File
@@ -1817,7 +1817,6 @@ StartOver:
CHECK_DB(sqlite3_bind_int64(stmt, 1, v[i].ip));
CHECK_DB(sqlite3_bind_text(stmt, 2, v[i].name, -1, SQLITE_TRANSIENT));
CHECK_DB(sqlite3_bind_int64(stmt, 3, v[i].created));
CHECK_DB(sqlite3_bind_int64(stmt, 3, v[i].created));
CHECK_DB((rc = DbStep(stmt)) == SQLITE_DONE ? SQLITE_OK : rc);
CHECK_DB(sqlite3_reset(stmt));
++processed;
+24 -10
View File
@@ -27,39 +27,53 @@
char16_t cmdline[32767];
TEST(mkntcmdline, empty) {
char16_t buf2[2];
EXPECT_EQ(0, mkntcmdline(buf2, (char *[]){0}, 2));
EXPECT_STREQ(u"", buf2);
}
TEST(mkntcmdline, truncation) {
char *argv[] = {"foo", NULL};
EXPECT_EQ(3, mkntcmdline(0, argv, 0));
char16_t buf2[2];
EXPECT_EQ(3, mkntcmdline(buf2, argv, 2));
EXPECT_STREQ(u"f", buf2);
}
TEST(mkntcmdline, emptyArgvList_cantBeEmptyOnWindows) {
char *argv[] = {"foo", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"foo", cmdline);
}
TEST(mkntcmdline, emptyArgvListWithProg_isEmpty) {
char *argv[] = {NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"", cmdline);
}
TEST(mkntcmdline, emptyArg_getsQuoted) {
char *argv[] = {"", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"\"\"", cmdline);
}
TEST(mkntcmdline, ignoranceIsBliss) {
char *argv[] = {"echo", "hello", "world", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"echo hello world", cmdline);
}
TEST(mkntcmdline, spaceInArgument_getQuotesWrappedAround) {
char *argv[] = {"echo", "hello there", "world", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"echo \"hello there\" world", cmdline);
}
TEST(mkntcmdline, justSlash) {
char *argv[] = {"\\", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"\\", cmdline);
}
@@ -69,7 +83,7 @@ TEST(mkntcmdline, testUnicode) {
gc(strdup("要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非")),
NULL,
};
EXPECT_NE(-1, mkntcmdline(cmdline, argv1));
EXPECT_NE(-1, mkntcmdline(cmdline, argv1, 32767));
EXPECT_STREQ(u"(╯°□°)╯ \"要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非\"",
cmdline);
}
@@ -80,13 +94,13 @@ TEST(mkntcmdline, fixit) {
"--version",
NULL,
};
EXPECT_NE(-1, mkntcmdline(cmdline, argv1));
EXPECT_NE(-1, mkntcmdline(cmdline, argv1, 32767));
EXPECT_STREQ(u"\"C:\\Program Files\\doom\\doom.exe\" --version", cmdline);
}
TEST(mkntcmdline, testWut) {
char *argv[] = {"C:\\Users\\jart\\𝑟𝑒𝑑𝑏𝑒𝑎𝑛", "--strace", NULL};
EXPECT_NE(-1, mkntcmdline(cmdline, argv));
EXPECT_NE(-1, mkntcmdline(cmdline, argv, 32767));
EXPECT_STREQ(u"C:\\Users\\jart\\𝑟𝑒𝑑𝑏𝑒𝑎𝑛 --strace", cmdline);
}
@@ -95,5 +109,5 @@ BENCH(mkntcmdline, lotsOfArgs) {
for (int i = 0; i < 999; ++i) {
argv[i] = "hello there hello there";
}
EZBENCH2("mkntcmdline", donothing, unassert(!mkntcmdline(cmdline, argv)));
EZBENCH2("mkntcmdline", donothing, mkntcmdline(cmdline, argv, 32767));
}
+3 -3
View File
@@ -33,9 +33,9 @@
__static_yoink("zipos");
__static_yoink("libc/testlib/hyperion.txt");
__static_yoink("inflate");
__static_yoink("inflateInit2");
__static_yoink("inflateEnd");
__static_yoink("_Cz_inflate");
__static_yoink("_Cz_inflateInit2");
__static_yoink("_Cz_inflateEnd");
void *Worker(void *arg) {
int i, fd;
+2 -1
View File
@@ -68,7 +68,8 @@ o/$(MODE)/test/libc/sock/shutdown_test.runs \
o/$(MODE)/test/libc/sock/setsockopt_test.runs \
o/$(MODE)/test/libc/sock/sendfile_test.runs \
o/$(MODE)/test/libc/sock/poll_test.runs \
o/$(MODE)/test/libc/sock/pollfd_test.runs: \
o/$(MODE)/test/libc/sock/pollfd_test.runs \
o/$(MODE)/test/libc/sock/getpeername_test.runs: \
private .PLEDGE = stdio rpath wpath cpath fattr proc inet
o/$(MODE)/test/libc/sock/sendrecvmsg_test.runs: \
+154
View File
@@ -0,0 +1,154 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2024 Gavin Arthur Hayes │
│ │
│ 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/dce.h"
#include "libc/sock/sock.h"
#include "libc/sock/struct/sockaddr.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/consts/sock.h"
#include "libc/testlib/subprocess.h"
#include "libc/testlib/testlib.h"
TEST(getpeername, worksAfterAcceptingOnFork) {
// https://github.com/jart/cosmopolitan/issues/1174
if (IsWindows()) {
return;
}
char buf[16] = {0};
uint32_t addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(0x7f000001),
};
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
SPAWN(fork);
ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize));
struct sockaddr_storage out = {0};
uint32_t out_size = sizeof(out);
ASSERT_SYS(0, 0, getpeername(4, (struct sockaddr *)&out, &out_size));
EXPECT_GE(sizeof(struct sockaddr_in), out_size);
EXPECT_EQ(AF_INET, ((struct sockaddr_in *)&out)->sin_family);
EXPECT_EQ(htonl(0x7f000001), ((struct sockaddr_in *)&out)->sin_addr.s_addr);
ASSERT_SYS(0, 5, send(4, "hello", 5, 0));
PARENT();
ASSERT_SYS(0, 0, close(3));
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 5, read(3, buf, 16));
ASSERT_STREQ("hello", buf);
ASSERT_SYS(0, 0, close(3));
WAIT(exit, 0);
}
TEST(getpeername, worksAfterAcceptingOnParent) {
char buf[16] = {0};
uint32_t addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(0x7f000001),
};
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
SPAWN(fork);
ASSERT_SYS(0, 0, close(3));
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 5, read(3, buf, 16));
ASSERT_STREQ("hello", buf);
PARENT();
ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize));
struct sockaddr_storage out = {0};
uint32_t out_size = sizeof(out);
ASSERT_SYS(0, 0, getpeername(4, (struct sockaddr *)&out, &out_size));
EXPECT_GE(sizeof(struct sockaddr_in), out_size);
EXPECT_EQ(AF_INET, ((struct sockaddr_in *)&out)->sin_family);
EXPECT_EQ(htonl(0x7f000001), ((struct sockaddr_in *)&out)->sin_addr.s_addr);
ASSERT_SYS(0, 5, send(4, "hello", 5, 0));
ASSERT_SYS(0, 0, close(4));
ASSERT_SYS(0, 0, close(3));
WAIT(exit, 0);
}
TEST(getpeername, worksAfterConnectingOnFork) {
char buf[16] = {0};
uint32_t addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(0x7f000001),
};
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
ASSERT_SYS(0, 4, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
SPAWN(fork);
ASSERT_SYS(0, 0, close(3));
ASSERT_SYS(0, 0, connect(4, (struct sockaddr *)&addr, sizeof(addr)));
struct sockaddr_storage out = {0};
uint32_t out_size = sizeof(out);
ASSERT_SYS(0, 0, getpeername(4, (struct sockaddr *)&out, &out_size));
EXPECT_GE(sizeof(struct sockaddr_in), out_size);
EXPECT_EQ(AF_INET, ((struct sockaddr_in *)&out)->sin_family);
EXPECT_EQ(htonl(0x7f000001), ((struct sockaddr_in *)&out)->sin_addr.s_addr);
ASSERT_SYS(0, 5, send(4, "hello", 5, 0));
PARENT();
ASSERT_SYS(0, 0, close(4));
ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 5, read(4, buf, 16));
ASSERT_STREQ("hello", buf);
ASSERT_SYS(0, 0, close(4));
ASSERT_SYS(0, 0, close(3));
WAIT(exit, 0);
}
TEST(getpeername, worksAfterConnectingOnParent) {
char buf[16] = {0};
uint32_t addrsize = sizeof(struct sockaddr_in);
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(0x7f000001),
};
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
SPAWN(fork);
ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize));
ASSERT_SYS(0, 5, read(4, buf, 16));
ASSERT_STREQ("hello", buf);
PARENT();
ASSERT_SYS(0, 0, close(3));
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
struct sockaddr_storage out = {0};
uint32_t out_size = sizeof(out);
ASSERT_SYS(0, 0, getpeername(3, (struct sockaddr *)&out, &out_size));
EXPECT_GE(sizeof(struct sockaddr_in), out_size);
EXPECT_EQ(AF_INET, ((struct sockaddr_in *)&out)->sin_family);
EXPECT_EQ(htonl(0x7f000001), ((struct sockaddr_in *)&out)->sin_addr.s_addr);
ASSERT_SYS(0, 5, send(3, "hello", 5, 0));
ASSERT_SYS(0, 0, close(3));
WAIT(exit, 0);
}
-2
View File
@@ -152,8 +152,6 @@ __attribute__((__constructor__)) static void StdioPro(int argc, char *argv[]) {
}
TEST(socket, canBeUsedAsExecutedStdio) {
if (IsWindows())
return; // TODO(jart): What broke this?
char buf[16] = {0};
const char *prog;
uint32_t addrsize = sizeof(struct sockaddr_in);
+51 -37
View File
@@ -16,53 +16,67 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
/*
* This test was contributed by @ahgamut
* https://github.com/jart/cosmopolitan/issues/61#issuecomment-792214575
*/
void SetUpOnce(void) {
testlib_enable_tmp_setup_teardown();
char path[PATH_MAX];
void teardown(void) {
unlink(path);
}
int writefile(const char* filename) {
int stat = 0;
FILE* fp = fopen(filename, "w");
stat = fputs("cosmopolitan libc\n", fp);
fclose(fp);
return stat;
}
int readfile(const char* filename) {
int stat = 0;
char buf1[30];
char buf2[30];
FILE *fp1, *fp2;
fp1 = fopen(filename, "r");
if (!fp1) {
printf("failed to read %s in r\n", filename);
int setup(void) {
int fd;
const char* tmpdir;
if ((tmpdir = getenv("TMPDIR")))
strlcpy(path, tmpdir, sizeof(path));
else
strlcpy(path, "/tmp", sizeof(path));
strlcat(path, "/freopen_test.XXXXXX", sizeof(path));
if ((fd = mkstemp(path)) == -1)
return 1;
}
buf1[0] = fgetc(fp1);
buf1[1] = '\0';
fp2 = freopen(filename, "rb", fp1);
if (!fp2) {
printf("failed to read %s in rb\n", filename);
return 1;
}
stat = fread(buf2, sizeof(buf2[0]), 20, fp2);
ASSERT_EQ(18, stat);
buf2[stat] = '\0';
fclose(fp2);
ASSERT_STREQ("c", buf1);
ASSERT_STREQ("cosmopolitan libc\n", buf2);
if (write(fd, "cosmopolitan libc\n", 18) != 18)
return 2;
if (close(fd))
return 3;
return 0;
}
TEST(freopen, test) {
writefile("file.txt");
readfile("file.txt");
int test(void) {
FILE* fp;
char buf[20];
if (!(fp = fopen(path, "r")))
return 4;
if (fgetc(fp) != 'c')
return 5;
if (!(fp = freopen(path, "rb", fp)))
return 6;
if (fread(buf, 1, 20, fp) != 18)
return 7;
if (memcmp(buf, "cosmopolitan libc\n", 18))
return 8;
if (fclose(fp))
return 9;
return 0;
}
int main(int argc, char* argv[]) {
int rc;
if ((rc = setup())) {
perror(path);
teardown();
return rc;
}
rc = test();
teardown();
return rc;
}
+25 -1
View File
@@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/stdio/stdio.h"
#include "libc/str/blake2.h"
#include "libc/assert.h"
#include "libc/mem/mem.h"
@@ -26,6 +27,9 @@
#include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h"
__static_yoink("libc/testlib/blake2b256_tests.txt");
__static_yoink("zipos");
uint8_t *EZBLAKE2B256(const char *s, size_t n) {
static uint8_t digest[BLAKE2B256_DIGEST_LENGTH];
BLAKE2B256(s, n, digest);
@@ -63,7 +67,27 @@ TEST(BLAKE2B256Test, ABC) {
EXPECT_BINEQ(
"03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314",
HEXBLAKE2B256("00"));
/* TODO(jart): do rest */
}
TEST(BLAKE2B256Test, vectors) {
char *line = NULL;
size_t cap = 0;
ssize_t n;
FILE *f = fopen("/zip/libc/testlib/blake2b256_tests.txt", "r");
uint8_t *digest = 0;
while ((n = getline(&line, &cap, f)) != -1) {
if (n < 2 || line[0] == '#')
continue;
line[n - 1] = 0;
if (!strncmp(line, "IN:", 3)) {
digest = HEXBLAKE2B256(line + 4);
}
if (!strncmp(line, "HASH: ", 6)) {
EXPECT_BINEQ(line + 6, digest);
}
}
fclose(f);
free(line);
}
BENCH(blake2, bench) {
+3
View File
@@ -52,6 +52,9 @@ o/$(MODE)/test/posix/%.dbg: \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
o/$(MODE)/test/posix/fread3gb_test.runs: \
private QUOTA += -F5gb -M5gb
.PHONY: o/$(MODE)/test/posix
o/$(MODE)/test/posix: \
$(TEST_POSIX_BINS) \
+69
View File
@@ -0,0 +1,69 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#define SIZE ((size_t)2 * 1024 * 1024 * 1024 + 13)
char path[PATH_MAX];
void teardown(void) {
unlink(path);
}
int setup(void) {
int fd;
struct stat st;
const char *tmpdir;
if (!stat("/dev/shm", &st))
strlcpy(path, "/dev/shm", sizeof(path));
else if ((tmpdir = getenv("TMPDIR")))
strlcpy(path, tmpdir, sizeof(path));
else
strlcpy(path, "/tmp", sizeof(path));
strlcat(path, "/fread3gb.XXXXXX", sizeof(path));
if ((fd = mkstemp(path)) == -1)
return 1;
if (ftruncate(fd, SIZE))
return 2;
if (pwrite(fd, "a", 1, 0) != 1)
return 3;
if (pwrite(fd, "z", 1, SIZE - 1) != 1)
return 4;
if (close(fd))
return 5;
return 0;
}
int test(void) {
FILE *f;
char *buf;
size_t rc;
if (!(f = fopen(path, "r")))
return 6;
if (!(buf = malloc(SIZE)))
return 7;
if ((rc = fread(buf, SIZE, 1, f)) != 1)
return 8;
if (buf[0] != 'a')
return 9;
if (buf[SIZE - 1] != 'z')
return 10;
if (fclose(f))
return 11;
return 0;
}
int main(int argc, char *argv[]) {
int rc;
if ((rc = setup())) {
perror(path);
teardown();
return rc;
}
rc = test();
teardown();
return rc;
}
+1 -1
View File
@@ -111,7 +111,7 @@
#if (MORECORE_CONTIGUOUS || defined(WIN32))
#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */
#else /* MORECORE_CONTIGUOUS */
#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
#define DEFAULT_GRANULARITY ((size_t)256U * (size_t)1024U)
#endif /* MORECORE_CONTIGUOUS */
#endif /* DEFAULT_GRANULARITY */
#ifndef DEFAULT_TRIM_THRESHOLD
+2
View File
@@ -36,3 +36,5 @@ LOCAL MODIFICATIONS
Added Python-like printf modulus operator for strings.
Added Python-like printf multiply operator for strings.
Fixed a buffer overflow in os.tmpname
+4 -4
View File
@@ -133,12 +133,12 @@ __static_yoink("lua_notice");
#if defined(LUA_USE_POSIX) /* { */
#define LUA_TMPNAMBUFSIZE 32
#define LUA_TMPNAMBUFSIZE 128
#define lua_tmpnam(b,e) { \
strcpy(b, __get_tmpdir()); \
strcat(b, "lua_XXXXXX"); \
e = mkstemp(b); \
strlcpy(b, __get_tmpdir(), LUA_TMPNAMBUFSIZE); \
e = strlcat(b, "lua_XXXXXX", LUA_TMPNAMBUFSIZE) >= LUA_TMPNAMBUFSIZE; \
e = e ? -1 : mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }
+3 -3
View File
@@ -45,9 +45,9 @@ __static_yoink("musl_libc_notice");
// something as substantive as this library, then we shall assume the
// application is meaty enough to benefit from the performance of the
// chromium zlib library (costs ~40kb binary) versus just having puff
__static_yoink("inflateInit2");
__static_yoink("inflate");
__static_yoink("inflateEnd");
__static_yoink("_Cz_inflateInit2");
__static_yoink("_Cz_inflate");
__static_yoink("_Cz_inflateEnd");
#endif
static char *
+16 -16
View File
@@ -7,7 +7,7 @@ THIRD_PARTY_PYTHON_ARTIFACTS = \
THIRD_PARTY_PYTHON_STAGE1_A \
THIRD_PARTY_PYTHON_STAGE2_A \
THIRD_PARTY_PYTHON_PYTEST_A \
THIRD_PARTY_PYTHON_PYTHON \
THIRD_PARTY_PYTHON_PYTHON3 \
THIRD_PARTY_PYTHON_FREEZE
THIRD_PARTY_PYTHON_BINS = \
@@ -17,7 +17,7 @@ THIRD_PARTY_PYTHON_BINS = \
THIRD_PARTY_PYTHON_COMS = \
o/$(MODE)/third_party/python/Parser/asdl_c \
o/$(MODE)/third_party/python/pystone \
o/$(MODE)/third_party/python/python \
o/$(MODE)/third_party/python/python3 \
o/$(MODE)/third_party/python/freeze \
o/$(MODE)/third_party/python/pycomp \
o/$(MODE)/third_party/python/pyobj \
@@ -29,7 +29,7 @@ THIRD_PARTY_PYTHON_CHECKS = \
$(THIRD_PARTY_PYTHON_STAGE2_A).pkg \
$(THIRD_PARTY_PYTHON_PYTEST_A).pkg \
$(THIRD_PARTY_PYTHON_HDRS:%=o/$(MODE)/%.ok) \
o/$(MODE)/third_party/python/python.pkg \
o/$(MODE)/third_party/python/python3.pkg \
o/$(MODE)/third_party/python/freeze.pkg
# TODO: Deal with aarch64 under qemu not making execve() easy.
@@ -3980,12 +3980,12 @@ THIRD_PARTY_PYTHON_SRCS = \
################################################################################
# PYTHON
THIRD_PARTY_PYTHON_PYTHON_SRCS = third_party/python/python.c
THIRD_PARTY_PYTHON_PYTHON_OBJS = o/$(MODE)/third_party/python/python.o
THIRD_PARTY_PYTHON_PYTHON_COMS = o/$(MODE)/third_party/python/python
THIRD_PARTY_PYTHON_PYTHON_BINS = $(THIRD_PARTY_PYTHON_PYTHON_COMS) $(THIRD_PARTY_PYTHON_PYTHON_COMS:%=%.dbg)
THIRD_PARTY_PYTHON_PYTHON_DEPS = $(call uniq,$(foreach x,$(THIRD_PARTY_PYTHON_PYTHON_DIRECTDEPS),$($(x))))
THIRD_PARTY_PYTHON_PYTHON_DIRECTDEPS = \
THIRD_PARTY_PYTHON_PYTHON3_SRCS = third_party/python/python3.c
THIRD_PARTY_PYTHON_PYTHON3_OBJS = o/$(MODE)/third_party/python/python3.o
THIRD_PARTY_PYTHON_PYTHON3_COMS = o/$(MODE)/third_party/python/python3
THIRD_PARTY_PYTHON_PYTHON3_BINS = $(THIRD_PARTY_PYTHON_PYTHON3_COMS) $(THIRD_PARTY_PYTHON_PYTHON3_COMS:%=%.dbg)
THIRD_PARTY_PYTHON_PYTHON3_DEPS = $(call uniq,$(foreach x,$(THIRD_PARTY_PYTHON_PYTHON3_DIRECTDEPS),$($(x))))
THIRD_PARTY_PYTHON_PYTHON3_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
@@ -4005,14 +4005,14 @@ THIRD_PARTY_PYTHON_PYTHON_DIRECTDEPS = \
THIRD_PARTY_XED \
TOOL_ARGS
o/$(MODE)/third_party/python/python.pkg: \
$(THIRD_PARTY_PYTHON_PYTHON_OBJS) \
$(foreach x,$(THIRD_PARTY_PYTHON_PYTHON_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/third_party/python/python3.pkg: \
$(THIRD_PARTY_PYTHON_PYTHON3_OBJS) \
$(foreach x,$(THIRD_PARTY_PYTHON_PYTHON3_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/third_party/python/python.dbg: \
o/$(MODE)/third_party/python/python.pkg \
$(THIRD_PARTY_PYTHON_PYTHON_DEPS) \
$(THIRD_PARTY_PYTHON_PYTHON_OBJS) \
o/$(MODE)/third_party/python/python3.dbg: \
o/$(MODE)/third_party/python/python3.pkg \
$(THIRD_PARTY_PYTHON_PYTHON3_DEPS) \
$(THIRD_PARTY_PYTHON_PYTHON3_OBJS) \
$(CRT) \
$(APE_NO_MODIFY_SELF)
@$(APELINK)
File renamed without changes.
+1 -1
View File
@@ -31,7 +31,7 @@
#ifndef USE_ZLIB
ZCONST ulg near *get_crc_table OF((void));
#endif
#if (1 || defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY))
# ifdef IZ_CRC_BE_OPTIMIZ
# undef IZ_CRC_BE_OPTIMIZ
# endif
+5 -5
View File
@@ -72,7 +72,7 @@
#include "libc/nt/winsock.h"
#endif
unsigned crc32(unsigned crc, const unsigned char *buf, unsigned len);
unsigned _Cz_crc32(unsigned crc, const unsigned char *buf, unsigned len);
/*
* XXX start of zipfile.h
@@ -867,7 +867,7 @@ local void read_Unicode_Path_entry(pZipListEntry)
}
strcpy(iname, pZipListEntry->iname);
chksum = crc32(chksum, (uch *)(iname), strlen(iname));
chksum = _Cz_crc32(chksum, (uch *)(iname), strlen(iname));
free(iname);
@@ -972,7 +972,7 @@ local void read_Unicode_Path_local_entry(pZipListEntry)
}
strcpy(iname, pZipListEntry->iname);
chksum = crc32(chksum, (uch *)(iname), strlen(iname));
chksum = _Cz_crc32(chksum, (uch *)(iname), strlen(iname));
free(iname);
@@ -1558,7 +1558,7 @@ local int add_Unicode_Path_local_extra_field(pZEntry)
# define inameLocal (pZEntry->iname)
#endif
chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
chksum = _Cz_crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
#ifdef WIN32_OEM
free(inameLocal);
@@ -1685,7 +1685,7 @@ local int add_Unicode_Path_cen_extra_field(pZEntry)
# define inameLocal (pZEntry->iname)
#endif
chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
chksum = _Cz_crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
#ifdef WIN32_OEM
free(inameLocal);
-4
View File
@@ -13,7 +13,6 @@
#define z_const const
#if 0
#define Z_COSMO_PREFIX_SET
#define Bytef _Cz_Bytef
@@ -163,9 +162,6 @@
#define zlibCompileFlags _Cz_zlibCompileFlags
#define zlibVersion _Cz_zlibVersion
#pragma message "zconf is included, so zlibVersion should be renamed"
#endif
typedef unsigned char Byte;
typedef unsigned int uInt; /* 16 bits or more */
+1 -6
View File
@@ -15,7 +15,7 @@ $PROG (GCC) $GCC_VERSION
Copyright (c) 2024 Justine Alexandra Roberts Tunney
Cosmopolitan Libc and LLVM libcxx/compiler-rt are subject to non-GPL
notice licenses, e.g. ISC, MIT, etc. Your compiled programs must embed
our copyright notices. This toolchain is configured to do so default.
our copyright notices. This toolchain is configured to do so by default.
Cosmopolitan comes with absolutely NO WARRANTY of any kind.
For more information, see the Cosmopolitan LICENSE files.
Copyright (C) 2022 Free Software Foundation, Inc.
@@ -184,11 +184,6 @@ for x; do
# no support for position independent executables
# https://github.com/jart/cosmopolitan/issues/1126
continue
elif [ x"$x" = x"-Werror" ] || \
[ x"$x" = x"-pedantic-errors" ]; then
# this toolchain is intended for building other people's code
# elevating warnings into errors, should only be done by devs
continue
elif [ x"$x" = x"-static-libgcc" ] || \
[ x"$x" = x"-shared-libgcc" ]; then
# cosmopolitan.a always has llvm compiler runtime static code
-5
View File
@@ -165,11 +165,6 @@ for x; do
# information."
set -- "$@" -momit-leaf-frame-pointer -foptimize-sibling-calls
continue
elif [ x"$x" != x"${x#-Werror}" ] || \
[ x"$x" = x"-pedantic-errors" ]; then
# this toolchain is intended for building other people's code
# elevating warnings into errors, should only be done by devs
continue
elif [ x"$x" = x"-dumpversion" ]; then
echo $GCC_VERSION
exit 0