From a3deef70c24f581c6a0c5df7cb36d4e366bd163f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jan 2024 08:25:37 -0800 Subject: [PATCH] Release Cosmopolitan v3.2 --- ape/loader.c | 13 ++++--- libc/calls/isqemu.c | 34 +++++++++++++++++++ libc/dce.h | 2 ++ libc/integral/normalize.inc | 4 +-- test/libc/calls/getcwd_test.c | 3 +- .../calls/getprogramexecutablename_test.c | 17 +++++++++- test/libc/calls/madvise_test.c | 5 ++- test/libc/calls/writev_test.c | 7 ++-- test/libc/stdio/tmpfile_test.c | 2 +- tool/cosmocc/README.md | 2 +- tool/cosmocc/package.sh | 4 +-- 11 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 libc/calls/isqemu.c diff --git a/ape/loader.c b/ape/loader.c index 6bbdf8af5..ca582bd4a 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -597,8 +597,9 @@ static char FindCommand(struct PathSearcher *ps) { return SearchPath(ps); } -static char *Commandv(struct PathSearcher *ps, int os, const char *name, - const char *syspath) { +static char *Commandv(struct PathSearcher *ps, int os, char *name, + const char *syspath, int may_path_search) { + if (!may_path_search) return name; ps->os = os; ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin"; if (!(ps->namelen = StrLen((ps->name = name)))) return 0; @@ -978,6 +979,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, } /* we can load via shell, shebang, or binfmt_misc */ + int may_path_search = 1; if ((literally = argc >= 3 && !StrCmp(argv[1], "-"))) { /* if the first argument is a hyphen then we give the user the power to change argv[0] or omit it entirely. most operating @@ -986,12 +988,12 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, prog = (char *)sp[3]; argc = sp[3] = sp[0] - 3; argv = (char **)((sp += 3) + 1); + may_path_search = 0; } else if (argc < 2) { ShowUsage(os, 2, 1); } else { if (argv[1][0] == '-') { - rc = !(argv[1][1] == 'h' && !argv[1][2]) || !StrCmp(argv[1] + 1, - "-help"); + rc = !(argv[1][1] == 'h' && !argv[1][2]) || !StrCmp(argv[1] + 1, "-help"); ShowUsage(os, 1 + rc, rc); } prog = (char *)sp[2]; @@ -1027,7 +1029,8 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, } /* resolve path of executable and read its first page */ - if (!(exe = Commandv(&M->ps, os, prog, GetEnv(envp, "PATH")))) { + if (!(exe = Commandv(&M->ps, os, prog, GetEnv(envp, "PATH"), + may_path_search))) { Pexit(os, prog, 0, "not found (maybe chmod +x or ./ needed)"); } else if ((fd = Open(exe, O_RDONLY, 0, os)) < 0) { Pexit(os, exe, fd, "open"); diff --git a/libc/calls/isqemu.c b/libc/calls/isqemu.c new file mode 100644 index 000000000..9d565e7bd --- /dev/null +++ b/libc/calls/isqemu.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2024 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "ape/sections.internal.h" +#include "libc/calls/calls.h" +#include "libc/calls/syscall-sysv.internal.h" +#include "libc/errno.h" + +/** + * Returns true if process is running under qemu-x86_64 or qemu-x86_64. + */ +int IsQemu(void) { + // qemu doesn't validate the advice argument + // we could also check if __getcwd(0, 0) raises efault + int e = errno; + int r = !sys_madvise(__executable_start, 16384, 127); + errno = e; + return r; +} diff --git a/libc/dce.h b/libc/dce.h index faabcac32..9ce486947 100644 --- a/libc/dce.h +++ b/libc/dce.h @@ -121,6 +121,8 @@ COSMOPOLITAN_C_START_ extern const int __hostos; +int IsQemu(void); + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* _COSMO_SOURCE */ diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 941cdee8b..3f8d2dd75 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -3,8 +3,8 @@ #endif #define __COSMOPOLITAN_MAJOR__ 3 -#define __COSMOPOLITAN_MINOR__ 1 -#define __COSMOPOLITAN_PATCH__ 3 +#define __COSMOPOLITAN_MINOR__ 2 +#define __COSMOPOLITAN_PATCH__ 0 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) diff --git a/test/libc/calls/getcwd_test.c b/test/libc/calls/getcwd_test.c index 22666d413..86a17b8ef 100644 --- a/test/libc/calls/getcwd_test.c +++ b/test/libc/calls/getcwd_test.c @@ -20,10 +20,10 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/libgen.h" -#include "libc/serialize.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/mem/gc.internal.h" +#include "libc/serialize.h" #include "libc/str/str.h" #include "libc/testlib/testlib.h" @@ -33,6 +33,7 @@ void SetUpOnce(void) { } TEST(__getcwd, zero) { + if (IsQemu()) return; ASSERT_SYS(ERANGE, -1, __getcwd(0, 0)); } diff --git a/test/libc/calls/getprogramexecutablename_test.c b/test/libc/calls/getprogramexecutablename_test.c index 9a1b4ff59..2665d34eb 100644 --- a/test/libc/calls/getprogramexecutablename_test.c +++ b/test/libc/calls/getprogramexecutablename_test.c @@ -18,7 +18,9 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/metalfile.internal.h" +#include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" #include "libc/limits.h" #include "libc/runtime/runtime.h" @@ -58,7 +60,13 @@ void SetUpOnce(void) { __attribute__((__constructor__)) static void Child(int argc, char *argv[]) { if (argc >= 2 && !strcmp(argv[1], "Child")) { - if (sys_chdir("/")) { + int rc; + if (!IsWindows()) { + rc = sys_chdir("/"); + } else { + rc = sys_chdir_nt("/"); + } + if (rc) { exit(122); } if (strcmp(argv[2], GetProgramExecutableName())) { @@ -105,6 +113,13 @@ TEST(GetProramExecutableName, weirdArgv0NullEnv) { TEST(GetProgramExecutableName, movedSelf) { if (skiptests) return; + if (IsAarch64() && IsQemu()) { + // clang-format off + // TODO(mrdomino): fix: make -j8 m=aarch64 o/aarch64/test/libc/calls/getprogramexecutablename_test.com.ok + // possibly related to the intersection of binfmt_misc and qemu-aarch64 + // clang-format on + return; + } char buf[BUFSIZ]; ASSERT_SYS(0, 3, open(GetProgramExecutableName(), O_RDONLY)); ASSERT_SYS(0, 4, creat("test", 0755)); diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index ed6701307..45947b6e5 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -70,6 +70,7 @@ TEST(madvise, subPages) { TEST(madvise, misalign) { char *p; if (!IsLinux()) return; // most platforms don't care + if (IsQemu()) return; // qemu claims to be linux but doesn't care ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); ASSERT_SYS(EINVAL, -1, madvise(p + 1, FRAMESIZE - 1, MADV_WILLNEED)); @@ -78,6 +79,7 @@ TEST(madvise, misalign) { TEST(madvise, badAdvice) { char *p; + if (IsAarch64() && IsQemu()) return; // qemu doesn't validate advice ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); ASSERT_SYS(EINVAL, -1, madvise(p, FRAMESIZE, 127)); @@ -85,7 +87,8 @@ TEST(madvise, badAdvice) { } TEST(madvise, missingMemory) { - if (!IsLinux()) return; + if (!IsLinux()) return; // most platforms don't care + if (IsQemu()) return; // qemu claims to be linux but doesn't care ASSERT_SYS(ENOMEM, -1, madvise((char *)0x83483838000, FRAMESIZE, MADV_WILLNEED)); } diff --git a/test/libc/calls/writev_test.c b/test/libc/calls/writev_test.c index 6731d17dd..5f7875ff8 100644 --- a/test/libc/calls/writev_test.c +++ b/test/libc/calls/writev_test.c @@ -126,9 +126,8 @@ TEST(writev, empty_stillPerformsIoOperation) { ASSERT_NE(-1, (fd = open("file", O_RDONLY))); errno = 0; EXPECT_SYS(EBADF, -1, writev(fd, iov, ARRAYLEN(iov))); -#ifndef __aarch64__ - // Can't test this due to qemu-aarch64 bug - EXPECT_EQ(-1, writev(fd, NULL, 0)); -#endif + if (!(IsAarch64() && IsQemu())) { + EXPECT_EQ(-1, writev(fd, NULL, 0)); + } EXPECT_NE(-1, close(fd)); } diff --git a/test/libc/stdio/tmpfile_test.c b/test/libc/stdio/tmpfile_test.c index 7e8fc42b8..a7eedea9f 100644 --- a/test/libc/stdio/tmpfile_test.c +++ b/test/libc/stdio/tmpfile_test.c @@ -81,7 +81,7 @@ TEST(tmpfile, test) { } #ifndef __aarch64__ -// TODO(jart): Find way to detect qemu-aarch64 +// TODO(jart): Why does this apply to pi and qemu-aarch64? TEST(tmpfile, renameToRealFile) { if (!(IsLinux() && __is_linux_2_6_23())) return; // need non-ancient linux FILE *f; diff --git a/tool/cosmocc/README.md b/tool/cosmocc/README.md index 39a8f03fe..1b3aa124a 100644 --- a/tool/cosmocc/README.md +++ b/tool/cosmocc/README.md @@ -298,7 +298,7 @@ statements instead, so that Cosmopolitan Libc's system constants will work as expected. Our modifications to GNU GCC are published under the ISC license at . The binaries you see here were first published at - which + which is regularly updated. ## Legal diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 306659042..5b9ef866e 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -89,10 +89,10 @@ fetch() { OLD=$PWD cd "$OUTDIR/" if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.29/aarch64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.30/aarch64-gcc.zip unzip aarch64-gcc.zip rm -f aarch64-gcc.zip - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.29/x86_64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.30/x86_64-gcc.zip unzip x86_64-gcc.zip rm -f x86_64-gcc.zip fi