Delete LIBC_CALLS_HEFTY

- fork() no longer requires malloc()
- readdir() moved to LIBC_STDIO
- Custom APIs moved to LIBC_X
This commit is contained in:
Justine Tunney 2021-02-02 22:17:53 -08:00
parent c843243322
commit 23a14b537c
44 changed files with 95 additions and 168 deletions

View file

@ -116,7 +116,6 @@ include libc/zipos/zipos.mk # │
include third_party/gdtoa/gdtoa.mk # │ include third_party/gdtoa/gdtoa.mk # │
include libc/time/time.mk # │ include libc/time/time.mk # │
include libc/alg/alg.mk # │ include libc/alg/alg.mk # │
include libc/calls/hefty/hefty.mk # │
include libc/stdio/stdio.mk # │ include libc/stdio/stdio.mk # │
include third_party/f2c/f2c.mk # │ include third_party/f2c/f2c.mk # │
include third_party/blas/blas.mk # │ include third_party/blas/blas.mk # │
@ -252,7 +251,6 @@ COSMOPOLITAN_OBJECTS = \
APE_LIB \ APE_LIB \
THIRD_PARTY_MUSL \ THIRD_PARTY_MUSL \
LIBC_STDIO \ LIBC_STDIO \
LIBC_CALLS_HEFTY \
THIRD_PARTY_REGEX \ THIRD_PARTY_REGEX \
LIBC_ALG \ LIBC_ALG \
LIBC_MEM \ LIBC_MEM \

View file

@ -8,7 +8,7 @@
*/ */
#endif #endif
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/hefty/copyfile.h" #include "libc/calls/copyfile.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/conv.h" #include "libc/fmt/conv.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"

View file

@ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_LOG \ LIBC_LOG \

View file

@ -154,7 +154,6 @@ static bool resized_;
static size_t vtsize_; static size_t vtsize_;
static bool artifacts_; static bool artifacts_;
static long tyn_, txn_; static long tyn_, txn_;
static const char* ffplay_;
static struct Frame vf_[2]; static struct Frame vf_[2];
static struct Audio audio_; static struct Audio audio_;
static const char* inputfn_; static const char* inputfn_;
@ -1685,6 +1684,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) {
FILE* fp; FILE* fp;
int devnull; int devnull;
int pipefds[2]; int pipefds[2];
const char* ffplay;
inputfn_ = opt_tasfile; inputfn_ = opt_tasfile;
if (!(fp = fopen(romfile, "rb"))) { if (!(fp = fopen(romfile, "rb"))) {
@ -1701,7 +1701,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) {
// open speaker // open speaker
// todo: this needs plenty of work // todo: this needs plenty of work
if ((ffplay_ = commandvenv("FFPLAY", "ffplay"))) { if ((ffplay = commandvenv("FFPLAY", "ffplay"))) {
devnull = open("/dev/null", O_WRONLY | O_CLOEXEC); devnull = open("/dev/null", O_WRONLY | O_CLOEXEC);
pipe2(pipefds, O_CLOEXEC); pipe2(pipefds, O_CLOEXEC);
if (!(playpid_ = vfork())) { if (!(playpid_ = vfork())) {
@ -1713,7 +1713,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) {
dup2(pipefds[0], 0); dup2(pipefds[0], 0);
dup2(devnull, 1); dup2(devnull, 1);
dup2(devnull, 2); dup2(devnull, 2);
execv(ffplay_, (char* const*)args); execv(ffplay, (char* const*)args);
abort(); abort();
} }
close(pipefds[0]); close(pipefds[0]);

View file

@ -94,6 +94,4 @@ LIBC_CALLS_OBJS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_OBJS))
LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS)) LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS))
.PHONY: o/$(MODE)/libc/calls .PHONY: o/$(MODE)/libc/calls
o/$(MODE)/libc/calls: \ o/$(MODE)/libc/calls: $(LIBC_CALLS_CHECKS)
o/$(MODE)/libc/calls/hefty \
$(LIBC_CALLS_CHECKS)

