From 23a14b537c4114bca5e6172608f849a231bdda74 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 2 Feb 2021 22:17:53 -0800 Subject: [PATCH] Delete LIBC_CALLS_HEFTY - fork() no longer requires malloc() - readdir() moved to LIBC_STDIO - Custom APIs moved to LIBC_X --- Makefile | 2 - examples/cp.c | 2 +- examples/examples.mk | 1 - examples/nesemu1.cc | 6 +- libc/calls/calls.mk | 4 +- libc/calls/{hefty => }/copyfile.c | 2 +- libc/calls/{hefty => }/copyfile.h | 6 +- libc/calls/execve-nt.c | 2 +- libc/calls/getenv.c | 3 - libc/calls/hefty/hefty.mk | 72 ------------------- libc/calls/ioctl.c | 1 + libc/calls/mkntenvblock.c | 11 ++- libc/calls/ntspawn.c | 5 +- libc/calls/ntspawn.h | 10 +-- libc/calls/openat.c | 9 ++- libc/calls/sigaction.c | 1 + libc/calls/{hefty => }/ttyname.c | 0 libc/calls/{hefty => }/ttyname_r.c | 0 libc/log/backtrace2.c | 10 --- libc/log/commandvenv.c | 27 ++++--- libc/log/log.h | 2 +- libc/log/log.mk | 1 - libc/{calls/hefty => runtime}/fork-nt.c | 51 ++++++------- libc/{calls/hefty => runtime}/fork.c | 0 libc/{calls/hefty => runtime}/vfork.S | 0 libc/{calls/hefty => stdio}/dirstream.c | 0 .../hefty => stdio}/get_current_dir_name.c | 0 libc/stdio/stdio.mk | 1 - libc/{calls/hefty => x}/filecmp.c | 0 libc/{calls/hefty => x}/replaceuser.c | 0 libc/x/x.mk | 1 - test/libc/calls/{hefty => }/fork_test.c | 0 test/libc/calls/mkntenvblock_test.c | 17 ++++- test/libc/calls/test.mk | 5 +- test/libc/calls/{hefty => }/vfork_test.c | 0 .../{calls/hefty => stdio}/dirstream_test.c | 0 test/libc/stdio/test.mk | 1 + third_party/chibicc/chibicc.mk | 1 - third_party/musl/musl.mk | 1 - tool/build/build.mk | 1 - tool/build/lib/buildlib.mk | 1 - tool/net/net.mk | 1 - tool/viz/printvideo.c | 4 +- tool/viz/viz.mk | 1 - 44 files changed, 95 insertions(+), 168 deletions(-) rename libc/calls/{hefty => }/copyfile.c (99%) rename libc/calls/{hefty => }/copyfile.h (66%) delete mode 100644 libc/calls/hefty/hefty.mk rename libc/calls/{hefty => }/ttyname.c (100%) rename libc/calls/{hefty => }/ttyname_r.c (100%) rename libc/{calls/hefty => runtime}/fork-nt.c (86%) rename libc/{calls/hefty => runtime}/fork.c (100%) rename libc/{calls/hefty => runtime}/vfork.S (100%) rename libc/{calls/hefty => stdio}/dirstream.c (100%) rename libc/{calls/hefty => stdio}/get_current_dir_name.c (100%) rename libc/{calls/hefty => x}/filecmp.c (100%) rename libc/{calls/hefty => x}/replaceuser.c (100%) rename test/libc/calls/{hefty => }/fork_test.c (100%) rename test/libc/calls/{hefty => }/vfork_test.c (100%) rename test/libc/{calls/hefty => stdio}/dirstream_test.c (100%) diff --git a/Makefile b/Makefile index 03ed5172d..37cf9490d 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,6 @@ include libc/zipos/zipos.mk # │ include third_party/gdtoa/gdtoa.mk # │ include libc/time/time.mk # │ include libc/alg/alg.mk # │ -include libc/calls/hefty/hefty.mk # │ include libc/stdio/stdio.mk # │ include third_party/f2c/f2c.mk # │ include third_party/blas/blas.mk # │ @@ -252,7 +251,6 @@ COSMOPOLITAN_OBJECTS = \ APE_LIB \ THIRD_PARTY_MUSL \ LIBC_STDIO \ - LIBC_CALLS_HEFTY \ THIRD_PARTY_REGEX \ LIBC_ALG \ LIBC_MEM \ diff --git a/examples/cp.c b/examples/cp.c index 0a6d558f1..0df70114a 100644 --- a/examples/cp.c +++ b/examples/cp.c @@ -8,7 +8,7 @@ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/calls.h" -#include "libc/calls/hefty/copyfile.h" +#include "libc/calls/copyfile.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" diff --git a/examples/examples.mk b/examples/examples.mk index 3b96bb137..5c8fda62a 100644 --- a/examples/examples.mk +++ b/examples/examples.mk @@ -44,7 +44,6 @@ EXAMPLES_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_FMT \ LIBC_INTRIN \ LIBC_LOG \ diff --git a/examples/nesemu1.cc b/examples/nesemu1.cc index 6cc6a69fb..b5e5664b5 100644 --- a/examples/nesemu1.cc +++ b/examples/nesemu1.cc @@ -154,7 +154,6 @@ static bool resized_; static size_t vtsize_; static bool artifacts_; static long tyn_, txn_; -static const char* ffplay_; static struct Frame vf_[2]; static struct Audio audio_; static const char* inputfn_; @@ -1685,6 +1684,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { FILE* fp; int devnull; int pipefds[2]; + const char* ffplay; inputfn_ = opt_tasfile; if (!(fp = fopen(romfile, "rb"))) { @@ -1701,7 +1701,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { // open speaker // todo: this needs plenty of work - if ((ffplay_ = commandvenv("FFPLAY", "ffplay"))) { + if ((ffplay = commandvenv("FFPLAY", "ffplay"))) { devnull = open("/dev/null", O_WRONLY | O_CLOEXEC); pipe2(pipefds, O_CLOEXEC); if (!(playpid_ = vfork())) { @@ -1713,7 +1713,7 @@ int PlayGame(const char* romfile, const char* opt_tasfile) { dup2(pipefds[0], 0); dup2(devnull, 1); dup2(devnull, 2); - execv(ffplay_, (char* const*)args); + execv(ffplay, (char* const*)args); abort(); } close(pipefds[0]); diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index c7f103d63..ec5993a26 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -94,6 +94,4 @@ LIBC_CALLS_OBJS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_OBJS)) LIBC_CALLS_TESTS = $(foreach x,$(LIBC_CALLS_ARTIFACTS),$($(x)_TESTS)) .PHONY: o/$(MODE)/libc/calls -o/$(MODE)/libc/calls: \ - o/$(MODE)/libc/calls/hefty \ - $(LIBC_CALLS_CHECKS) +o/$(MODE)/libc/calls: $(LIBC_CALLS_CHECKS) diff --git a/libc/calls/hefty/copyfile.c b/libc/calls/copyfile.c similarity index 99% rename from libc/calls/hefty/copyfile.c rename to libc/calls/copyfile.c index 47fc77dd4..d32e1801a 100644 --- a/libc/calls/hefty/copyfile.c +++ b/libc/calls/copyfile.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/hefty/copyfile.h" +#include "libc/calls/copyfile.h" #include "libc/calls/internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" diff --git a/libc/calls/hefty/copyfile.h b/libc/calls/copyfile.h similarity index 66% rename from libc/calls/hefty/copyfile.h rename to libc/calls/copyfile.h index 0f0c78ed6..f9ba2f877 100644 --- a/libc/calls/hefty/copyfile.h +++ b/libc/calls/copyfile.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ -#define COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ +#ifndef COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ +#define COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ #define COPYFILE_NOCLOBBER 1 #define COPYFILE_PRESERVE_OWNER 2 @@ -12,4 +12,4 @@ int copyfile(const char *, const char *, int) paramsnonnull(); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_COPYFILE_H_ */ +#endif /* COSMOPOLITAN_LIBC_CALLS_COPYFILE_H_ */ diff --git a/libc/calls/execve-nt.c b/libc/calls/execve-nt.c index 49ff0296f..c6c5a476e 100644 --- a/libc/calls/execve-nt.c +++ b/libc/calls/execve-nt.c @@ -47,7 +47,7 @@ textwindows int execve$nt(const char *program, char *const argv[], 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); if (rc == -1) return -1; CloseHandle(procinfo.hThread); diff --git a/libc/calls/getenv.c b/libc/calls/getenv.c index a6ea91c28..cff58f1e9 100644 --- a/libc/calls/getenv.c +++ b/libc/calls/getenv.c @@ -16,10 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/bits/bits.h" -#include "libc/bits/safemacros.h" #include "libc/runtime/runtime.h" -#include "libc/str/str.h" /** * Returns value of environment variable, or NULL if not found. diff --git a/libc/calls/hefty/hefty.mk b/libc/calls/hefty/hefty.mk deleted file mode 100644 index 36914e522..000000000 --- a/libc/calls/hefty/hefty.mk +++ /dev/null @@ -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) diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c index 1aac73136..4b3e5f864 100644 --- a/libc/calls/ioctl.c +++ b/libc/calls/ioctl.c @@ -25,6 +25,7 @@ /** * Controls settings on device. + * @vforksafe */ int(ioctl)(int fd, uint64_t request, void *memory) { __IOCTL_DISPATCH(EQUAL, fd, request, memory); diff --git a/libc/calls/mkntenvblock.c b/libc/calls/mkntenvblock.c index 0ec52f5e1..beae3b238 100644 --- a/libc/calls/mkntenvblock.c +++ b/libc/calls/mkntenvblock.c @@ -51,18 +51,23 @@ static void SortStrings(char **a, size_t n) { * * 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 - * @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; uint64_t w; char **vars; wint_t x, y; size_t i, j, k, n, m; for (n = 0; envp[n];) n++; - vars = alloca(n * sizeof(char *)); + vars = alloca((n + 1) * sizeof(char *)); memcpy(vars, envp, n * sizeof(char *)); + if (extravar) vars[n++] = extravar; SortStrings(vars, n); for (k = i = 0; i < n; ++i) { j = 0; diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index a3606b50d..1ee9b41dd 100644 --- a/libc/calls/ntspawn.c +++ b/libc/calls/ntspawn.c @@ -48,6 +48,7 @@ struct SpawnBlock { * don't need to be passed in sorted order; however, this function * goes faster the closer they are to sorted * @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 * be inherited; which, assuming the System V wrapper functions are * being used, should mean (1) all files and sockets that weren't @@ -59,7 +60,7 @@ struct SpawnBlock { */ textwindows int ntspawn( 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, uint32_t dwCreationFlags, const char16_t *opt_lpCurrentDirectory, const struct NtStartupInfo *lpStartupInfo, @@ -81,7 +82,7 @@ textwindows int ntspawn( MapViewOfFileExNuma(handle, kNtFileMapRead | kNtFileMapWrite, 0, 0, blocksize, NULL, kNtNumaNoPreferredNode))) { 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, opt_lpThreadAttributes, bInheritHandles, dwCreationFlags | kNtCreateUnicodeEnvironment, diff --git a/libc/calls/ntspawn.h b/libc/calls/ntspawn.h index 6933ed293..b794d5cce 100644 --- a/libc/calls/ntspawn.h +++ b/libc/calls/ntspawn.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ -#define COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ +#ifndef COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ +#define COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ #include "libc/nt/struct/processinformation.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/struct/startupinfo.h" @@ -7,12 +7,12 @@ COSMOPOLITAN_C_START_ int mkntcmdline(char16_t[ARG_MAX], const char *, char *const[]) hidden; -int mkntenvblock(char16_t[ARG_MAX], char *const[]) hidden; -int ntspawn(const char *, char *const[], char *const[], +int mkntenvblock(char16_t[ARG_MAX], char *const[], const char *) hidden; +int ntspawn(const char *, char *const[], char *const[], const char *, struct NtSecurityAttributes *, struct NtSecurityAttributes *, bool32, uint32_t, const char16_t *, const struct NtStartupInfo *, struct NtProcessInformation *) hidden; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_HEFTY_NTSPAWN_H_ */ +#endif /* COSMOPOLITAN_LIBC_CALLS_NTSPAWN_H_ */ diff --git a/libc/calls/openat.c b/libc/calls/openat.c index ccac9b901..5955a85cb 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -37,6 +37,7 @@ * ignored if O_CREAT or O_TMPFILE weren't passed * @return number needing close(), or -1 w/ errno * @asyncsignalsafe + * @vforksafe */ nodiscard int openat(int dirfd, const char *file, int flags, ...) { va_list va; @@ -47,11 +48,9 @@ nodiscard int openat(int dirfd, const char *file, int flags, ...) { va_end(va); if (!file) return efault(); if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) { - if (dirfd == AT_FDCWD) { - return weaken(__zipos_open)(&zipname, flags, mode); - } else { - return eopnotsupp(); /* TODO */ - } + if (__vforked) return einval(); + if (dirfd != AT_FDCWD) return einval(); + return weaken(__zipos_open)(&zipname, flags, mode); } else if (!IsWindows()) { return openat$sysv(dirfd, file, flags, mode); } else { diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index 5a6b94f1b..8ea675b3e 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -118,6 +118,7 @@ static void sigaction$native2cosmo(union metasigaction *sa) { * * @see xsigaction() for a much better api * @asyncsignalsafe + * @vforksafe */ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { _Static_assert(sizeof(struct sigaction) > sizeof(struct sigaction$linux) && diff --git a/libc/calls/hefty/ttyname.c b/libc/calls/ttyname.c similarity index 100% rename from libc/calls/hefty/ttyname.c rename to libc/calls/ttyname.c diff --git a/libc/calls/hefty/ttyname_r.c b/libc/calls/ttyname_r.c similarity index 100% rename from libc/calls/hefty/ttyname_r.c rename to libc/calls/ttyname_r.c diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index eb34bc68d..8d28e0ea2 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -48,7 +48,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { struct Garbages *garbage; sigset_t chldmask, savemask; const struct StackFrame *frame; - struct sigaction ignore, saveint, savequit; const char *debugbin, *p1, *p2, *p3, *addr2line; char buf[kBacktraceBufSize], *argv[kBacktraceMaxFrames]; 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; } 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); sigaddset(&chldmask, SIGCHLD); sigprocmask(SIG_BLOCK, &chldmask, &savemask); pipe(pipefds); if (!(pid = vfork())) { - sigaction(SIGINT, &saveint, NULL); - sigaction(SIGQUIT, &savequit, NULL); sigprocmask(SIG_SETMASK, &savemask, NULL); dup2(pipefds[1], 1); close(pipefds[0]); @@ -124,8 +116,6 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { if (errno == EINTR) continue; return -1; } - sigaction(SIGINT, &saveint, NULL); - sigaction(SIGQUIT, &savequit, NULL); sigprocmask(SIG_SETMASK, &savemask, NULL); if (WIFEXITED(ws) && !WEXITSTATUS(ws)) { return 0; diff --git a/libc/log/commandvenv.c b/libc/log/commandvenv.c index 13d1ca39a..38b89131d 100644 --- a/libc/log/commandvenv.c +++ b/libc/log/commandvenv.c @@ -25,19 +25,30 @@ /** * 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; - char pathbuf[PATH_MAX]; + static char pathbuf[PATH_MAX]; + if (*cmd == '/' || *cmd == '\\') return cmd; if ((exepath = getenv(var))) { - if (!isempty(exepath) && access(exepath, X_OK) != -1) { - return strdup(exepath); + if (isempty(exepath)) return NULL; + if (access(exepath, X_OK) != -1) { + return exepath; } else { return NULL; } - } else if ((exepath = commandv(cmd, pathbuf))) { - return strdup(exepath); - } else { - return NULL; } + return commandv(cmd, pathbuf); } diff --git a/libc/log/log.h b/libc/log/log.h index c92f29776..48424363e 100644 --- a/libc/log/log.h +++ b/libc/log/log.h @@ -40,7 +40,7 @@ void memsummary(int); /* light version of same thing */ uint16_t getttycols(uint16_t); int getttysize(int, struct winsize *) paramsnonnull(); bool IsTerminalInarticulate(void) nosideeffect; -char *commandvenv(const char *, const char *) nodiscard; +const char *commandvenv(const char *, const char *); const char *GetAddr2linePath(void); const char *GetGdbPath(void); diff --git a/libc/log/log.mk b/libc/log/log.mk index f0aa754f1..9418a904d 100644 --- a/libc/log/log.mk +++ b/libc/log/log.mk @@ -28,7 +28,6 @@ LIBC_LOG_A_CHECKS = \ LIBC_LOG_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_ELF \ LIBC_FMT \ LIBC_INTRIN \ diff --git a/libc/calls/hefty/fork-nt.c b/libc/runtime/fork-nt.c similarity index 86% rename from libc/calls/hefty/fork-nt.c rename to libc/runtime/fork-nt.c index ed465a2ff..e0be9f52d 100644 --- a/libc/calls/hefty/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -46,13 +46,14 @@ #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" -static textwindows int64_t ParseInt(char16_t **p) { - uint64_t x = 0; - while ('0' <= **p && **p <= '9') { - x *= 10; - x += *(*p)++ - '0'; +static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) { + *x = 0; + while (*p == ' ') p++; + while ('0' <= *p && *p <= '9') { + *x *= 10; + *x += *p++ - '0'; } - return x; + return p; } 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) { - int64_t h; void *addr; jmp_buf jb; - char16_t *p; uint64_t size; uint32_t i, varlen; struct DirectMap dm; + int64_t reader, writer; char16_t var[21 + 1 + 21 + 1]; varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var)); + if (!varlen) return; + if (varlen >= ARRAYLEN(var)) ExitProcess(123); SetEnvironmentVariable(u"_FORK", NULL); - if (!varlen || varlen >= ARRAYLEN(var)) return; - p = var; - h = ParseInt(&p); - if (*p++ == ' ') CloseHandle(ParseInt(&p)); - ReadAll(h, jb, sizeof(jb)); - ReadAll(h, &_mmi.i, sizeof(_mmi.i)); + ParseInt(ParseInt(var, &reader), &writer); + ReadAll(reader, jb, sizeof(jb)); + ReadAll(reader, &_mmi.i, sizeof(_mmi.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); size = ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE; if (_mmi.p[i].flags & MAP_PRIVATE) { CloseHandle(_mmi.p[i].h); - _mmi.p[i].h = - __mmap$nt(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, -1, 0) - .maphandle; - ReadAll(h, addr, size); + _mmi.p[i].h = __mmap$nt(addr, size, _mmi.p[i].prot, -1, 0).maphandle; + ReadAll(reader, addr, size); } else { MapViewOfFileExNuma( _mmi.p[i].h, @@ -109,9 +106,9 @@ textwindows void WinMainForked(void) { 0, 0, size, addr, kNtNumaNoPreferredNode); } } - ReadAll(h, _edata, _end - _edata); - CloseHandle(h); - unsetenv("_FORK"); + ReadAll(reader, _edata, _end - _edata); + CloseHandle(reader); + CloseHandle(writer); if (weaken(__wincrash$nt)) { AddVectoredExceptionHandler(1, (void *)weaken(__wincrash$nt)); } @@ -123,17 +120,16 @@ textwindows int fork$nt(void) { int i, rc, pid; char exe[PATH_MAX]; int64_t reader, writer; - char *p, buf[21 + 1 + 21 + 1]; + char *p, forkvar[6 + 21 + 1 + 21 + 1]; struct NtStartupInfo startinfo; struct NtProcessInformation procinfo; if ((pid = __getemptyfd()) == -1) return -1; if (!setjmp(jb)) { if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) { - p = buf; + p = stpcpy(forkvar, "_FORK="); p += uint64toarray_radix10(reader, p); *p++ = ' '; p += uint64toarray_radix10(writer, p); - setenv("_FORK", buf, true); memset(&startinfo, 0, sizeof(startinfo)); startinfo.cb = sizeof(struct NtStartupInfo); startinfo.dwFlags = kNtStartfUsestdhandles; @@ -141,8 +137,8 @@ textwindows int fork$nt(void) { startinfo.hStdOutput = g_fds.p[1].handle; startinfo.hStdError = g_fds.p[2].handle; GetModuleFileNameA(0, exe, ARRAYLEN(exe)); - if (ntspawn(exe, g_argv, environ, &kNtIsInheritable, NULL, true, 0, NULL, - &startinfo, &procinfo) != -1) { + if (ntspawn(exe, g_argv, environ, forkvar, &kNtIsInheritable, NULL, true, + 0, NULL, &startinfo, &procinfo) != -1) { CloseHandle(reader); CloseHandle(procinfo.hThread); if (weaken(__sighandrvas) && @@ -167,7 +163,6 @@ textwindows int fork$nt(void) { } else { rc = -1; } - unsetenv("_FORK"); rc = pid; } else { rc = __winerr(); diff --git a/libc/calls/hefty/fork.c b/libc/runtime/fork.c similarity index 100% rename from libc/calls/hefty/fork.c rename to libc/runtime/fork.c diff --git a/libc/calls/hefty/vfork.S b/libc/runtime/vfork.S similarity index 100% rename from libc/calls/hefty/vfork.S rename to libc/runtime/vfork.S diff --git a/libc/calls/hefty/dirstream.c b/libc/stdio/dirstream.c similarity index 100% rename from libc/calls/hefty/dirstream.c rename to libc/stdio/dirstream.c diff --git a/libc/calls/hefty/get_current_dir_name.c b/libc/stdio/get_current_dir_name.c similarity index 100% rename from libc/calls/hefty/get_current_dir_name.c rename to libc/stdio/get_current_dir_name.c diff --git a/libc/stdio/stdio.mk b/libc/stdio/stdio.mk index 221aa9f7f..e2fb92791 100644 --- a/libc/stdio/stdio.mk +++ b/libc/stdio/stdio.mk @@ -27,7 +27,6 @@ LIBC_STDIO_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_FMT \ LIBC_INTRIN \ LIBC_MEM \ diff --git a/libc/calls/hefty/filecmp.c b/libc/x/filecmp.c similarity index 100% rename from libc/calls/hefty/filecmp.c rename to libc/x/filecmp.c diff --git a/libc/calls/hefty/replaceuser.c b/libc/x/replaceuser.c similarity index 100% rename from libc/calls/hefty/replaceuser.c rename to libc/x/replaceuser.c diff --git a/libc/x/x.mk b/libc/x/x.mk index 8471121ae..6a8ca91ef 100644 --- a/libc/x/x.mk +++ b/libc/x/x.mk @@ -34,7 +34,6 @@ LIBC_X_A_CHECKS = \ LIBC_X_A_DIRECTDEPS = \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_FMT \ LIBC_INTRIN \ LIBC_MEM \ diff --git a/test/libc/calls/hefty/fork_test.c b/test/libc/calls/fork_test.c similarity index 100% rename from test/libc/calls/hefty/fork_test.c rename to test/libc/calls/fork_test.c diff --git a/test/libc/calls/mkntenvblock_test.c b/test/libc/calls/mkntenvblock_test.c index cd4e395a8..cdc9e77cd 100644 --- a/test/libc/calls/mkntenvblock_test.c +++ b/test/libc/calls/mkntenvblock_test.c @@ -24,13 +24,13 @@ char16_t envvars[ARG_MAX]; TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) { char *envp[] = {NULL}; - ASSERT_NE(-1, mkntenvblock(envvars, envp)); + ASSERT_NE(-1, mkntenvblock(envvars, envp, NULL)); ASSERT_BINEQ(u"  ", envvars); } TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { 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   " u"h d u c = d   " u"u = b   " @@ -39,3 +39,16 @@ TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) { u"  ", 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); +} diff --git a/test/libc/calls/test.mk b/test/libc/calls/test.mk index 49c60e349..92080975a 100644 --- a/test/libc/calls/test.mk +++ b/test/libc/calls/test.mk @@ -4,8 +4,7 @@ PKGS += TEST_LIBC_CALLS TEST_LIBC_CALLS_SRCS := \ - $(wildcard test/libc/calls/*.c) \ - $(wildcard test/libc/calls/hefty/*.c) + $(wildcard test/libc/calls/*.c) TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS)) TEST_LIBC_CALLS_OBJS = \ @@ -26,13 +25,13 @@ TEST_LIBC_CALLS_CHECKS = \ TEST_LIBC_CALLS_DIRECTDEPS = \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_FMT \ LIBC_INTRIN \ LIBC_LOG \ LIBC_MEM \ LIBC_NEXGEN32E \ LIBC_RAND \ + LIBC_STDIO \ LIBC_RUNTIME \ LIBC_STR \ LIBC_STUBS \ diff --git a/test/libc/calls/hefty/vfork_test.c b/test/libc/calls/vfork_test.c similarity index 100% rename from test/libc/calls/hefty/vfork_test.c rename to test/libc/calls/vfork_test.c diff --git a/test/libc/calls/hefty/dirstream_test.c b/test/libc/stdio/dirstream_test.c similarity index 100% rename from test/libc/calls/hefty/dirstream_test.c rename to test/libc/stdio/dirstream_test.c diff --git a/test/libc/stdio/test.mk b/test/libc/stdio/test.mk index 565fa0c01..5a727767b 100644 --- a/test/libc/stdio/test.mk +++ b/test/libc/stdio/test.mk @@ -29,6 +29,7 @@ TEST_LIBC_STDIO_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_MEM \ LIBC_NEXGEN32E \ + LIBC_RAND \ LIBC_RUNTIME \ LIBC_STDIO \ LIBC_STR \ diff --git a/third_party/chibicc/chibicc.mk b/third_party/chibicc/chibicc.mk index 2dad14334..afede2673 100644 --- a/third_party/chibicc/chibicc.mk +++ b/third_party/chibicc/chibicc.mk @@ -51,7 +51,6 @@ THIRD_PARTY_CHIBICC_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_FMT \ LIBC_INTRIN \ LIBC_LOG \ diff --git a/third_party/musl/musl.mk b/third_party/musl/musl.mk index d1b5b69bb..0e592f927 100644 --- a/third_party/musl/musl.mk +++ b/third_party/musl/musl.mk @@ -19,7 +19,6 @@ THIRD_PARTY_MUSL_A_OBJS = \ THIRD_PARTY_MUSL_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_INTRIN \ LIBC_MEM \ LIBC_NEXGEN32E \ diff --git a/tool/build/build.mk b/tool/build/build.mk index 45da7c7ce..6210e701f 100644 --- a/tool/build/build.mk +++ b/tool/build/build.mk @@ -28,7 +28,6 @@ TOOL_BUILD_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_DNS \ LIBC_ELF \ LIBC_FMT \ diff --git a/tool/build/lib/buildlib.mk b/tool/build/lib/buildlib.mk index 97128341d..6bb6634e3 100644 --- a/tool/build/lib/buildlib.mk +++ b/tool/build/lib/buildlib.mk @@ -27,7 +27,6 @@ TOOL_BUILD_LIB_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_ELF \ LIBC_FMT \ LIBC_INTRIN \ diff --git a/tool/net/net.mk b/tool/net/net.mk index 93202deef..35fd28468 100644 --- a/tool/net/net.mk +++ b/tool/net/net.mk @@ -22,7 +22,6 @@ TOOL_NET_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_DNS \ LIBC_FMT \ LIBC_INTRIN \ diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index 51ce661e8..a6f39aa47 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -1473,8 +1473,8 @@ int main(int argc, char *argv[]) { if (!tuned_) PickDefaults(); if (optind == argc) PrintUsage(EX_USAGE, stderr); patharg_ = argv[optind]; - sox_ = commandvenv("SOX", "sox"); - ffplay_ = commandvenv("FFPLAY", "ffplay"); + sox_ = strdup(commandvenv("SOX", "sox")); + ffplay_ = strdup(commandvenv("FFPLAY", "ffplay")); infd_ = STDIN_FILENO; outfd_ = STDOUT_FILENO; if (!setjmp(jb_)) { diff --git a/tool/viz/viz.mk b/tool/viz/viz.mk index 811000a77..17aa48ae8 100644 --- a/tool/viz/viz.mk +++ b/tool/viz/viz.mk @@ -22,7 +22,6 @@ TOOL_VIZ_DIRECTDEPS = \ DSP_TTY \ LIBC_BITS \ LIBC_CALLS \ - LIBC_CALLS_HEFTY \ LIBC_DNS \ LIBC_FMT \ LIBC_INTRIN \