From 00084577a3c8974fa7c09c15537b16160caa8d77 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 12 Sep 2023 08:58:57 -0700 Subject: [PATCH] Improve posix_spawn() some more --- build/definitions.mk | 45 ----- build/rules.mk | 70 ++----- libc/intrin/pthread_mutex_lock.c | 4 +- libc/intrin/pthread_mutex_unlock.c | 4 +- libc/runtime/zipos-open.c | 8 +- libc/stdio/dirstream.c | 8 +- libc/stdio/posix_spawn.c | 263 +++++++++++++++---------- libc/thread/pthread_create.c | 2 + test/libc/intrin/lock_test.c | 2 + test/libc/stdio/posix_spawn_test.c | 40 ++++ test/libc/stdio/test.mk | 10 - test/libc/thread/pthread_cancel_test.c | 2 +- test/libc/thread/sem_timedwait_test.c | 2 +- third_party/gdtoa/misc.c | 8 - third_party/mbedtls/test/lib.c | 2 +- tool/build/lib/eztls.c | 12 ++ tool/build/runit.c | 8 - tool/build/runitd.c | 104 +++++----- 18 files changed, 301 insertions(+), 293 deletions(-) diff --git a/build/definitions.mk b/build/definitions.mk index 796e0590d..21552bc23 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -61,7 +61,6 @@ ZFLAGS ?= XARGS ?= xargs -P4 -rs8000 DOT ?= dot CLANG = clang -FC = gfortran #/opt/cross9f/bin/x86_64-linux-musl-gfortran TMPDIR = o/tmp AR = build/bootstrap/ar.com @@ -334,8 +333,6 @@ LD.libs = \ COMPILE.c.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(c.flags) COMPILE.cxx.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(cxx.flags) -COMPILE.f.flags = $(cc.flags) $(copt.flags) $(f.flags) -COMPILE.F.flags = $(cc.flags) $(copt.flags) $(cpp.flags) $(f.flags) COMPILE.i.flags = $(cc.flags) $(copt.flags) $(c.flags) COMPILE.ii.flags = $(cc.flags) $(copt.flags) $(cxx.flags) LINK.flags = $(DEFAULT_LDFLAGS) $(CONFIG_LDFLAGS) $(LDFLAGS) @@ -343,20 +340,14 @@ OBJECTIFY.c.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) OBJECTIFY.cxx.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(cxx.flags) OBJECTIFY.s.flags = $(ASONLYFLAGS) $(s.flags) OBJECTIFY.S.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) -OBJECTIFY.f.flags = $(cc.flags) $(o.flags) $(S.flags) $(f.flags) -OBJECTIFY.F.flags = $(cc.flags) $(o.flags) $(S.flags) $(cpp.flags) $(copt.flags) $(f.flags) PREPROCESS.flags = -E $(copt.flags) $(cc.flags) $(cpp.flags) PREPROCESS.lds.flags = -D__LINKER__ $(filter-out -g%,$(PREPROCESS.flags)) -P -xc COMPILE.c = $(CC) -S $(COMPILE.c.flags) COMPILE.cxx = $(CXX) -S $(COMPILE.cxx.flags) COMPILE.i = $(CC) -S $(COMPILE.i.flags) -COMPILE.f = $(FC) -S $(COMPILE.f.flags) -COMPILE.F = $(FC) -S $(COMPILE.F.flags) OBJECTIFY.s = $(AS) $(OBJECTIFY.s.flags) OBJECTIFY.S = $(CC) $(OBJECTIFY.S.flags) -c -OBJECTIFY.f = $(FC) $(OBJECTIFY.f.flags) -c -OBJECTIFY.F = $(FC) $(OBJECTIFY.F.flags) -c OBJECTIFY.c = $(CC) $(OBJECTIFY.c.flags) -c OBJECTIFY.cxx = $(CXX) $(OBJECTIFY.cxx.flags) -c PREPROCESS = $(CC) $(PREPROCESS.flags) @@ -382,42 +373,6 @@ OBJECTIFY.greg.c = \ -fwrapv \ -c -OBJECTIFY.ansi.c = $(CC) $(OBJECTIFY.c.flags) -ansi -Wextra -Werror -pedantic-errors -c -OBJECTIFY.c99.c = $(CC) $(OBJECTIFY.c.flags) -std=c99 -Wextra -Werror -pedantic-errors -c -OBJECTIFY.c11.c = $(CC) $(OBJECTIFY.c.flags) -std=c11 -Wextra -Werror -pedantic-errors -c -OBJECTIFY.c2x.c = $(CC) $(OBJECTIFY.c.flags) -std=c2x -Wextra -Werror -pedantic-errors -c - -OBJECTIFY.ncabi.c = \ - $(GCC) \ - $(OBJECTIFY.c.flags) \ - -mno-sse \ - -mfpmath=387 \ - -fno-stack-protector \ - -fno-instrument-functions \ - -fno-optimize-sibling-calls \ - -fno-sanitize=all \ - -fcall-saved-rcx \ - -fcall-saved-rdx \ - -fcall-saved-rdi \ - -fcall-saved-rsi \ - -fcall-saved-r8 \ - -fcall-saved-r9 \ - -fcall-saved-r10 \ - -fcall-saved-r11 \ - -c \ - -xc - -OBJECTIFY.initabi.c = \ - $(GCC) \ - $(OBJECTIFY.c.flags) \ - -fno-stack-protector \ - -fno-instrument-functions \ - -fno-optimize-sibling-calls \ - -fno-sanitize=all \ - -fcall-saved-rdi \ - -fcall-saved-rsi \ - -c - TAGSFLAGS = \ -e \ -a \ diff --git a/build/rules.mk b/build/rules.mk index 4025aece8..e2a4c9f95 100644 --- a/build/rules.mk +++ b/build/rules.mk @@ -23,49 +23,8 @@ else MAKE_OBJCOPY = $(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S $< $@ && $(MAKE_ZIPCOPY) endif -o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $< -o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $< -o/$(MODE)/%: o/$(MODE)/%.dbg ; @$(MAKE_OBJCOPY) -o/$(MODE)/%.o: %.f ; @$(COMPILE) -AOBJECTIFY.f $(OBJECTIFY.f) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.F ; @$(COMPILE) -AOBJECTIFY.F $(OBJECTIFY.F) $(OUTPUT_OPTION) $< -o/$(MODE)/%.h: %.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< -o/$(MODE)/%.h: o/$(MODE)/%.c ; @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< -o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< -o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $< -o/$(MODE)/%.initabi.o: %.initabi.c ; @$(COMPILE) -AOBJECTIFY.init $(OBJECTIFY.initabi.c) $(OUTPUT_OPTION) $< -o/$(MODE)/%.ncabi.o: %.ncabi.c ; @$(COMPILE) -AOBJECTIFY.nc $(OBJECTIFY.ncabi.c) $(OUTPUT_OPTION) $< - -ifneq ($(ARCH), aarch64) -o/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/%.o: o/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/%.s: %.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $< -o/%.s: o/%.S ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) $< -o/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/%.o: o/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: %.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -o/$(MODE)/%.o: o/$(MODE)/%.S ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< -else -o/%.o: %.s libc/empty.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/%.o: o/%.s libc/empty.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/%.s: %.S libc/empty.s ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) libc/empty.s -o/%.s: o/%.S libc/empty.s ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) libc/empty.s -o/%.o: %.S libc/empty.s ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/%.o: o/%.S libc/empty.s ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/$(MODE)/%.o: %.s libc/empty.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/$(MODE)/%.o: o/$(MODE)/%.s libc/empty.s ; @$(COMPILE) -AOBJECTIFY.s $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/$(MODE)/%.o: %.S libc/empty.s ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -o/$(MODE)/%.o: o/$(MODE)/%.S libc/empty.s ; @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s -endif - -o/%.o: %.cc - @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< - @$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@ - -o/%.o: o/%.cc - @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< - @$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@ +o/$(MODE)/%: o/$(MODE)/%.dbg + @$(MAKE_OBJCOPY) o/$(MODE)/%.o: %.c @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $< @@ -75,13 +34,26 @@ o/$(MODE)/%.o: o/$(MODE)/%.c @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $< @$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@ -o/$(MODE)/%.o: o/$(MODE)/%.cc - @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< - @$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@ +o/$(MODE)/%.h: %.c + @$(COMPILE) -AAMALGAMATE $(PREPROCESS) $(OUTPUT_OPTION) -fdirectives-only -P $< -o/%.greg.o: %.greg.c - @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< - @$(COMPILE) -AFIXUPOBJ -wT$@ $(FIXUPOBJ) $@ +o/$(MODE)/%.o: %.cc + @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $< + +o/$(MODE)/%.lds: %.lds + @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $< + +ifneq ($(ARCH), aarch64) +o/$(MODE)/%.o: %.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/%.o: o/$(MODE)/%.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +else +o/$(MODE)/%.o: %.S libc/empty.s + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s +o/$(MODE)/%.o: o/$(MODE)/%.S libc/empty.s + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.s) $(OUTPUT_OPTION) libc/empty.s +endif o/$(MODE)/%.o: %.greg.c @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $< diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 4d6b6432b..955488083 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -67,7 +67,9 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) { int t; - if (__vforked) return 0; + if ((!__threaded && mutex->_pshared != PTHREAD_PROCESS_SHARED) || __vforked) { + return 0; + } LOCKTRACE("pthread_mutex_lock(%t)", mutex); diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index 643eec8ed..158688c7c 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -39,7 +39,9 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) { int t; - if (__vforked) return 0; + if ((!__threaded && mutex->_pshared != PTHREAD_PROCESS_SHARED) || __vforked) { + return 0; + } LOCKTRACE("pthread_mutex_unlock(%t)", mutex); diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index 8bc0154d0..da289f5a6 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -53,15 +53,11 @@ static size_t __zipos_maptotal; static pthread_mutex_t __zipos_lock_obj; static void __zipos_lock(void) { - if (__threaded) { - pthread_mutex_lock(&__zipos_lock_obj); - } + pthread_mutex_lock(&__zipos_lock_obj); } static void __zipos_unlock(void) { - if (__threaded) { - pthread_mutex_unlock(&__zipos_lock_obj); - } + pthread_mutex_unlock(&__zipos_lock_obj); } static void __zipos_funlock(void) { diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index 5da0eeec8..3fba4f06d 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -132,15 +132,11 @@ struct dirent_netbsd { }; static void lockdir(DIR *dir) { - if (__threaded) { - pthread_mutex_lock(&dir->lock); - } + pthread_mutex_lock(&dir->lock); } static void unlockdir(DIR *dir) { - if (__threaded) { - pthread_mutex_unlock(&dir->lock); - } + pthread_mutex_unlock(&dir->lock); } static textwindows dontinline int fdopendir_nt(DIR *res, int fd) { diff --git a/libc/stdio/posix_spawn.c b/libc/stdio/posix_spawn.c index bade9ef96..a2a3cb0a7 100644 --- a/libc/stdio/posix_spawn.c +++ b/libc/stdio/posix_spawn.c @@ -18,26 +18,33 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/stdio/posix_spawn.h" #include "libc/assert.h" +#include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/ntspawn.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/fd.internal.h" #include "libc/calls/struct/rlimit.h" +#include "libc/calls/struct/rlimit.internal.h" +#include "libc/calls/struct/rusage.internal.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/atomic.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/handlock.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/mem/alloca.h" +#include "libc/nt/createfile.h" #include "libc/nt/enum/processcreationflags.h" #include "libc/nt/enum/startf.h" #include "libc/nt/files.h" @@ -50,6 +57,9 @@ #include "libc/stdio/posix_spawn.internal.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" +#include "libc/sysv/consts/at.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/fd.h" #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/ok.h" @@ -57,13 +67,30 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -static void posix_spawn_cleanup3fds(int fds[3]) { +#ifndef SYSDEBUG +#define read sys_read +#define write sys_write +#define close sys_close +#define pipe2 sys_pipe2 +#define getgid sys_getgid +#define setgid sys_setgid +#define getuid sys_getuid +#define setuid sys_setuid +#define setsid sys_setsid +#define setpgid sys_setpgid +#define fcntl __sys_fcntl +#define wait4 __sys_wait4 +#define openat __sys_openat +#define setrlimit sys_setrlimit +#define sigprocmask sys_sigprocmask +#endif + +static atomic_bool real_vfork; // i.e. not qemu/wsl/xnu/openbsd + +static void posix_spawn_unhand(int64_t hands[3]) { for (int i = 0; i < 3; ++i) { - if (fds[i] != -1) { - int e = errno; - if (close(fds[i])) { - errno = e; - } + if (hands[i] != -1) { + CloseHandle(hands[i]); } } } @@ -76,13 +103,6 @@ static void posix_spawn_inherit(int64_t hands[3], bool32 bInherit) { } } -static const char *DescribePid(char buf[12], int err, int *pid) { - if (err) return "n/a"; - if (!pid) return "NULL"; - FormatInt32(buf, *pid); - return buf; -} - static textwindows errno_t posix_spawn_windows_impl( int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { @@ -91,7 +111,6 @@ static textwindows errno_t posix_spawn_windows_impl( // create file descriptor work area char stdio_kind[3] = {kFdEmpty, kFdEmpty, kFdEmpty}; intptr_t stdio_handle[3] = {-1, -1, -1}; - int close_this_fd_later[3] = {-1, -1, -1}; for (i = 0; i < 3; ++i) { if (g_fds.p[i].kind != kFdEmpty && !(g_fds.p[i].flags & O_CLOEXEC)) { stdio_kind[i] = g_fds.p[i].kind; @@ -103,6 +122,7 @@ static textwindows errno_t posix_spawn_windows_impl( int child = __reservefd(-1); // apply user file actions + intptr_t close_handle[3] = {-1, -1, -1}; if (file_actions) { int err = 0; for (struct _posix_faction *a = *file_actions; a && !err; a = a->next) { @@ -122,12 +142,18 @@ static textwindows errno_t posix_spawn_windows_impl( } break; case _POSIX_SPAWN_OPEN: { - int fd, e = errno; + int64_t hand; + int e = errno; + char16_t path16[PATH_MAX]; + uint32_t perm, share, disp, attr; unassert(a->fildes < 3u); - if ((fd = open(a->path, a->oflag, a->mode)) != -1) { - close_this_fd_later[a->fildes] = fd; - stdio_kind[a->fildes] = g_fds.p[fd].kind; - stdio_handle[a->fildes] = g_fds.p[fd].handle; + if (__mkntpathat(AT_FDCWD, a->path, 0, path16) != -1 && + GetNtOpenFlags(a->oflag, a->mode, // + &perm, &share, &disp, &attr) != -1 && + (hand = CreateFile(path16, perm, share, 0, disp, attr, 0))) { + stdio_kind[a->fildes] = kFdFile; + close_handle[a->fildes] = hand; + stdio_handle[a->fildes] = hand; } else { err = errno; errno = e; @@ -139,7 +165,7 @@ static textwindows errno_t posix_spawn_windows_impl( } } if (err) { - posix_spawn_cleanup3fds(close_this_fd_later); + posix_spawn_unhand(close_handle); __releasefd(child); return err; } @@ -191,7 +217,7 @@ static textwindows errno_t posix_spawn_windows_impl( rc = ntspawn(path, argv, envp, v, 0, 0, bInheritHandles, dwCreationFlags, 0, &startinfo, &procinfo); posix_spawn_inherit(stdio_handle, false); - posix_spawn_cleanup3fds(close_this_fd_later); + posix_spawn_unhand(close_handle); __hand_runlock(); if (rc == -1) { int err = errno; @@ -212,6 +238,13 @@ static textwindows errno_t posix_spawn_windows_impl( return 0; } +static const char *DescribePid(char buf[12], int err, int *pid) { + if (err) return "n/a"; + if (!pid) return "NULL"; + FormatInt32(buf, *pid); + return buf; +} + static textwindows dontinline errno_t posix_spawn_windows( int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { @@ -230,49 +263,6 @@ static textwindows dontinline errno_t posix_spawn_windows( return err; } -static wontreturn void posix_spawn_die(const char *thing) { - const char *reason; // print b/c there's no other way - if (!(reason = _strerdoc(errno))) reason = "Unknown error"; - tinyprint(2, program_invocation_short_name, ": posix_spawn ", thing, - " failed: ", reason, "\n", NULL); - _Exit(127); -} - -static void RunUnixFileActions(struct _posix_faction *a) { - for (; a; a = a->next) { - switch (a->action) { - case _POSIX_SPAWN_CLOSE: - if (close(a->fildes)) { - posix_spawn_die("close"); - } - break; - case _POSIX_SPAWN_DUP2: - if (dup2(a->fildes, a->newfildes) == -1) { - posix_spawn_die("dup2"); - } - break; - case _POSIX_SPAWN_OPEN: { - int t; - if ((t = open(a->path, a->oflag, a->mode)) == -1) { - posix_spawn_die(a->path); - } - if (t != a->fildes) { - if (dup2(t, a->fildes) == -1) { - close(t); - posix_spawn_die("dup2"); - } - if (close(t)) { - posix_spawn_die("close"); - } - } - break; - } - default: - __builtin_unreachable(); - } - } -} - /** * Spawns process, the POSIX way. * @@ -289,15 +279,6 @@ static void RunUnixFileActions(struct _posix_faction *a) { * this implementation will ensure signal handlers can't be called in * the child process since that'd likely corrupt the parent's memory. * - * This implementation doesn't create a pipe like Musl Libc, and will - * report errors in the child process by printing the cause to stderr - * which ensures posix_spawn stays fast, and works w/ `RLIMIT_FILENO` - * There is however one particular case where knowing the execve code - * truly matters, which is ETXTBSY. Thankfully, there's a rarely used - * signal with the exact same magic number across supported platforms - * called SIGVTALRM which we send to wait4 when execve raises ETXTBSY - * Please note that on Windows posix_spawn() returns ETXTBSY directly - * * @param pid if non-null shall be set to child pid on success * @param path is resolved path of program which is not `$PATH` searched * @param file_actions specifies close(), dup2(), and open() operations @@ -316,60 +297,102 @@ errno_t posix_spawn(int *pid, const char *path, if (IsWindows()) { return posix_spawn_windows(pid, path, file_actions, attrp, argv, envp); } + int pfds[2]; + bool use_pipe; + volatile int status = 0; sigset_t blockall, oldmask; int child, res, cs, e = errno; - if (access(path, X_OK)) { - res = errno; - errno = e; - return res; - } + volatile bool can_clobber = false; sigfillset(&blockall); - sys_sigprocmask(SIG_SETMASK, &blockall, &oldmask); + sigprocmask(SIG_SETMASK, &blockall, &oldmask); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + if ((use_pipe = !atomic_load_explicit(&real_vfork, memory_order_acquire))) { + if (pipe2(pfds, O_CLOEXEC)) { + res = errno; + goto ParentFailed; + } + } if (!(child = vfork())) { + can_clobber = true; sigset_t *childmask; + bool lost_cloexec = 0; struct sigaction dfl = {0}; short flags = attrp && *attrp ? (*attrp)->flags : 0; + if (use_pipe) close(pfds[0]); for (int sig = 1; sig < _NSIG; sig++) { if (__sighandrvas[sig] != (long)SIG_DFL && (__sighandrvas[sig] != (long)SIG_IGN || ((flags & POSIX_SPAWN_SETSIGDEF) && - sigismember(&(*attrp)->sigdefault, sig) == 1) || - sig == SIGVTALRM)) { + sigismember(&(*attrp)->sigdefault, sig) == 1))) { sigaction(sig, &dfl, 0); } } - if (flags & POSIX_SPAWN_SETSIGMASK) { - childmask = &(*attrp)->sigmask; - } else { - childmask = &oldmask; - } - sys_sigprocmask(SIG_SETMASK, childmask, 0); if (flags & POSIX_SPAWN_SETSID) { setsid(); } if ((flags & POSIX_SPAWN_SETPGROUP) && setpgid(0, (*attrp)->pgroup)) { - posix_spawn_die("setpgid"); + goto ChildFailed; } if ((flags & POSIX_SPAWN_RESETIDS) && setgid(getgid())) { - posix_spawn_die("setgid"); + goto ChildFailed; } - if ((flags & POSIX_SPAWN_RESETIDS) && setgid(getgid())) { - posix_spawn_die("setuid"); + if ((flags & POSIX_SPAWN_RESETIDS) && setuid(getuid())) { + goto ChildFailed; } if (file_actions) { - RunUnixFileActions(*file_actions); + struct _posix_faction *a; + for (a = *file_actions; a; a = a->next) { + if (use_pipe && pfds[1] == a->fildes) { + int p2; + if ((p2 = dup(pfds[1])) == -1) { + goto ChildFailed; + } + lost_cloexec = true; + close(pfds[1]); + pfds[1] = p2; + } + switch (a->action) { + case _POSIX_SPAWN_CLOSE: + if (close(a->fildes)) { + goto ChildFailed; + } + break; + case _POSIX_SPAWN_DUP2: + if (dup2(a->fildes, a->newfildes) == -1) { + goto ChildFailed; + } + break; + case _POSIX_SPAWN_OPEN: { + int t; + if ((t = openat(AT_FDCWD, a->path, a->oflag, a->mode)) == -1) { + goto ChildFailed; + } + if (t != a->fildes) { + if (dup2(t, a->fildes) == -1) { + close(t); + goto ChildFailed; + } + if (close(t)) { + goto ChildFailed; + } + } + break; + } + default: + __builtin_unreachable(); + } + } } if (IsLinux() || IsFreebsd() || IsNetbsd()) { if (flags & POSIX_SPAWN_SETSCHEDULER) { if (sched_setscheduler(0, (*attrp)->schedpolicy, &(*attrp)->schedparam) == -1) { - posix_spawn_die("sched_setscheduler"); + goto ChildFailed; } } if (flags & POSIX_SPAWN_SETSCHEDPARAM) { if (sched_setparam(0, &(*attrp)->schedparam)) { - posix_spawn_die("sched_setparam"); + goto ChildFailed; } } } @@ -377,24 +400,58 @@ errno_t posix_spawn(int *pid, const char *path, for (int rez = 0; rez <= ARRAYLEN((*attrp)->rlim); ++rez) { if ((*attrp)->rlimset & (1u << rez)) { if (setrlimit(rez, (*attrp)->rlim + rez)) { - posix_spawn_die("setrlimit"); + goto ChildFailed; } } } } + if (lost_cloexec) { + fcntl(pfds[1], F_SETFD, FD_CLOEXEC); + } + if (flags & POSIX_SPAWN_SETSIGMASK) { + childmask = &(*attrp)->sigmask; + } else { + childmask = &oldmask; + } + sigprocmask(SIG_SETMASK, childmask, 0); if (!envp) envp = environ; execve(path, argv, envp); - if (errno == ETXTBSY) { - sys_kill(getpid(), SIGVTALRM, 1); + ChildFailed: + res = errno; + if (!use_pipe) { + status = res; + } else { + write(pfds[1], &res, sizeof(res)); } - posix_spawn_die(path); + _Exit(127); + } + if (use_pipe) { + close(pfds[1]); } - sys_sigprocmask(SIG_SETMASK, &oldmask, 0); - pthread_setcancelstate(cs, 0); if (child != -1) { - if (pid) *pid = child; - return 0; + if (!use_pipe) { + res = status; + } else { + if (can_clobber) { + atomic_store_explicit(&real_vfork, true, memory_order_release); + } + res = 0; + read(pfds[0], &res, sizeof(res)); + } + if (!res) { + if (pid) *pid = child; + } else { + wait4(child, 0, 0, 0); + } } else { - return errno; + res = errno; } + if (use_pipe) { + close(pfds[0]); + } +ParentFailed: + sigprocmask(SIG_SETMASK, &oldmask, 0); + pthread_setcancelstate(cs, 0); + errno = e; + return res; } diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 9f9f3ba84..c49daf5ad 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -49,6 +49,8 @@ __static_yoink("nsync_mu_lock"); __static_yoink("nsync_mu_unlock"); +__static_yoink("nsync_mu_rlock"); +__static_yoink("nsync_mu_runlock"); __static_yoink("_pthread_atfork"); #define MAP_ANON_OPENBSD 0x1000 diff --git a/test/libc/intrin/lock_test.c b/test/libc/intrin/lock_test.c index 45188ccb4..8a992218c 100644 --- a/test/libc/intrin/lock_test.c +++ b/test/libc/intrin/lock_test.c @@ -180,6 +180,8 @@ int main(int argc, char *argv[]) { _Exit(1); } + __threaded = 1; + ASSERT_EQ(0, pthread_mutexattr_init(&attr)); ASSERT_EQ(0, pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL)); ASSERT_EQ(0, pthread_mutex_init(&mu, &attr)); diff --git a/test/libc/stdio/posix_spawn_test.c b/test/libc/stdio/posix_spawn_test.c index 390426d59..bf999ec14 100644 --- a/test/libc/stdio/posix_spawn_test.c +++ b/test/libc/stdio/posix_spawn_test.c @@ -23,8 +23,10 @@ #include "libc/calls/state.internal.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" +#include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/safemacros.internal.h" @@ -219,6 +221,44 @@ TEST(posix_spawn, agony) { } } +void EmptySigHandler(int sig) { +} + +TEST(posix_spawn, etxtbsy) { + if (IsWindows()) return; // can't deliver signals between processes + if (IsXnu()) return; // they don't appear impacted by this race condition + if (IsNetbsd()) return; // they don't appear impacted by this race condition + if (IsOpenbsd()) return; // they don't appear impacted by this race condition + int ws, me, pid, thief; + char *prog = "./life.com"; + char *args[] = {prog, 0}; + char *envs[] = {0}; + sigset_t ss, old; + testlib_extract("/zip/life.com", prog, 0755); + for (int i = 0; i < 2; ++i) { + sigemptyset(&ss); + sigaddset(&ss, SIGUSR1); + sigprocmask(SIG_BLOCK, &ss, &old); + sigdelset(&ss, SIGUSR1); + ASSERT_SYS(0, 3, open(prog, O_RDWR)); + signal(SIGUSR1, EmptySigHandler); + me = getpid(); + if (!(thief = fork())) { + ASSERT_SYS(0, 0, kill(me, SIGUSR1)); + ASSERT_SYS(EINTR, -1, sigsuspend(&ss)); + _Exit(0); + } + EXPECT_SYS(0, 0, close(3)); + EXPECT_SYS(EINTR, -1, sigsuspend(&ss)); + EXPECT_EQ(ETXTBSY, posix_spawn(&pid, prog, NULL, NULL, args, envs)); + EXPECT_EQ(0, kill(thief, SIGUSR1)); + EXPECT_EQ(thief, wait(&ws)); + ASSERT_EQ(0, ws); + sigprocmask(SIG_SETMASK, &old, 0); + unassert(!errno); + } +} + //////////////////////////////////////////////////////////////////////////////// void ForkExecveWait(const char *prog) { diff --git a/test/libc/stdio/test.mk b/test/libc/stdio/test.mk index 3e66a340d..2fe0b5f38 100644 --- a/test/libc/stdio/test.mk +++ b/test/libc/stdio/test.mk @@ -100,16 +100,6 @@ o/$(MODE)/test/libc/stdio/posix_spawn_test.com.dbg: \ $(APE_NO_MODIFY_SELF) @$(APELINK) -o/$(MODE)/test/libc/stdio/wut_test.com.dbg: \ - $(TEST_LIBC_STDIO_DEPS) \ - o/$(MODE)/test/libc/stdio/wut_test.o \ - o/$(MODE)/test/libc/stdio/stdio.pkg \ - o/$(MODE)/tool/build/echo.com.zip.o \ - $(LIBC_TESTMAIN) \ - $(CRT) \ - $(APE_NO_MODIFY_SELF) - @$(APELINK) - $(TEST_LIBC_STDIO_OBJS): private \ DEFAULT_CCFLAGS += \ -fno-builtin diff --git a/test/libc/thread/pthread_cancel_test.c b/test/libc/thread/pthread_cancel_test.c index d77e55f5d..8a947edb3 100644 --- a/test/libc/thread/pthread_cancel_test.c +++ b/test/libc/thread/pthread_cancel_test.c @@ -169,7 +169,7 @@ void *CondWaitDeferredWorker(void *arg) { pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, 0); ASSERT_EQ(0, pthread_mutex_lock(&mu)); ASSERT_EQ(ECANCELED, pthread_cond_timedwait(&cv, &mu, 0)); - __builtin_trap(); + abort(); } TEST(pthread_cancel, condDeferredWait_reacquiresMutex) { diff --git a/test/libc/thread/sem_timedwait_test.c b/test/libc/thread/sem_timedwait_test.c index 1d97b792c..79c802426 100644 --- a/test/libc/thread/sem_timedwait_test.c +++ b/test/libc/thread/sem_timedwait_test.c @@ -95,7 +95,7 @@ void *Worker(void *arg) { sem_t **s = arg; struct timespec ts; ASSERT_SYS(0, 0, clock_gettime(CLOCK_REALTIME, &ts)); - ts.tv_sec += 1; + ts.tv_sec += 10; ASSERT_SYS(0, 0, sem_post(s[0])); ASSERT_SYS(0, 0, sem_timedwait(s[1], &ts)); return 0; diff --git a/third_party/gdtoa/misc.c b/third_party/gdtoa/misc.c index 33d7d08fa..441b91a15 100644 --- a/third_party/gdtoa/misc.c +++ b/third_party/gdtoa/misc.c @@ -44,16 +44,12 @@ static pthread_mutex_t __gdtoa_lock1_obj; static void __gdtoa_lock(void) { - if (!__threaded) - return; pthread_mutex_lock(&__gdtoa_lock_obj); } static void __gdtoa_unlock(void) { - if (!__threaded) - return; pthread_mutex_unlock(&__gdtoa_lock_obj); } @@ -66,16 +62,12 @@ __gdtoa_initlock(void) static void __gdtoa_lock1(void) { - if (!__threaded) - return; pthread_mutex_lock(&__gdtoa_lock1_obj); } static void __gdtoa_unlock1(void) { - if (!__threaded) - return; pthread_mutex_unlock(&__gdtoa_lock1_obj); } diff --git a/third_party/mbedtls/test/lib.c b/third_party/mbedtls/test/lib.c index 8c0cdba6a..77add2c7b 100644 --- a/third_party/mbedtls/test/lib.c +++ b/third_party/mbedtls/test/lib.c @@ -79,7 +79,7 @@ struct Buffer { char *output; jmp_buf jmp_tmp; -int option_verbose = 1; +int option_verbose; mbedtls_test_info_t mbedtls_test_info; static char tmpdir[PATH_MAX]; static char third_party[PATH_MAX]; diff --git a/tool/build/lib/eztls.c b/tool/build/lib/eztls.c index 7f9a0a9e4..b2f6547e1 100644 --- a/tool/build/lib/eztls.c +++ b/tool/build/lib/eztls.c @@ -21,6 +21,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/iovec.h" #include "libc/errno.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/runtime/syslib.internal.h" @@ -28,6 +29,7 @@ #include "libc/x/x.h" #include "libc/x/xsigaction.h" #include "net/https/https.h" +#include "third_party/mbedtls/debug.h" #include "third_party/mbedtls/net_sockets.h" #include "third_party/mbedtls/ssl.h" @@ -210,9 +212,19 @@ void EzInitialize(void) { InitializeRng(&ezrng); } +static void OnSslDebug(void *ctx, int level, const char *file, int line, + const char *message) { + char sline[12]; + char slevel[12]; + FormatInt32(sline, line); + FormatInt32(slevel, level); + tinyprint(2, file, ":", sline, ": (", slevel, ") ", message, "\n", NULL); +} + void EzSetup(char psk[32]) { int rc; EzSanity(); + mbedtls_ssl_conf_dbg(&ezconf, OnSslDebug, 0); mbedtls_ssl_conf_rng(&ezconf, mbedtls_ctr_drbg_random, &ezrng); if ((rc = mbedtls_ssl_conf_psk(&ezconf, psk, 32, "runit", 5))) { EzTlsDie("EzSetup mbedtls_ssl_conf_psk", rc); diff --git a/tool/build/runit.c b/tool/build/runit.c index fdf6d7d81..465ad4b7e 100644 --- a/tool/build/runit.c +++ b/tool/build/runit.c @@ -345,14 +345,6 @@ int ReadResponse(void) { return exitcode; } -static inline bool IsElf(const char *p, size_t n) { - return n >= 4 && READ32LE(p) == READ32LE("\177ELF"); -} - -static inline bool IsMachO(const char *p, size_t n) { - return n >= 4 && READ32LE(p) == 0xFEEDFACEu + 1; -} - int RunOnHost(char *spec) { int err; char *p; diff --git a/tool/build/runitd.c b/tool/build/runitd.c index 7491e6e7c..83b53e68e 100644 --- a/tool/build/runitd.c +++ b/tool/build/runitd.c @@ -28,6 +28,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" +#include "libc/fmt/itoa.h" #include "libc/fmt/libgen.h" #include "libc/intrin/bits.h" #include "libc/intrin/kprintf.h" @@ -77,6 +78,7 @@ #include "net/http/escape.h" #include "net/https/https.h" #include "third_party/getopt/getopt.internal.h" +#include "third_party/mbedtls/debug.h" #include "third_party/mbedtls/ssl.h" #include "third_party/zlib/zlib.h" #include "tool/build/lib/eztls.h" @@ -124,7 +126,7 @@ #define LOG_LEVEL_WARN 0 #define LOG_LEVEL_INFO 1 -#define LOG_LEVEL_VERB 3 +#define LOG_LEVEL_VERB 2 #define LOG_LEVEL_DEBU 3 #define DEBUF(FMT, ...) LOGF(DEBU, FMT, ##__VA_ARGS__) @@ -157,7 +159,7 @@ struct Client { char *data; } rbuf; char *output; - char exepath[128]; + char tmpexepath[128]; char buf[32768]; }; @@ -203,7 +205,7 @@ void GetOpts(int argc, char *argv[]) { g_servaddr.sin_family = AF_INET; g_servaddr.sin_port = htons(RUNITD_PORT); g_servaddr.sin_addr.s_addr = INADDR_ANY; - while ((opt = getopt(argc, argv, "fqhvsdrl:p:t:w:")) != -1) { + while ((opt = getopt(argc, argv, "fqhvVsdrl:p:t:w:")) != -1) { switch (opt) { case 'f': use_ftrace = true; @@ -217,6 +219,9 @@ void GetOpts(int argc, char *argv[]) { case 'v': ++g_log_level; break; + case 'V': + ++mbedtls_debug_threshold; + break; case 'd': g_daemonize = true; break; @@ -422,8 +427,8 @@ void FreeClient(struct Client *client) { waitpid(client->pid, 0, 0); } Close(&client->fd); - if (*client->exepath) { - unlink(client->exepath); + if (*client->tmpexepath) { + unlink(client->tmpexepath); } if (client->once) { inflateEnd(&client->zs); @@ -441,7 +446,7 @@ void *ClientWorker(void *arg) { int events, wstatus; struct Client *client = arg; uint32_t namesize, filesize; - char *addrstr, *exename, *exe; + char *addrstr, *origname; unsigned char msg[4 + 1 + 4 + 4 + 4]; SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER, g_psk); @@ -467,14 +472,14 @@ void *ClientWorker(void *arg) { namesize = READ32BE(msg + 5); filesize = READ32BE(msg + 9); crc = READ32BE(msg + 13); - exename = gc(calloc(1, namesize + 1)); - Recv(client, exename, namesize); - INFOF("%s sent %#s (%'u bytes @ %#s)", addrstr, exename, filesize, - client->exepath); - exe = gc(malloc(filesize)); - Recv(client, exe, filesize); - if (crc32_z(0, exe, filesize) != crc) { - WARNF("%s crc mismatch! %#s", addrstr, exename); + origname = gc(calloc(1, namesize + 1)); + Recv(client, origname, namesize); + INFOF("%s sent %#s (%'u bytes @ %#s)", addrstr, origname, filesize, + client->tmpexepath); + char *exedata = gc(malloc(filesize)); + Recv(client, exedata, filesize); + if (crc32_z(0, exedata, filesize) != crc) { + WARNF("%s crc mismatch! %#s", addrstr, origname); pthread_exit(0); } @@ -483,36 +488,28 @@ void *ClientWorker(void *arg) { // condition can happen, where etxtbsy is raised by our execve // we're using o_cloexec so it's guaranteed to fix itself fast // thus we use an optimistic approach to avoid expensive locks - sprintf(client->exepath, "o/%s.XXXXXX.com", basename(exename)); - int exefd = openatemp(AT_FDCWD, client->exepath, 4, O_CLOEXEC, 0700); + sprintf(client->tmpexepath, "o/%s.XXXXXX.com", basename(origname)); + int exefd = openatemp(AT_FDCWD, client->tmpexepath, 4, O_CLOEXEC, 0700); ftruncate(exefd, filesize); - if (write(exefd, exe, filesize) != filesize) { - WARNF("%s failed to write %#s", addrstr, exename); + if (write(exefd, exedata, filesize) != filesize) { + WARNF("%s failed to write %#s", addrstr, origname); close(exefd); pthread_exit(0); } if (close(exefd)) { - WARNF("%s failed to close %#s", addrstr, exename); + WARNF("%s failed to close %#s", addrstr, origname); pthread_exit(0); } // do the args int i = 0; char *args[8] = {0}; - if (!IsXnuSilicon()) { - exe = client->exepath; - } else { - exe = "ape-m1.com"; - args[i++] = (char *)exe; - args[i++] = "-"; - args[i++] = client->exepath; - } - args[i++] = client->exepath; + args[i++] = client->tmpexepath; if (use_strace) args[i++] = "--strace"; if (use_ftrace) args[i++] = "--ftrace"; // run program, tee'ing stderr to both log and client - DEBUF("spawning %s", client->exepath); + DEBUF("spawning %s", client->tmpexepath); sigemptyset(&sigmask); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGCHLD); @@ -528,7 +525,7 @@ RetryOnEtxtbsyRaceCondition: WARNF("%s failed to spawn on %s due because either (1) the ETXTBSY race " "condition kept happening or (2) the program in question actually " "is crashing with SIGVTALRM, without printing anything to out/err!", - exename, g_hostname); + origname, g_hostname); pthread_exit(0); } if (usleep(1u << etxtbsy_tries)) { @@ -548,12 +545,13 @@ RetryOnEtxtbsyRaceCondition: posix_spawn_file_actions_adddup2(&spawnfila, g_bogusfd, 0); posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 1); posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 2); - err = posix_spawn(&client->pid, exe, &spawnfila, &spawnattr, args, environ); + err = posix_spawn(&client->pid, client->tmpexepath, &spawnfila, &spawnattr, + args, environ); if (err) { if (err == ETXTBSY) { goto RetryOnEtxtbsyRaceCondition; } - WARNF("%s failed to spawn on %s due to %s", exename, g_hostname, + WARNF("%s failed to spawn on %s due to %s", client->tmpexepath, g_hostname, strerror(err)); pthread_exit(0); } @@ -561,13 +559,13 @@ RetryOnEtxtbsyRaceCondition: posix_spawnattr_destroy(&spawnattr); Close(&client->pipe[1]); - DEBUF("communicating %s[%d]", exename, client->pid); + DEBUF("communicating %s[%d]", origname, client->pid); struct timespec deadline = timespec_add(timespec_real(), timespec_fromseconds(DEATH_CLOCK_SECONDS)); for (;;) { if (g_interrupted) { WARNF("killing %d %s and hanging up %d due to interrupt", client->fd, - exename, client->pid); + origname, client->pid); HangupClientAndTerminateJob: SendProgramOutput(client); mbedtls_ssl_close_notify(&ezssl); @@ -577,7 +575,7 @@ RetryOnEtxtbsyRaceCondition: } struct timespec now = timespec_real(); if (timespec_cmp(now, deadline) >= 0) { - WARNF("killing %s (pid %d) which timed out after %d seconds", exename, + WARNF("killing %s (pid %d) which timed out after %d seconds", origname, client->pid, DEATH_CLOCK_SECONDS); goto HangupClientAndTerminateJob; } @@ -594,7 +592,7 @@ RetryOnEtxtbsyRaceCondition: continue; } else { WARNF("killing %d %s and hanging up %d because poll failed", client->fd, - exename, client->pid); + origname, client->pid); goto HangupClientAndTerminateJob; } } @@ -604,37 +602,37 @@ RetryOnEtxtbsyRaceCondition: char buf[512]; received = mbedtls_ssl_read(&ezssl, buf, sizeof(buf)); if (!received) { - WARNF("%s client disconnected so killing worker %d", exename, + WARNF("%s client disconnected so killing worker %d", origname, client->pid); goto TerminateJob; } if (received > 0) { - WARNF("%s client sent %d unexpected bytes so killing job", exename, + WARNF("%s client sent %d unexpected bytes so killing job", origname, received); goto HangupClientAndTerminateJob; } if (received == MBEDTLS_ERR_SSL_WANT_READ) { // EAGAIN SO_RCVTIMEO - WARNF("%s (pid %d) is taking a really long time", exename, + WARNF("%s (pid %d) is taking a really long time", origname, client->pid); continue; } WARNF("client ssl read failed with -0x%04x (%s) so killing %s", - -received, GetTlsError(received), exename); + -received, GetTlsError(received), origname); goto TerminateJob; } if (fds[1].revents) { char buf[512]; ssize_t got = read(client->pipe[0], buf, sizeof(buf)); if (got == -1) { - WARNF("got %s reading %s output", strerror(errno), exename); + WARNF("got %s reading %s output", strerror(errno), origname); goto HangupClientAndTerminateJob; } if (!got) { - VERBF("got eof reading %s output", exename); + VERBF("got eof reading %s output", origname); Close(&client->pipe[0]); break; } - DEBUF("got %ld bytes reading %s output", got, exename); + DEBUF("got %ld bytes reading %s output", got, origname); appendd(&client->output, buf, got); } } @@ -645,7 +643,7 @@ WaitAgain: int wrc = wait4(client->pid, &wstatus, 0, &rusage); if (wrc == -1) { if (errno == EINTR) { - WARNF("waitpid interrupted; killing %s pid %d", exename, client->pid); + WARNF("waitpid interrupted; killing %s pid %d", origname, client->pid); kill(client->pid, SIGINT); goto WaitAgain; } @@ -657,12 +655,12 @@ WaitAgain: int exitcode; if (WIFEXITED(wstatus)) { if (WEXITSTATUS(wstatus)) { - WARNF("%s on %s exited with %d", exename, g_hostname, + WARNF("%s on %s exited with %d", origname, g_hostname, WEXITSTATUS(wstatus)); appendf(&client->output, "------ %s %s $?=%d (0x%08x) ------\n", - g_hostname, exename, WEXITSTATUS(wstatus), wstatus); + g_hostname, origname, WEXITSTATUS(wstatus), wstatus); } else { - VERBF("%s on %s exited with %d", exename, g_hostname, + VERBF("%s on %s exited with %d", origname, g_hostname, WEXITSTATUS(wstatus)); } exitcode = WEXITSTATUS(wstatus); @@ -672,13 +670,13 @@ WaitAgain: client->output = 0; goto RetryOnEtxtbsyRaceCondition; } - WARNF("%s on %s terminated with %s", exename, g_hostname, + WARNF("%s on %s terminated with %s", origname, g_hostname, strsignal(WTERMSIG(wstatus))); exitcode = 128 + WTERMSIG(wstatus); appendf(&client->output, "------ %s %s $?=%s (0x%08x) ------\n", g_hostname, - exename, strsignal(WTERMSIG(wstatus)), wstatus); + origname, strsignal(WTERMSIG(wstatus)), wstatus); } else { - WARNF("%s on %s died with wait status 0x%08x", exename, g_hostname, + WARNF("%s on %s died with wait status 0x%08x", origname, g_hostname, wstatus); exitcode = 127; } @@ -689,9 +687,9 @@ WaitAgain: SendProgramOutput(client); SendExitMessage(exitcode); mbedtls_ssl_close_notify(&ezssl); - if (etxtbsy_tries) { - VERBF("encountered %d ETXTBSY race conditions spawning %s", etxtbsy_tries, - exename); + if (etxtbsy_tries > 1) { + WARNF("encountered %d ETXTBSY race conditions spawning %s", + etxtbsy_tries - 1, origname); } pthread_exit(0); }