View file

@ -16,7 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/calls/hefty/copyfile.h" #include "libc/calls/copyfile.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/dce.h" #include "libc/dce.h"

View file

@ -1,5 +1,5 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ #ifndef COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ #define COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_
#define COPYFILE_NOCLOBBER 1 #define COPYFILE_NOCLOBBER 1
#define COPYFILE_PRESERVE_OWNER 2 #define COPYFILE_PRESERVE_OWNER 2
@ -12,4 +12,4 @@ int copyfile(const char *, const char *, int) paramsnonnull();
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ */ #endif /* COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ */

View file

@ -47,7 +47,7 @@ textwindows int execve$nt(const char *program, char *const argv[],
close(i); close(i);
} }
} }
rc = ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo, rc = ntspawn(program, argv, envp, NULL, NULL, NULL, true, 0, NULL, &startinfo,
&procinfo); &procinfo);
if (rc == -1) return -1; if (rc == -1) return -1;
CloseHandle(procinfo.hThread); CloseHandle(procinfo.hThread);

View file

@ -16,10 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/str/str.h"
/** /**
* Returns value of environment variable, or NULL if not found. * Returns value of environment variable, or NULL if not found.

View file

@ -1,72 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
#
# SYNOPSIS
#
# Cosmopolitan System Call Compatibility Layer
#
# DESCRIPTION
#
# This subpackage exports functions traditionally understood as system
# calls that Cosmopolitan needs to wrap in a nontrivial way, requiring
# things like dynamic memory allocation.
PKGS += LIBC_CALLS_HEFTY
LIBC_CALLS_HEFTY_ARTIFACTS += LIBC_CALLS_HEFTY_A
LIBC_CALLS_HEFTY = $(LIBC_CALLS_HEFTY_A_DEPS) $(LIBC_CALLS_HEFTY_A)
LIBC_CALLS_HEFTY_A = o/$(MODE)/libc/calls/hefty/hefty.a
LIBC_CALLS_HEFTY_A_FILES := $(wildcard libc/calls/hefty/*)
LIBC_CALLS_HEFTY_A_HDRS = $(filter %.h,$(LIBC_CALLS_HEFTY_A_FILES))
LIBC_CALLS_HEFTY_A_SRCS_S = $(filter %.S,$(LIBC_CALLS_HEFTY_A_FILES))
LIBC_CALLS_HEFTY_A_SRCS_C = $(filter %.c,$(LIBC_CALLS_HEFTY_A_FILES))
LIBC_CALLS_HEFTY_A_SRCS = \
$(LIBC_CALLS_HEFTY_A_SRCS_S) \
$(LIBC_CALLS_HEFTY_A_SRCS_C)
LIBC_CALLS_HEFTY_A_OBJS = \
$(LIBC_CALLS_HEFTY_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(LIBC_CALLS_HEFTY_A_SRCS_C:%.c=o/$(MODE)/%.o)
LIBC_CALLS_HEFTY_A_CHECKS = \
$(LIBC_CALLS_HEFTY_A).pkg \
$(LIBC_CALLS_HEFTY_A_HDRS:%=o/$(MODE)/%.ok)
LIBC_CALLS_HEFTY_A_DIRECTDEPS = \
LIBC_ALG \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 \
LIBC_RUNTIME \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_SYSV_CALLS
LIBC_CALLS_HEFTY_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x))))
$(LIBC_CALLS_HEFTY_A): \
libc/calls/hefty/ \
$(LIBC_CALLS_HEFTY_A).pkg \
$(LIBC_CALLS_HEFTY_A_OBJS)
$(LIBC_CALLS_HEFTY_A).pkg: \
$(LIBC_CALLS_HEFTY_A_OBJS) \
$(foreach x,$(LIBC_CALLS_HEFTY_A_DIRECTDEPS),$($(x)_A).pkg)
LIBC_CALLS_HEFTY_LIBS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)))
LIBC_CALLS_HEFTY_SRCS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_SRCS))
LIBC_CALLS_HEFTY_HDRS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_HDRS))
LIBC_CALLS_HEFTY_BINS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_BINS))
LIBC_CALLS_HEFTY_CHECKS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_CHECKS))
LIBC_CALLS_HEFTY_OBJS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_OBJS))
LIBC_CALLS_HEFTY_TESTS = $(foreach x,$(LIBC_CALLS_HEFTY_ARTIFACTS),$($(x)_TESTS))
$(LIBC_CALLS_HEFTY_OBJS): $(BUILD_FILES) libc/calls/hefty/hefty.mk
.PHONY: o/$(MODE)/libc/calls/hefty
o/$(MODE)/libc/calls/hefty: $(LIBC_CALLS_HEFTY_CHECKS)

View file

@ -25,6 +25,7 @@
/** /**
* Controls settings on device. * Controls settings on device.
* @vforksafe
*/ */
int(ioctl)(int fd, uint64_t request, void *memory) { int(ioctl)(int fd, uint64_t request, void *memory) {
__IOCTL_DISPATCH(EQUAL, fd, request, memory); __IOCTL_DISPATCH(EQUAL, fd, request, memory);

View file

@ -51,18 +51,23 @@ static void SortStrings(char **a, size_t n) {
* *
* This is designed to meet the requirements of CreateProcess(). * This is designed to meet the requirements of CreateProcess().
* *
* @param envvars receives sorted double-NUL terminated string list
* @param envp is an a NULL-terminated array of UTF-8 strings * @param envp is an a NULL-terminated array of UTF-8 strings
* @return freshly allocated lpEnvironment or NULL w/ errno * @param extravar is a VAR=val string we consider part of envp or NULL
* @return 0 on success, or -1 w/ errno
* @error E2BIG if total number of shorts exceeded ARG_MAX (0x8000)
*/ */
textwindows int mkntenvblock(char16_t envvars[ARG_MAX], char *const envp[]) { textwindows int mkntenvblock(char16_t envvars[ARG_MAX], char *const envp[],
const char *extravar) {
axdx_t rc; axdx_t rc;
uint64_t w; uint64_t w;
char **vars; char **vars;
wint_t x, y; wint_t x, y;
size_t i, j, k, n, m; size_t i, j, k, n, m;
for (n = 0; envp[n];) n++; for (n = 0; envp[n];) n++;
vars = alloca(n * sizeof(char *)); vars = alloca((n + 1) * sizeof(char *));
memcpy(vars, envp, n * sizeof(char *)); memcpy(vars, envp, n * sizeof(char *));
if (extravar) vars[n++] = extravar;
SortStrings(vars, n); SortStrings(vars, n);
for (k = i = 0; i < n; ++i) { for (k = i = 0; i < n; ++i) {
j = 0; j = 0;

View file

@ -48,6 +48,7 @@ struct SpawnBlock {
* don't need to be passed in sorted order; however, this function * don't need to be passed in sorted order; however, this function
* goes faster the closer they are to sorted * goes faster the closer they are to sorted
* @param envp[m-1] is NULL * @param envp[m-1] is NULL
* @param extravar is added to envp to avoid setenv() in caller
* @param bInheritHandles means handles already marked inheritable will * @param bInheritHandles means handles already marked inheritable will
* be inherited; which, assuming the System V wrapper functions are * be inherited; which, assuming the System V wrapper functions are
* being used, should mean (1) all files and sockets that weren't * being used, should mean (1) all files and sockets that weren't
@ -59,7 +60,7 @@ struct SpawnBlock {
*/ */
textwindows int ntspawn( textwindows int ntspawn(
const char *prog, char *const argv[], char *const envp[], const char *prog, char *const argv[], char *const envp[],
struct NtSecurityAttributes *opt_lpProcessAttributes, const char *extravar, struct NtSecurityAttributes *opt_lpProcessAttributes,
struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles, struct NtSecurityAttributes *opt_lpThreadAttributes, bool32 bInheritHandles,
uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory, uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory,
const struct NtStartupInfo *lpStartupInfo, const struct NtStartupInfo *lpStartupInfo,
@ -81,7 +82,7 @@ textwindows int ntspawn(
MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0, MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0,
blocksize, NULL, kNtNumaNoPreferredNode))) { blocksize, NULL, kNtNumaNoPreferredNode))) {
if (mkntcmdline(block->cmdline, prog, argv) != -1 && if (mkntcmdline(block->cmdline, prog, argv) != -1 &&
mkntenvblock(block->envvars, envp) != -1) { mkntenvblock(block->envvars, envp, extravar) != -1) {
if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes, if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes,
opt_lpThreadAttributes, bInheritHandles, opt_lpThreadAttributes, bInheritHandles,
dwCreationFlags | kNtCreateUnicodeEnvironment, dwCreationFlags | kNtCreateUnicodeEnvironment,

View file

@ -1,5 +1,5 @@
#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ #ifndef COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_
#define COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ #define COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_
#include "libc/nt/struct/processinformation.h" #include "libc/nt/struct/processinformation.h"
#include "libc/nt/struct/securityattributes.h" #include "libc/nt/struct/securityattributes.h"
#include "libc/nt/struct/startupinfo.h" #include "libc/nt/struct/startupinfo.h"
@ -7,12 +7,12 @@
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
int mkntcmdline(char16_t[ARG_MAX], const char *, char *const[]) hidden; int mkntcmdline(char16_t[ARG_MAX], const char *, char *const[]) hidden;
int mkntenvblock(char16_t[ARG_MAX], char *const[]) hidden; int mkntenvblock(char16_t[ARG_MAX], char *const[], const char *) hidden;
int ntspawn(const char *, char *const[], char *const[], int ntspawn(const char *, char *const[], char *const[], const char *,
struct NtSecurityAttributes *, struct NtSecurityAttributes *, struct NtSecurityAttributes *, struct NtSecurityAttributes *,
bool32, uint32_t, const char16_t *, const struct NtStartupInfo *, bool32, uint32_t, const char16_t *, const struct NtStartupInfo *,
struct NtProcessInformation *) hidden; struct NtProcessInformation *) hidden;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ */ #endif /* COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ */

View file

@ -37,6 +37,7 @@
* ignored if O_CREAT or O_TMPFILE weren't passed * ignored if O_CREAT or O_TMPFILE weren't passed
* @return number needing close(), or -1 w/ errno * @return number needing close(), or -1 w/ errno
* @asyncsignalsafe * @asyncsignalsafe
* @vforksafe
*/ */
nodiscard int openat(int dirfd, const char *file, int flags, ...) { nodiscard int openat(int dirfd, const char *file, int flags, ...) {
va_list va; va_list va;
@ -47,11 +48,9 @@ nodiscard int openat(int dirfd, const char *file, int flags, ...) {
va_end(va); va_end(va);
if (!file) return efault(); if (!file) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) { if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) {
if (dirfd == AT_FDCWD) { if (__vforked) return einval();
return weaken(__zipos_open)(&zipname, flags, mode); if (dirfd != AT_FDCWD) return einval();
} else { return weaken(__zipos_open)(&zipname, flags, mode);
return eopnotsupp(); /* TODO */
}
} else if (!IsWindows()) { } else if (!IsWindows()) {
return openat$sysv(dirfd, file, flags, mode); return openat$sysv(dirfd, file, flags, mode);
} else { } else {

View file

@ -118,6 +118,7 @@ static void sigaction$native2cosmo(union metasigaction *sa) {
* *
* @see xsigaction() for a much better api * @see xsigaction() for a much better api
* @asyncsignalsafe * @asyncsignalsafe
* @vforksafe
*/ */
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
_Static_assert(sizeof(struct sigaction) > sizeof(struct sigaction$linux) && _Static_assert(sizeof(struct sigaction) > sizeof(struct sigaction$linux) &&

View file

@ -48,7 +48,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
struct Garbages *garbage; struct Garbages *garbage;
sigset_t chldmask, savemask; sigset_t chldmask, savemask;
const struct StackFrame *frame; const struct StackFrame *frame;
struct sigaction ignore, saveint, savequit;
const char *debugbin, *p1, *p2, *p3, *addr2line; const char *debugbin, *p1, *p2, *p3, *addr2line;
char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames]; char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames];
if (IsOpenbsd()) return -1; if (IsOpenbsd()) return -1;
@ -77,18 +76,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
j += uint64toarray_radix16(addr - 1, buf + j) + 1; j += uint64toarray_radix16(addr - 1, buf + j) + 1;
} }
argv[i++] = NULL; argv[i++] = NULL;
ignore.sa_flags = 0;
ignore.sa_handler = SIG_IGN;
sigemptyset(&ignore.sa_mask);
sigaction(SIGINT, &ignore, &saveint);
sigaction(SIGQUIT, &ignore, &savequit);
sigemptyset(&chldmask); sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD); sigaddset(&chldmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &chldmask, &savemask); sigprocmask(SIG_BLOCK, &chldmask, &savemask);
pipe(pipefds); pipe(pipefds);
if (!(pid = vfork())) { if (!(pid = vfork())) {
sigaction(SIGINT, &saveint, NULL);
sigaction(SIGQUIT, &savequit, NULL);
sigprocmask(SIG_SETMASK, &savemask, NULL); sigprocmask(SIG_SETMASK, &savemask, NULL);
dup2(pipefds[1], 1); dup2(pipefds[1], 1);
close(pipefds[0]); close(pipefds[0]);
@ -124,8 +116,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
if (errno == EINTR) continue; if (errno == EINTR) continue;
return -1; return -1;
} }
sigaction(SIGINT, &saveint, NULL);
sigaction(SIGQUIT, &savequit, NULL);
sigprocmask(SIG_SETMASK, &savemask, NULL); sigprocmask(SIG_SETMASK, &savemask, NULL);
if (WIFEXITED(ws) && !WEXITSTATUS(ws)) { if (WIFEXITED(ws) && !WEXITSTATUS(ws)) {
return 0; return 0;

View file

@ -25,19 +25,30 @@
/** /**
* Finds full executable path in overridable way. * Finds full executable path in overridable way.
*
* This is a higher level version of the commandv() function. Programs
* that spawn subprocesses can use this function to determine the path
* at startup.
*
* @param var is environment variable which may be used to override
* PATH search, and it can force a NULL result if it's empty
* @param cmd is name of program, which is returned asap if it's an
* absolute path
* @return pointer to exe path string, or NULL if it couldn't be found
* or the environment variable was empty; noting that the caller
* should copy this string before saving it
*/ */
nodiscard char *commandvenv(const char *var, const char *cmd) { const char *commandvenv(const char *var, const char *cmd) {
const char *exepath; const char *exepath;
char pathbuf[PATH_MAX]; static char pathbuf[PATH_MAX];
if (*cmd == '/' || *cmd == '\\') return cmd;
if ((exepath = getenv(var))) { if ((exepath = getenv(var))) {
if (!isempty(exepath) && access(exepath, X_OK) != -1) { if (isempty(exepath)) return NULL;
return strdup(exepath); if (access(exepath, X_OK) != -1) {
return exepath;
} else { } else {
return NULL; return NULL;
} }
} else if ((exepath = commandv(cmd, pathbuf))) {
return strdup(exepath);
} else {
return NULL;
} }
return commandv(cmd, pathbuf);
} }

View file

@ -40,7 +40,7 @@ void memsummary(int); /* light version of same thing */
uint16_t getttycols(uint16_t); uint16_t getttycols(uint16_t);
int getttysize(int, struct winsize *) paramsnonnull(); int getttysize(int, struct winsize *) paramsnonnull();
bool IsTerminalInarticulate(void) nosideeffect; bool IsTerminalInarticulate(void) nosideeffect;
char *commandvenv(const char *, const char *) nodiscard; const char *commandvenv(const char *, const char *);
const char *GetAddr2linePath(void); const char *GetAddr2linePath(void);
const char *GetGdbPath(void); const char *GetGdbPath(void);

View file

@ -28,7 +28,6 @@ LIBC_LOG_A_CHECKS = \
LIBC_LOG_A_DIRECTDEPS = \ LIBC_LOG_A_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_ELF \ LIBC_ELF \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \

View file

@ -46,13 +46,14 @@
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
static textwindows int64_t ParseInt(char16_t **p) { static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) {
uint64_t x = 0; *x = 0;
while ('0' <= **p && **p <= '9') { while (*p == ' ') p++;
x *= 10; while ('0' <= *p && *p <= '9') {
x += *(*p)++ - '0'; *x *= 10;
*x += *p++ - '0';
} }
return x; return p;
} }
static noinline textwindows void ForkIo(int64_t h, void *buf, size_t n, static noinline textwindows void ForkIo(int64_t h, void *buf, size_t n,
@ -74,32 +75,28 @@ static noinline textwindows void ReadAll(int64_t h, void *buf, size_t n) {
} }
textwindows void WinMainForked(void) { textwindows void WinMainForked(void) {
int64_t h;
void *addr; void *addr;
jmp_buf jb; jmp_buf jb;
char16_t *p;
uint64_t size; uint64_t size;
uint32_t i, varlen; uint32_t i, varlen;
struct DirectMap dm; struct DirectMap dm;
int64_t reader, writer;
char16_t var[21 + 1 + 21 + 1]; char16_t var[21 + 1 + 21 + 1];
varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var)); varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var));
if (!varlen) return;
if (varlen >= ARRAYLEN(var)) ExitProcess(123);
SetEnvironmentVariable(u"_FORK", NULL); SetEnvironmentVariable(u"_FORK", NULL);
if (!varlen || varlen >= ARRAYLEN(var)) return; ParseInt(ParseInt(var, &reader), &writer);
p = var; ReadAll(reader, jb, sizeof(jb));
h = ParseInt(&p); ReadAll(reader, &_mmi.i, sizeof(_mmi.i));
if (*p++ == ' ') CloseHandle(ParseInt(&p));
ReadAll(h, jb, sizeof(jb));
ReadAll(h, &_mmi.i, sizeof(_mmi.i));
for (i = 0; i < _mmi.i; ++i) { for (i = 0; i < _mmi.i; ++i) {
ReadAll(h, &_mmi.p[i], sizeof(_mmi.p[i])); ReadAll(reader, &_mmi.p[i], sizeof(_mmi.p[i]));
addr = (void *)((uint64_t)_mmi.p[i].x << 16); addr = (void *)((uint64_t)_mmi.p[i].x << 16);
size = ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE; size = ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE;
if (_mmi.p[i].flags & MAP_PRIVATE) { if (_mmi.p[i].flags & MAP_PRIVATE) {
CloseHandle(_mmi.p[i].h); CloseHandle(_mmi.p[i].h);
_mmi.p[i].h = _mmi.p[i].h = __mmap$nt(addr, size, _mmi.p[i].prot, -1, 0).maphandle;
__mmap$nt(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, -1, 0) ReadAll(reader, addr, size);
.maphandle;
ReadAll(h, addr, size);
} else { } else {
MapViewOfFileExNuma( MapViewOfFileExNuma(
_mmi.p[i].h, _mmi.p[i].h,
@ -109,9 +106,9 @@ textwindows void WinMainForked(void) {
0, 0, size, addr, kNtNumaNoPreferredNode); 0, 0, size, addr, kNtNumaNoPreferredNode);
} }
} }
ReadAll(h, _edata, _end - _edata); ReadAll(reader, _edata, _end - _edata);
CloseHandle(h); CloseHandle(reader);
unsetenv("_FORK"); CloseHandle(writer);
if (weaken(__wincrash$nt)) { if (weaken(__wincrash$nt)) {
AddVectoredExceptionHandler(1, (void *)weaken(__wincrash$nt)); AddVectoredExceptionHandler(1, (void *)weaken(__wincrash$nt));
} }
@ -123,17 +120,16 @@ textwindows int fork$nt(void) {
int i, rc, pid; int i, rc, pid;
char exe[PATH_MAX]; char exe[PATH_MAX];
int64_t reader, writer; int64_t reader, writer;
char *p, buf[21 + 1 + 21 + 1]; char *p, forkvar[6 + 21 + 1 + 21 + 1];
struct NtStartupInfo startinfo; struct NtStartupInfo startinfo;
struct NtProcessInformation procinfo; struct NtProcessInformation procinfo;
if ((pid = __getemptyfd()) == -1) return -1; if ((pid = __getemptyfd()) == -1) return -1;
if (!setjmp(jb)) { if (!setjmp(jb)) {
if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) { if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) {
p = buf; p = stpcpy(forkvar, "_FORK=");
p += uint64toarray_radix10(reader, p); p += uint64toarray_radix10(reader, p);
*p++ = ' '; *p++ = ' ';
p += uint64toarray_radix10(writer, p); p += uint64toarray_radix10(writer, p);
setenv("_FORK", buf, true);
memset(&startinfo, 0, sizeof(startinfo)); memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(struct NtStartupInfo); startinfo.cb = sizeof(struct NtStartupInfo);
startinfo.dwFlags = kNtStartfUsestdhandles; startinfo.dwFlags = kNtStartfUsestdhandles;
@ -141,8 +137,8 @@ textwindows int fork$nt(void) {
startinfo.hStdOutput = g_fds.p[1].handle; startinfo.hStdOutput = g_fds.p[1].handle;
startinfo.hStdError = g_fds.p[2].handle; startinfo.hStdError = g_fds.p[2].handle;
GetModuleFileNameA(0, exe, ARRAYLEN(exe)); GetModuleFileNameA(0, exe, ARRAYLEN(exe));
if (ntspawn(exe, g_argv, environ, &kNtIsInheritable, NULL, true, 0, NULL, if (ntspawn(exe, g_argv, environ, forkvar, &kNtIsInheritable, NULL, true,
&startinfo, &procinfo) != -1) { 0, NULL, &startinfo, &procinfo) != -1) {
CloseHandle(reader); CloseHandle(reader);
CloseHandle(procinfo.hThread); CloseHandle(procinfo.hThread);
if (weaken(__sighandrvas) && if (weaken(__sighandrvas) &&
@ -167,7 +163,6 @@ textwindows int fork$nt(void) {
} else { } else {
rc = -1; rc = -1;
} }
unsetenv("_FORK");
rc = pid; rc = pid;
} else { } else {
rc = __winerr(); rc = __winerr();

View file

@ -27,7 +27,6 @@ LIBC_STDIO_A_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_MEM \ LIBC_MEM \

View file

@ -34,7 +34,6 @@ LIBC_X_A_CHECKS = \
LIBC_X_A_DIRECTDEPS = \ LIBC_X_A_DIRECTDEPS = \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_MEM \ LIBC_MEM \

View file

@ -24,13 +24,13 @@ char16_t envvars[ARG_MAX];
TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) { TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) {
char *envp[] = {NULL}; char *envp[] = {NULL};
ASSERT_NE(-1, mkntenvblock(envvars, envp)); ASSERT_NE(-1, mkntenvblock(envvars, envp, NULL));
ASSERT_BINEQ(u"  ", envvars); ASSERT_BINEQ(u"  ", envvars);
} }
TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL}; char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
ASSERT_NE(-1, mkntenvblock(envvars, envp)); ASSERT_NE(-1, mkntenvblock(envvars, envp, NULL));
ASSERT_BINEQ(u"c = d   " ASSERT_BINEQ(u"c = d   "
u"h d u c = d   " u"h d u c = d   "
u"u = b   " u"u = b   "
@ -39,3 +39,16 @@ TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) {
u"  ", u"  ",
envvars); envvars);
} }
TEST(mkntenvblock, extraVar_getsAdded) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
ASSERT_NE(-1, mkntenvblock(envvars, envp, "a=a"));
ASSERT_BINEQ(u"a = a   "
u"c = d   "
u"h d u c = d   "
u"u = b   "
u"u h = d   "
u"Θù= ^ù  "
u"  ",
envvars);
}

View file

@ -4,8 +4,7 @@
PKGS += TEST_LIBC_CALLS PKGS += TEST_LIBC_CALLS
TEST_LIBC_CALLS_SRCS := \ TEST_LIBC_CALLS_SRCS := \
$(wildcard test/libc/calls/*.c) \ $(wildcard test/libc/calls/*.c)
$(wildcard test/libc/calls/hefty/*.c)
TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS)) TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS))
TEST_LIBC_CALLS_OBJS = \ TEST_LIBC_CALLS_OBJS = \
@ -26,13 +25,13 @@ TEST_LIBC_CALLS_CHECKS = \
TEST_LIBC_CALLS_DIRECTDEPS = \ TEST_LIBC_CALLS_DIRECTDEPS = \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_LOG \ LIBC_LOG \
LIBC_MEM \ LIBC_MEM \
LIBC_NEXGEN32E \ LIBC_NEXGEN32E \
LIBC_RAND \ LIBC_RAND \
LIBC_STDIO \
LIBC_RUNTIME \ LIBC_RUNTIME \
LIBC_STR \ LIBC_STR \
LIBC_STUBS \ LIBC_STUBS \

View file

@ -29,6 +29,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_MEM \ LIBC_MEM \
LIBC_NEXGEN32E \ LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \ LIBC_RUNTIME \
LIBC_STDIO \ LIBC_STDIO \
LIBC_STR \ LIBC_STR \

View file

@ -51,7 +51,6 @@ THIRD_PARTY_CHIBICC_A_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_LOG \ LIBC_LOG \

View file

@ -19,7 +19,6 @@ THIRD_PARTY_MUSL_A_OBJS = \
THIRD_PARTY_MUSL_A_DIRECTDEPS = \ THIRD_PARTY_MUSL_A_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_INTRIN \ LIBC_INTRIN \
LIBC_MEM \ LIBC_MEM \
LIBC_NEXGEN32E \ LIBC_NEXGEN32E \

View file

@ -28,7 +28,6 @@ TOOL_BUILD_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_DNS \ LIBC_DNS \
LIBC_ELF \ LIBC_ELF \
LIBC_FMT \ LIBC_FMT \

View file

@ -27,7 +27,6 @@ TOOL_BUILD_LIB_A_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_ELF \ LIBC_ELF \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \

View file

@ -22,7 +22,6 @@ TOOL_NET_DIRECTDEPS = \
LIBC_ALG \ LIBC_ALG \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_DNS \ LIBC_DNS \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \

View file

@ -1473,8 +1473,8 @@ int main(int argc, char *argv[]) {
if (!tuned_) PickDefaults(); if (!tuned_) PickDefaults();
if (optind == argc) PrintUsage(EX_USAGE, stderr); if (optind == argc) PrintUsage(EX_USAGE, stderr);
patharg_ = argv[optind]; patharg_ = argv[optind];
sox_ = commandvenv("SOX", "sox"); sox_ = strdup(commandvenv("SOX", "sox"));
ffplay_ = commandvenv("FFPLAY", "ffplay"); ffplay_ = strdup(commandvenv("FFPLAY", "ffplay"));
infd_ = STDIN_FILENO; infd_ = STDIN_FILENO;
outfd_ = STDOUT_FILENO; outfd_ = STDOUT_FILENO;
if (!setjmp(jb_)) { if (!setjmp(jb_)) {

View file

@ -22,7 +22,6 @@ TOOL_VIZ_DIRECTDEPS = \
DSP_TTY \ DSP_TTY \
LIBC_BITS \ LIBC_BITS \
LIBC_CALLS \ LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_DNS \ LIBC_DNS \
LIBC_FMT \ LIBC_FMT \
LIBC_INTRIN \ LIBC_INTRIN \