Merge pull request #50246 from aszlig/libredirect-darwin

libredirect: Add support for Darwin
This commit is contained in:
Eelco Dolstra 2018-11-12 12:21:38 +01:00 committed by GitHub
commit f7d5b76e03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 8 deletions

View File

@ -1,19 +1,41 @@
{ 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
'';
buildPhase =
''
gcc -Wall -std=c99 -O3 -shared libredirect.c -o libredirect.so -fPIC -ldl
'';
shlibext = stdenv.targetPlatform.extensions.sharedLibrary;
installPhase = "mkdir -p $out/lib; cp libredirect.so $out/lib";
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.linux;
platforms = stdenv.lib.platforms.unix;
description = "An LD_PRELOAD library to intercept and rewrite the paths in glibc calls";
longDescription = ''
libredirect is an LD_PRELOAD library to intercept and rewrite the paths in

View File

@ -0,0 +1,59 @@
#include <assert.h>
#include <fcntl.h>
#include <spawn.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#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;
}