Merge pull request #124157 from nh2/libredirect-children

libredirect: Fix redirects not working for subprocesses
This commit is contained in:
Pascal Bach 2021-09-04 13:19:08 +02:00 committed by GitHub
commit 1871c113f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 2 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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