From b02d13ccde8d87349fa8b503dff22f08a7308133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C5=8Dshin?= Date: Sun, 31 Dec 2023 14:53:15 -0500 Subject: [PATCH] Re-enable/fix non-argv[0] exe name tests (#1046) --- .../calls/getprogramexecutablename_test.c | 52 ++++++++++++++----- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/test/libc/calls/getprogramexecutablename_test.c b/test/libc/calls/getprogramexecutablename_test.c index 13f475163..99294ce95 100644 --- a/test/libc/calls/getprogramexecutablename_test.c +++ b/test/libc/calls/getprogramexecutablename_test.c @@ -17,21 +17,42 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/metalfile.internal.h" #include "libc/dce.h" #include "libc/limits.h" #include "libc/runtime/runtime.h" +#include "libc/serialize.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/ok.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" static char *self; +static bool skiptests; void SetUpOnce(void) { self = GetProgramExecutableName(); testlib_enable_tmp_setup_teardown(); + if (IsMetal()) { + skiptests = true; + } else if (IsOpenbsd() || (IsXnu() && !IsXnuSilicon())) { + ASSERT_STRNE(self, ""); + ASSERT_SYS(0, 3, open(self, O_RDONLY)); + char buf[8]; + ASSERT_SYS(0, 8, pread(3, buf, 8, 0)); + ASSERT_SYS(0, 0, close(3)); + if (READ64LE(buf) != READ64LE("MZqFpD='") && + READ64LE(buf) != READ64LE("jartsr='") && + READ64LE(buf) != READ64LE("APEDBG='")) { + fprintf(stderr, + "we appear to be running as an assimilated binary on OpenBSD or " + "x86_64 XNU;\nGetProgramExecutableName is unreliable here\n"); + skiptests = true; + } + } } __attribute__((__constructor__)) static void Child(int argc, char *argv[]) { @@ -39,6 +60,12 @@ __attribute__((__constructor__)) static void Child(int argc, char *argv[]) { if (strcmp(argv[2], GetProgramExecutableName())) { exit(123); } + if (!IsXnuSilicon()) exit(0); + /* TODO(mrdomino): argv[0] tests only pass on XnuSilicon right now because + __sys_execve fails there, so the ape loader is used. + the correct check is "we have been invoked either as an + assimilated binary or via the ape loader, and not via a + raw __sys_execve." */ if (strcmp(argv[3], argv[0])) { exit(124); } @@ -47,18 +74,17 @@ __attribute__((__constructor__)) static void Child(int argc, char *argv[]) { } TEST(GetProgramExecutableName, ofThisFile) { - EXPECT_EQ('/', *self); - EXPECT_TRUE(!!strstr(self, "getprogramexecutablename_test")); + if (IsMetal()) { + EXPECT_STREQ(self, APE_COM_NAME); + } else { + EXPECT_EQ('/', *self); + EXPECT_TRUE(!!strstr(self, "getprogramexecutablename_test")); + EXPECT_SYS(0, 0, access(self, X_OK)); + } } -/* TODO(mrdomino): these tests only pass on XnuSilicon right now because - __sys_execve fails there, so the ape loader is used. - the correct check here is "we have been invoked either - as an assimilated binary or via the ape loader, and not - via a raw __sys_execve." */ - TEST(GetProgramExecutableName, nullEnv) { - if (!IsXnuSilicon()) return; + if (skiptests) return; SPAWN(fork); execve(self, (char *[]){self, "Child", self, self, 0}, (char *[]){0}); abort(); @@ -66,7 +92,7 @@ TEST(GetProgramExecutableName, nullEnv) { } TEST(GetProramExecutableName, weirdArgv0NullEnv) { - if (!IsXnuSilicon()) return; + if (skiptests) return; SPAWN(fork); execve(self, (char *[]){"hello", "Child", self, "hello", 0}, (char *[]){0}); abort(); @@ -74,7 +100,7 @@ TEST(GetProramExecutableName, weirdArgv0NullEnv) { } TEST(GetProgramExecutableName, weirdArgv0CosmoVar) { - if (!IsXnuSilicon()) return; + if (skiptests) return; char buf[32 + PATH_MAX]; stpcpy(stpcpy(buf, "COSMOPOLITAN_PROGRAM_EXECUTABLE="), self); SPAWN(fork); @@ -85,7 +111,7 @@ TEST(GetProgramExecutableName, weirdArgv0CosmoVar) { } TEST(GetProgramExecutableName, weirdArgv0WrongCosmoVar) { - if (!IsXnuSilicon()) return; + if (skiptests) return; char *bad = "COSMOPOLITAN_PROGRAM_EXECUTABLE=hi"; SPAWN(fork); execve(self, (char *[]){"hello", "Child", self, "hello", 0}, @@ -95,7 +121,7 @@ TEST(GetProgramExecutableName, weirdArgv0WrongCosmoVar) { } TEST(GetProgramExecutableName, movedSelf) { - if (!IsXnuSilicon()) return; + if (skiptests) return; char buf[BUFSIZ]; ASSERT_SYS(0, 3, open(GetProgramExecutableName(), O_RDONLY)); ASSERT_SYS(0, 4, creat("test", 0755));