From 34dd1c68f877912290fcad4bb8d4d3c0035ef5e6 Mon Sep 17 00:00:00 2001 From: aszlig Date: Mon, 12 Nov 2018 10:48:15 +0100 Subject: [PATCH] libredirect: Add a small test This is just a sanity check on whether the library correctly wraps the syscalls and it's using the "true" executable for posix_spawn() and execv(). The installCheckPhase is not executed if we are cross-compiling, so this shouldn't break cross-compilation. One thing I'm not actually sure is whether ${coreutils}/bin/true is universally available on all the platforms, nor whether all the functions we use in the test are available, but we can still fix that after we've found out about that. Signed-off-by: aszlig --- pkgs/build-support/libredirect/default.nix | 22 +++++++- pkgs/build-support/libredirect/test.c | 59 ++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 pkgs/build-support/libredirect/test.c diff --git a/pkgs/build-support/libredirect/default.nix b/pkgs/build-support/libredirect/default.nix index fec659ff5fd..09a3da6729a 100644 --- a/pkgs/build-support/libredirect/default.nix +++ b/pkgs/build-support/libredirect/default.nix @@ -1,21 +1,39 @@ -{ stdenv }: +{ stdenv, coreutils }: stdenv.mkDerivation { name = "libredirect-0"; - unpackPhase = "cp ${./libredirect.c} libredirect.c"; + unpackPhase = '' + cp ${./libredirect.c} libredirect.c + cp ${./test.c} test.c + ''; shlibext = stdenv.targetPlatform.extensions.sharedLibrary; buildPhase = '' $CC -Wall -std=c99 -O3 -shared libredirect.c \ -o "libredirect$shlibext" -fPIC -ldl + + if [ -n "$doInstallCheck" ]; then + $CC -Wall -std=c99 -O3 test.c -o test + fi ''; installPhase = '' install -vD "libredirect$shlibext" "$out/lib/libredirect$shlibext" ''; + doInstallCheck = true; + + installCheckPhase = if stdenv.isDarwin then '' + NIX_REDIRECTS="/foo/bar/test=${coreutils}/bin/true" \ + DYLD_INSERT_LIBRARIES="$out/lib/libredirect$shlibext" \ + DYLD_FORCE_FLAT_NAMESPACE=1 ./test + '' else '' + NIX_REDIRECTS="/foo/bar/test=${coreutils}/bin/true" \ + LD_PRELOAD="$out/lib/libredirect$shlibext" ./test + ''; + meta = { platforms = stdenv.lib.platforms.unix; description = "An LD_PRELOAD library to intercept and rewrite the paths in glibc calls"; diff --git a/pkgs/build-support/libredirect/test.c b/pkgs/build-support/libredirect/test.c new file mode 100644 index 00000000000..b57664db3c1 --- /dev/null +++ b/pkgs/build-support/libredirect/test.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TESTPATH "/foo/bar/test" + +extern char **environ; + +void test_spawn(void) { + pid_t pid; + int ret; + posix_spawn_file_actions_t file_actions; + char *argv[] = {"true", NULL}; + + assert(posix_spawn_file_actions_init(&file_actions) == 0); + + ret = posix_spawn(&pid, TESTPATH, &file_actions, NULL, argv, environ); + + assert(ret == 0); + assert(waitpid(pid, NULL, 0) != -1); +} + +void test_execv(void) { + char *argv[] = {"true", NULL}; + assert(execv(TESTPATH, argv) == 0); +} + +int main(void) +{ + FILE *testfp; + int testfd; + struct stat testsb; + + testfp = fopen(TESTPATH, "r"); + assert(testfp != NULL); + fclose(testfp); + + testfd = open(TESTPATH, O_RDONLY); + assert(testfd != -1); + close(testfd); + + assert(access(TESTPATH, X_OK) == 0); + + assert(stat(TESTPATH, &testsb) != -1); + + test_spawn(); + test_execv(); + + /* If all goes well, this is never reached because test_execv() replaces + * the current process. + */ + return 0; +}