mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Enable argv[0] tests in more places (#1061)
Now we do them for assimilated binaries (except on OpenBSD or XNU non-Silicon), for XnuSilicon, and for binaries with the preserve- argv[0] auxv flag set. We check whether to pass the argv[0] value at the test site rather than the Child site. We move a lot of the test initialization into Child in the non-child case, in order to get at the pre-init value of `__program_executable_name`. Finally, we print out info about what we are skipping.
This commit is contained in:
parent
b09096691a
commit
636bc4007b
4 changed files with 41 additions and 25 deletions
|
@ -947,6 +947,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp,
|
|||
} else if (SupportsNetbsd() && !os && ap[0] == AT_EXECFN_NETBSD) {
|
||||
os = NETBSD;
|
||||
} else if (SupportsLinux() && ap[0] == AT_FLAGS) {
|
||||
// TODO(mrdomino): maybe set/insert this when we are called as "ape -".
|
||||
arg0 = !!(ap[1] & AT_FLAGS_PRESERVE_ARGV0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "libc/errno.h"
|
||||
#include "libc/fmt/libgen.h"
|
||||
#include "libc/intrin/getenv.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
|
@ -260,5 +261,6 @@ static void InitProgramExecutableName(void) {
|
|||
*/
|
||||
char *GetProgramExecutableName(void) {
|
||||
cosmo_once(&g_prog.once, InitProgramExecutableName);
|
||||
STRACE("GetProgramExecutableName() → %#s", __program_executable_name);
|
||||
return __program_executable_name;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_FLAGS 8
|
||||
#define AT_FLAGS_PRESERVE_ARGV0_BIT 0
|
||||
#define AT_FLAGS_PRESERVE_ARGV0 (1 << AT_FLAGS_PRESERVE_ARGV0_BIT)
|
||||
#define AT_ENTRY 9
|
||||
|
||||
COSMOPOLITAN_C_START_
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "libc/serialize.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
|
@ -34,14 +35,16 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
|
||||
static char *self;
|
||||
static bool skiptests;
|
||||
static bool loaded, skiptests, skiparg0;
|
||||
|
||||
void SetUpOnce(void) {
|
||||
self = GetProgramExecutableName();
|
||||
testlib_enable_tmp_setup_teardown();
|
||||
if (IsMetal()) {
|
||||
skiptests = true;
|
||||
} else if (IsOpenbsd() || (IsXnu() && !IsXnuSilicon())) {
|
||||
} else if (IsWindows()) {
|
||||
/* do all tests */
|
||||
} else if (!loaded) {
|
||||
ASSERT_STRNE(self, "");
|
||||
ASSERT_SYS(0, 3, open(self, O_RDONLY));
|
||||
char buf[8];
|
||||
|
@ -50,15 +53,24 @@ void SetUpOnce(void) {
|
|||
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;
|
||||
// GetProgramExecutableName does not work reliably for assimilated
|
||||
// OpenBSD or XNU binaries.
|
||||
skiptests = IsOpenbsd() || (IsXnu() && !IsXnuSilicon());
|
||||
}
|
||||
} else {
|
||||
skiparg0 =
|
||||
!(IsXnuSilicon() || (getauxval(AT_FLAGS) & AT_FLAGS_PRESERVE_ARGV0));
|
||||
}
|
||||
fprintf(stderr, loaded ? "loaded\n" : "not loaded\n");
|
||||
if (skiptests) {
|
||||
fprintf(stderr, "skipping most GetProgramExecutableName tests\n");
|
||||
} else if (skiparg0) {
|
||||
fprintf(stderr, "skipping argv[0] tests\n");
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((__constructor__)) static void Child(int argc, char *argv[]) {
|
||||
loaded = !!__program_executable_name;
|
||||
if (argc >= 2 && !strcmp(argv[1], "Child")) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
|
@ -72,15 +84,11 @@ __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 (argc >= 4) {
|
||||
if (strcmp(argv[3], argv[0])) {
|
||||
exit(124);
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +106,8 @@ TEST(GetProgramExecutableName, ofThisFile) {
|
|||
TEST(GetProgramExecutableName, nullEnv) {
|
||||
if (skiptests) return;
|
||||
SPAWN(fork);
|
||||
execve(self, (char *[]){self, "Child", self, self, 0}, (char *[]){0});
|
||||
execve(self, (char *[]){self, "Child", self, skiparg0 ? 0 : self, 0},
|
||||
(char *[]){0});
|
||||
abort();
|
||||
EXITS(0);
|
||||
}
|
||||
|
@ -106,7 +115,8 @@ TEST(GetProgramExecutableName, nullEnv) {
|
|||
TEST(GetProramExecutableName, weirdArgv0NullEnv) {
|
||||
if (skiptests) return;
|
||||
SPAWN(fork);
|
||||
execve(self, (char *[]){"hello", "Child", self, "hello", 0}, (char *[]){0});
|
||||
execve(self, (char *[]){"hello", "Child", self, skiparg0 ? 0 : "hello", 0},
|
||||
(char *[]){0});
|
||||
abort();
|
||||
EXITS(0);
|
||||
}
|
||||
|
@ -133,11 +143,12 @@ TEST(GetProgramExecutableName, movedSelf) {
|
|||
ASSERT_NE(NULL, getcwd(buf, BUFSIZ - 5));
|
||||
stpcpy(buf + strlen(buf), "/test");
|
||||
SPAWN(fork);
|
||||
execve(buf, (char *[]){"hello", "Child", buf, "hello", 0}, (char *[]){0});
|
||||
execve(buf, (char *[]){"hello", "Child", buf, skiparg0 ? 0 : "hello", 0},
|
||||
(char *[]){0});
|
||||
abort();
|
||||
EXITS(0);
|
||||
SPAWN(fork);
|
||||
execve("./test", (char *[]){"hello", "Child", buf, "hello", 0},
|
||||
execve("./test", (char *[]){"hello", "Child", buf, skiparg0 ? 0 : "hello", 0},
|
||||
(char *[]){0});
|
||||
abort();
|
||||
EXITS(0);
|
||||
|
|
Loading…
Reference in a new issue