diff --git a/pkgs/clan-cli/tests/getpwnam-preload.c b/pkgs/clan-cli/tests/getpwnam-preload.c index 828007ed1..d671116ed 100644 --- a/pkgs/clan-cli/tests/getpwnam-preload.c +++ b/pkgs/clan-cli/tests/getpwnam-preload.c @@ -6,12 +6,44 @@ #include #include +#ifdef __APPLE__ +#include +#include +#endif + +#ifdef __APPLE__ +struct dyld_interpose { + const void *replacement; + const void *replacee; +}; +#define WRAPPER(ret, name) static ret _fakeroot_wrapper_##name +#define WRAPPER_DEF(name) \ + __attribute__(( \ + used)) static struct dyld_interpose _fakeroot_interpose_##name \ + __attribute__((section("__DATA,__interpose"))) = { \ + &_fakeroot_wrapper_##name, &name}; +#else +#define WRAPPER(ret, name) ret name +#define WRAPPER_DEF(name) +#endif + typedef struct passwd *(*getpwnam_type)(const char *name); -struct passwd *getpwnam(const char *name) { +WRAPPER(struct passwd *, getpwnam)(const char *name) { struct passwd *pw; - getpwnam_type orig_getpwnam; - orig_getpwnam = (getpwnam_type)dlsym(RTLD_NEXT, "getpwnam"); +#ifdef __APPLE__ +#define orig_getpwnam(name) getpwnam(name) +#else + static getpwnam_type orig_getpwnam = NULL; + + if (!orig_getpwnam) { + orig_getpwnam = (getpwnam_type)dlsym(RTLD_NEXT, "getpwnam"); + if (!orig_getpwnam) { + fprintf(stderr, "dlsym error: %s\n", dlerror()); + exit(1); + } + } +#endif pw = orig_getpwnam(name); if (pw) { @@ -21,6 +53,17 @@ struct passwd *getpwnam(const char *name) { exit(1); } pw->pw_shell = strdup(shell); + fprintf(stderr, "getpwnam: %s -> %s\n", name, pw->pw_shell); } return pw; } +WRAPPER_DEF(getpwnam) + +#ifdef __APPLE__ +// sandbox_init(3) doesn't work in nix build sandbox +WRAPPER(int, sandbox_init)(const char *profile, uint64_t flags, void *handle) { + return 0; +} +WRAPPER_DEF(sandbox_init) +#else +#endif diff --git a/pkgs/clan-cli/tests/test_ssh_remote.py b/pkgs/clan-cli/tests/test_ssh_remote.py index 22d2c546f..18d9b4c20 100644 --- a/pkgs/clan-cli/tests/test_ssh_remote.py +++ b/pkgs/clan-cli/tests/test_ssh_remote.py @@ -1,4 +1,5 @@ import contextlib +import sys from collections.abc import Generator from typing import Any, NamedTuple @@ -127,6 +128,10 @@ def test_parse_ssh_options() -> None: assert host.ssh_options["StrictHostKeyChecking"] == "yes" +is_darwin = sys.platform == "darwin" + + +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run(hosts: list[Host], runtime: AsyncRuntime) -> None: for host in hosts: proc = runtime.async_run( @@ -135,6 +140,7 @@ def test_run(hosts: list[Host], runtime: AsyncRuntime) -> None: assert proc.wait().result.stdout == "hello\n" +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run_environment(hosts: list[Host], runtime: AsyncRuntime) -> None: for host in hosts: proc = runtime.async_run( @@ -157,6 +163,7 @@ def test_run_environment(hosts: list[Host], runtime: AsyncRuntime) -> None: assert "env_var=true" in p2.wait().result.stdout +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run_no_shell(hosts: list[Host], runtime: AsyncRuntime) -> None: for host in hosts: proc = runtime.async_run( @@ -165,6 +172,7 @@ def test_run_no_shell(hosts: list[Host], runtime: AsyncRuntime) -> None: assert proc.wait().result.stdout == "hello\n" +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run_function(hosts: list[Host], runtime: AsyncRuntime) -> None: def some_func(h: Host) -> bool: p = h.run(["echo", "hello"]) @@ -175,6 +183,7 @@ def test_run_function(hosts: list[Host], runtime: AsyncRuntime) -> None: assert proc.wait().result +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_timeout(hosts: list[Host], runtime: AsyncRuntime) -> None: for host in hosts: proc = runtime.async_run( @@ -184,6 +193,7 @@ def test_timeout(hosts: list[Host], runtime: AsyncRuntime) -> None: assert isinstance(error, ClanCmdTimeoutError) +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run_exception(hosts: list[Host], runtime: AsyncRuntime) -> None: for host in hosts: proc = runtime.async_run( @@ -203,6 +213,7 @@ def test_run_exception(hosts: list[Host], runtime: AsyncRuntime) -> None: raise AssertionError(msg) +@pytest.mark.skipif(is_darwin, reason="preload doesn't work on darwin") def test_run_function_exception(hosts: list[Host], runtime: AsyncRuntime) -> None: def some_func(h: Host) -> CmdOut: return h.run_local(["exit 1"], RunOpts(shell=True))