summary refs log tree commit diff
diff options
context:
space:
mode:
authorPascal Bach <pascal.bach@nextrem.ch>2021-09-04 13:19:08 +0200
committerGitHub <noreply@github.com>2021-09-04 13:19:08 +0200
commit1871c113f1d44f8e8922586b333e11d174bd19ca (patch)
treede3b09ce3d9b97d2b40f376c8c13879debef49d2
parent90982af6a14f75b148f98ac6cc09c569b14c0b61 (diff)
parentfc5196c2f089e1483429aecd8dff56387a444e6b (diff)
downloadnixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar.gz
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar.bz2
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar.lz
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar.xz
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.tar.zst
nixpkgs-1871c113f1d44f8e8922586b333e11d174bd19ca.zip
Merge pull request #124157 from nh2/libredirect-children
libredirect: Fix redirects not working for subprocesses
-rw-r--r--pkgs/build-support/libredirect/default.nix13
-rw-r--r--pkgs/build-support/libredirect/libredirect.c9
-rw-r--r--pkgs/build-support/libredirect/test.c15
3 files changed, 35 insertions, 2 deletions
diff --git a/pkgs/build-support/libredirect/default.nix b/pkgs/build-support/libredirect/default.nix
index 4678d35442f..42525ec98a7 100644
--- a/pkgs/build-support/libredirect/default.nix
+++ b/pkgs/build-support/libredirect/default.nix
@@ -14,6 +14,8 @@ stdenv.mkDerivation rec {
   outputs = ["out" "hook"];
 
   buildPhase = ''
+    runHook preBuild
+
     $CC -Wall -std=c99 -O3 -fPIC -ldl -shared \
       ${lib.optionalString stdenv.isDarwin "-Wl,-install_name,$out/lib/$libName"} \
       -o "$libName" \
@@ -22,9 +24,18 @@ stdenv.mkDerivation rec {
     if [ -n "$doInstallCheck" ]; then
       $CC -Wall -std=c99 -O3 test.c -o test
     fi
+
+    runHook postBuild
   '';
 
+  # We want to retain debugging info to be able to use GDB on libredirect.so
+  # to more easily investigate which function overrides are missing or why
+  # existing ones do not have the intended effect.
+  dontStrip = true;
+
   installPhase = ''
+    runHook preInstall
+
     install -vD "$libName" "$out/lib/$libName"
 
     mkdir -p "$hook/nix-support"
@@ -36,6 +47,8 @@ stdenv.mkDerivation rec {
     export LD_PRELOAD="$out/lib/$libName"
     ''}
     SETUP_HOOK
+
+    runHook postInstall
   '';
 
   doInstallCheck = true;
diff --git a/pkgs/build-support/libredirect/libredirect.c b/pkgs/build-support/libredirect/libredirect.c
index dfa2978e9f4..5b0ef485670 100644
--- a/pkgs/build-support/libredirect/libredirect.c
+++ b/pkgs/build-support/libredirect/libredirect.c
@@ -17,15 +17,22 @@ static int nrRedirects = 0;
 static char * from[MAX_REDIRECTS];
 static char * to[MAX_REDIRECTS];
 
+static int isInitialized = 0;
+
 // FIXME: might run too late.
 static void init() __attribute__((constructor));
 
 static void init()
 {
+    if (isInitialized) return;
+
     char * spec = getenv("NIX_REDIRECTS");
     if (!spec) return;
 
-    unsetenv("NIX_REDIRECTS");
+    // Ensure we only run this code once.
+    // We do not do `unsetenv("NIX_REDIRECTS")` to ensure that redirects
+    // also get initialized for subprocesses.
+    isInitialized = 1;
 
     char * spec2 = malloc(strlen(spec) + 1);
     strcpy(spec2, spec);
diff --git a/pkgs/build-support/libredirect/test.c b/pkgs/build-support/libredirect/test.c
index 722d1303771..853f26bb520 100644
--- a/pkgs/build-support/libredirect/test.c
+++ b/pkgs/build-support/libredirect/test.c
@@ -10,6 +10,7 @@
 #include <sys/wait.h>
 
 #define TESTPATH "/foo/bar/test"
+#define SUBTEST "./test sub"
 
 extern char **environ;
 
@@ -36,7 +37,11 @@ void test_system(void) {
     assert(system(TESTPATH) == 0);
 }
 
-int main(void)
+void test_subprocess(void) {
+    assert(system(SUBTEST) == 0);
+}
+
+int main(int argc, char *argv[])
 {
     FILE *testfp;
     int testfd;
@@ -56,6 +61,14 @@ int main(void)
 
     test_spawn();
     test_system();
+
+    // Only run subprocess if no arguments are given
+    // as the subprocess will be called without argument
+    // otherwise we will have infinite recursion
+    if (argc == 1) {
+        test_subprocess();
+    }
+
     test_execv();
 
     /* If all goes well, this is never reached because test_execv() replaces