From b7d36b8d597df1a9d799fa9d6d8d55137a525570 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Mon, 4 Oct 2021 22:35:09 +0200 Subject: Add golden tests for make-binary-wrapper. To run tests after cloning on linux, use the following: nix-build pkgs/top-level/release.nix -A tests.make-binary-wrapper.x86_64-linux --- pkgs/test/default.nix | 2 + pkgs/test/make-binary-wrapper/add-flags.c | 23 ++++++++ pkgs/test/make-binary-wrapper/argv0.c | 10 ++++ pkgs/test/make-binary-wrapper/basic.c | 9 +++ pkgs/test/make-binary-wrapper/combination.c | 58 ++++++++++++++++++ pkgs/test/make-binary-wrapper/default.nix | 69 ++++++++++++++++++++++ pkgs/test/make-binary-wrapper/env.c | 17 ++++++ pkgs/test/make-binary-wrapper/golden-test-utils.sh | 44 ++++++++++++++ pkgs/test/make-binary-wrapper/prefix.c | 33 +++++++++++ pkgs/test/make-binary-wrapper/suffix.c | 33 +++++++++++ 10 files changed, 298 insertions(+) create mode 100644 pkgs/test/make-binary-wrapper/add-flags.c create mode 100644 pkgs/test/make-binary-wrapper/argv0.c create mode 100644 pkgs/test/make-binary-wrapper/basic.c create mode 100644 pkgs/test/make-binary-wrapper/combination.c create mode 100644 pkgs/test/make-binary-wrapper/default.nix create mode 100644 pkgs/test/make-binary-wrapper/env.c create mode 100644 pkgs/test/make-binary-wrapper/golden-test-utils.sh create mode 100644 pkgs/test/make-binary-wrapper/prefix.c create mode 100644 pkgs/test/make-binary-wrapper/suffix.c (limited to 'pkgs/test') diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index b9f05bdff8d01..acf639b4a46ea 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -35,6 +35,8 @@ with pkgs; macOSSierraShared = callPackage ./macos-sierra-shared {}; + make-binary-wrapper = callPackage ./make-binary-wrapper { inherit makeBinaryWrapper; }; + cross = callPackage ./cross {}; rustCustomSysroot = callPackage ./rust-sysroot {}; diff --git a/pkgs/test/make-binary-wrapper/add-flags.c b/pkgs/test/make-binary-wrapper/add-flags.c new file mode 100644 index 0000000000000..70d43e0bec081 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/add-flags.c @@ -0,0 +1,23 @@ +// makeCWrapper /send/me/flags \ + --add-flags "-x -y -z" \ + --add-flags -abc + +#include +#include + +int main(int argc, char **argv) { + char **argv_tmp = malloc(sizeof(*argv_tmp) * (5 + argc)); + argv_tmp[0] = argv[0]; + argv_tmp[1] = "-x"; + argv_tmp[2] = "-y"; + argv_tmp[3] = "-z"; + argv_tmp[4] = "-abc"; + for (int i = 1; i < argc; ++i) { + argv_tmp[4 + i] = argv[i]; + } + argv_tmp[4 + argc] = NULL; + argv = argv_tmp; + + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} \ No newline at end of file diff --git a/pkgs/test/make-binary-wrapper/argv0.c b/pkgs/test/make-binary-wrapper/argv0.c new file mode 100644 index 0000000000000..8e3e1f2987b5b --- /dev/null +++ b/pkgs/test/make-binary-wrapper/argv0.c @@ -0,0 +1,10 @@ +// makeCWrapper /path/to/some/executable \ + --argv0 alternative-name + +#include +#include + +int main(int argc, char **argv) { + argv[0] = "alternative-name"; + return execv("/path/to/some/executable", argv); +} diff --git a/pkgs/test/make-binary-wrapper/basic.c b/pkgs/test/make-binary-wrapper/basic.c new file mode 100644 index 0000000000000..de366c5196306 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/basic.c @@ -0,0 +1,9 @@ +// makeCWrapper /path/to/executable + +#include +#include + +int main(int argc, char **argv) { + argv[0] = "/path/to/executable"; + return execv("/path/to/executable", argv); +} diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c new file mode 100644 index 0000000000000..925fdf1ccfb4a --- /dev/null +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -0,0 +1,58 @@ +// makeCWrapper /path/to/executable \ + --argv0 my-wrapper \ + --set-default MESSAGE HELLO \ + --prefix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ \ + --add-flags "-x -y -z" \ + --set MESSAGE2 WORLD + +#include +#include +#include + +char *concat3(char *x, char *y, char *z) { + int xn = strlen(x); + int yn = strlen(y); + int zn = strlen(z); + char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + strncpy(res, x, xn); + strncpy(res + xn, y, yn); + strncpy(res + xn + yn, z, zn); + res[xn + yn + zn] = '\0'; + return res; +} + +void set_env_prefix(char *env, char *sep, char *val) { + char *existing = getenv(env); + if (existing) val = concat3(val, sep, existing); + setenv(env, val, 1); + if (existing) free(val); +} + +void set_env_suffix(char *env, char *sep, char *val) { + char *existing = getenv(env); + if (existing) val = concat3(existing, sep, val); + setenv(env, val, 1); + if (existing) free(val); +} + +int main(int argc, char **argv) { + setenv("MESSAGE", "HELLO", 0); + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + putenv("MESSAGE2=WORLD"); + + char **argv_tmp = malloc(sizeof(*argv_tmp) * (4 + argc)); + argv_tmp[0] = argv[0]; + argv_tmp[1] = "-x"; + argv_tmp[2] = "-y"; + argv_tmp[3] = "-z"; + for (int i = 1; i < argc; ++i) { + argv_tmp[3 + i] = argv[i]; + } + argv_tmp[3 + argc] = NULL; + argv = argv_tmp; + + argv[0] = "my-wrapper"; + return execv("/path/to/executable", argv); +} diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix new file mode 100644 index 0000000000000..0b9f7e5abea2e --- /dev/null +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -0,0 +1,69 @@ +{ lib, stdenv, runCommand, makeBinaryWrapper }: + +let + makeGoldenTest = { name, filename }: stdenv.mkDerivation { + name = name; + dontUnpack = true; + buildInputs = [ makeBinaryWrapper ]; + phases = [ "installPhase" ]; + installPhase = '' + source ${./golden-test-utils.sh} + mkdir -p $out/bin + command=$(getInputCommand "${filename}") + eval "$command" > "$out/bin/result" + ''; + passthru = { + assertion = '' + source ${./golden-test-utils.sh} + contents=$(getOutputText "${filename}") + echo "$contents" | diff $out/bin/result - + ''; + }; + }; + tests = { + add-flags = makeGoldenTest { name = "add-flags"; filename = ./add-flags.c; }; + argv0 = makeGoldenTest { name = "argv0"; filename = ./argv0.c; }; + basic = makeGoldenTest { name = "basic"; filename = ./basic.c; }; + combination = makeGoldenTest { name = "combination"; filename = ./combination.c; }; + env = makeGoldenTest { name = "env"; filename = ./env.c; }; + prefix = makeGoldenTest { name = "prefix"; filename = ./prefix.c; }; + suffix = makeGoldenTest { name = "suffix"; filename = ./suffix.c; }; + }; +in runCommand "make-binary-wrapper-test" { + passthru = tests; + meta.platforms = lib.platforms.all; +} '' + validate() { + local name=$1 + local testout=$2 + local assertion=$3 + + echo -n "... $name: " >&2 + + local rc=0 + (out=$testout eval "$assertion") || rc=1 + + if [ "$rc" -eq 0 ]; then + echo "yes" >&2 + else + echo "no" >&2 + fi + + return "$rc" + } + + echo "checking whether makeCWrapper works properly... ">&2 + + fail= + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (_: test: '' + validate "${test.name}" "${test}" ${lib.escapeShellArg test.assertion} || fail=1 + '') tests)} + + if [ "$fail" ]; then + echo "failed" + exit 1 + else + echo "succeeded" + touch $out + fi +'' diff --git a/pkgs/test/make-binary-wrapper/env.c b/pkgs/test/make-binary-wrapper/env.c new file mode 100644 index 0000000000000..89f1f496b3497 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/env.c @@ -0,0 +1,17 @@ +// makeCWrapper /hello/world \ + --set PART1 HELLO \ + --set-default PART2 WORLD \ + --unset SOME_OTHER_VARIABLE \ + --set PART3 $'"!!\n"' + +#include +#include + +int main(int argc, char **argv) { + putenv("PART1=HELLO"); + setenv("PART2", "WORLD", 0); + unsetenv("SOME_OTHER_VARIABLE"); + putenv("PART3=\"!!\n\""); + argv[0] = "/hello/world"; + return execv("/hello/world", argv); +} \ No newline at end of file diff --git a/pkgs/test/make-binary-wrapper/golden-test-utils.sh b/pkgs/test/make-binary-wrapper/golden-test-utils.sh new file mode 100644 index 0000000000000..a0408b5a90896 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/golden-test-utils.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Split a generated C-file into the command used to generate it, +# and the outputted code itself. + +# This is useful because it allows input and output to be inside the same file + +# How it works: +# - The first line needs to start with '//' (and becomes the command). +# - Whitespace/padding between the comment and the generated code is ignored +# - To write a command using multiple lines, end each line with backslash (\) + +# Count the number of lines before the output text starts +# commandLineCount FILE +commandLineCount() { + local n state + n=0 + state="init" + while IFS="" read -r p || [ -n "$p" ]; do + case $state in + init) + if [[ $p =~ ^//.*\\$ ]]; then state="comment" + elif [[ $p =~ ^//.* ]]; then state="padding" + else break + fi + ;; + comment) [[ ! $p =~ ^.*\\$ ]] && state="padding";; + padding) [ -n "${p// }" ] && break;; + esac + n=$((n+1)) + done < "$1" + printf '%s' "$n" +} + +# getInputCommand FILE +getInputCommand() { + n=$(commandLineCount "$1") + head -n "$n" "$1" | awk '{ if (NR == 1) print substr($0, 3); else print $0 }' +} + +# getOutputText FILE +getOutputText() { + n=$(commandLineCount "$1") + sed "1,${n}d" "$1" +} diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c new file mode 100644 index 0000000000000..914fd851bb7e7 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -0,0 +1,33 @@ +// makeCWrapper /path/to/executable \ + --prefix PATH : /usr/bin/ \ + --prefix PATH : /usr/local/bin/ + +#include +#include +#include + +char *concat3(char *x, char *y, char *z) { + int xn = strlen(x); + int yn = strlen(y); + int zn = strlen(z); + char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + strncpy(res, x, xn); + strncpy(res + xn, y, yn); + strncpy(res + xn + yn, z, zn); + res[xn + yn + zn] = '\0'; + return res; +} + +void set_env_prefix(char *env, char *sep, char *val) { + char *existing = getenv(env); + if (existing) val = concat3(val, sep, existing); + setenv(env, val, 1); + if (existing) free(val); +} + +int main(int argc, char **argv) { + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_prefix("PATH", ":", "/usr/local/bin/"); + argv[0] = "/path/to/executable"; + return execv("/path/to/executable", argv); +} \ No newline at end of file diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c new file mode 100644 index 0000000000000..865d76fe34e2a --- /dev/null +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -0,0 +1,33 @@ +// makeCWrapper /path/to/executable \ + --suffix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ + +#include +#include +#include + +char *concat3(char *x, char *y, char *z) { + int xn = strlen(x); + int yn = strlen(y); + int zn = strlen(z); + char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + strncpy(res, x, xn); + strncpy(res + xn, y, yn); + strncpy(res + xn + yn, z, zn); + res[xn + yn + zn] = '\0'; + return res; +} + +void set_env_suffix(char *env, char *sep, char *val) { + char *existing = getenv(env); + if (existing) val = concat3(existing, sep, val); + setenv(env, val, 1); + if (existing) free(val); +} + +int main(int argc, char **argv) { + set_env_suffix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + argv[0] = "/path/to/executable"; + return execv("/path/to/executable", argv); +} \ No newline at end of file -- cgit 1.4.1 From 4b833cc141172f88e563692f2458253212d1cf1a Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Mon, 4 Oct 2021 22:38:14 +0200 Subject: EditorConfig: Switch from tabs to spaces --- pkgs/test/make-binary-wrapper/golden-test-utils.sh | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/golden-test-utils.sh b/pkgs/test/make-binary-wrapper/golden-test-utils.sh index a0408b5a90896..80e880e11e485 100644 --- a/pkgs/test/make-binary-wrapper/golden-test-utils.sh +++ b/pkgs/test/make-binary-wrapper/golden-test-utils.sh @@ -12,23 +12,23 @@ # Count the number of lines before the output text starts # commandLineCount FILE commandLineCount() { - local n state - n=0 - state="init" - while IFS="" read -r p || [ -n "$p" ]; do - case $state in - init) - if [[ $p =~ ^//.*\\$ ]]; then state="comment" - elif [[ $p =~ ^//.* ]]; then state="padding" - else break - fi - ;; - comment) [[ ! $p =~ ^.*\\$ ]] && state="padding";; - padding) [ -n "${p// }" ] && break;; - esac - n=$((n+1)) - done < "$1" - printf '%s' "$n" + local n state + n=0 + state="init" + while IFS="" read -r p || [ -n "$p" ]; do + case $state in + init) + if [[ $p =~ ^//.*\\$ ]]; then state="comment" + elif [[ $p =~ ^//.* ]]; then state="padding" + else break + fi + ;; + comment) [[ ! $p =~ ^.*\\$ ]] && state="padding";; + padding) [ -n "${p// }" ] && break;; + esac + n=$((n+1)) + done < "$1" + printf '%s' "$n" } # getInputCommand FILE -- cgit 1.4.1 From 7cca19a46a1803320df1a8d43ca669dcf9e87e84 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Tue, 19 Oct 2021 09:25:24 -0700 Subject: Set strictDeps = true in makeGoldenTest Co-authored-by: Robert Hensing --- pkgs/test/make-binary-wrapper/default.nix | 1 + 1 file changed, 1 insertion(+) (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index 0b9f7e5abea2e..c30d430d3aba9 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -4,6 +4,7 @@ let makeGoldenTest = { name, filename }: stdenv.mkDerivation { name = name; dontUnpack = true; + strictDeps = true; buildInputs = [ makeBinaryWrapper ]; phases = [ "installPhase" ]; installPhase = '' -- cgit 1.4.1 From a95a7a22be0c0768df613c4c74981374259665d6 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Tue, 19 Oct 2021 18:35:42 +0200 Subject: Switch from buildInputs to nativeBuildInpuits in makeGoldenTest --- pkgs/test/make-binary-wrapper/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index c30d430d3aba9..72e7fb094a482 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -5,7 +5,7 @@ let name = name; dontUnpack = true; strictDeps = true; - buildInputs = [ makeBinaryWrapper ]; + nativeBuildInputs = [ makeBinaryWrapper ]; phases = [ "installPhase" ]; installPhase = '' source ${./golden-test-utils.sh} -- cgit 1.4.1 From 3a014be2f2230b3228e122b7c74fb7561b495195 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Tue, 9 Nov 2021 02:55:26 +0100 Subject: Assert that malloc does not return a NULL pointer for better error messages + to satisfy static analysis tools. --- pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 8 +++++++- pkgs/test/make-binary-wrapper/add-flags.c | 2 ++ pkgs/test/make-binary-wrapper/combination.c | 3 +++ pkgs/test/make-binary-wrapper/prefix.c | 2 ++ pkgs/test/make-binary-wrapper/suffix.c | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index bb9b5f453d196..d7b888292d581 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -64,7 +64,7 @@ makeDocumentedCWrapper() { # ARGS: same as makeBinaryWrapper makeCWrapper() { local argv0 n params cmd main flagsBefore flags executable params length - local uses_prefix uses_suffix uses_concat3 + local uses_prefix uses_suffix uses_concat3 uses_assert executable=$(escapeStringLiteral "$1") params=("$@") length=${#params[*]} @@ -94,6 +94,7 @@ makeCWrapper() { main="$main $cmd"$'\n' uses_prefix=1 uses_concat3=1 + uses_assert=1 n=$((n + 3)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 3 arguments"$'\n' ;; @@ -102,12 +103,14 @@ makeCWrapper() { main="$main $cmd"$'\n' uses_suffix=1 uses_concat3=1 + uses_assert=1 n=$((n + 3)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 3 arguments"$'\n' ;; --add-flags) flags="${params[n + 1]}" flagsBefore="$flagsBefore $flags" + uses_assert=1 n=$((n + 1)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 1 argument"$'\n' ;; @@ -129,6 +132,7 @@ makeCWrapper() { printf '%s\n' "#include " printf '%s\n' "#include " [ -z "$uses_concat3" ] || printf '%s\n' "#include " + [ -z "$uses_assert" ] || printf '%s\n' "#include " [ -z "$uses_concat3" ] || printf '\n%s\n' "$(concat3Fn)" [ -z "$uses_prefix" ] || printf '\n%s\n' "$(setEnvPrefixFn)" [ -z "$uses_suffix" ] || printf '\n%s\n' "$(setEnvSuffixFn)" @@ -146,6 +150,7 @@ addFlags() { result="$result ${var}[$((n+1))] = \"$flag\";"$'\n' done printf ' %s\n' "char **$var = malloc(sizeof(*$var) * ($((n+1)) + argc));" + printf ' %s\n' "assert($var != NULL);" printf ' %s\n' "${var}[0] = argv[0];" printf '%s' "$result" printf ' %s\n' "for (int i = 1; i < argc; ++i) {" @@ -222,6 +227,7 @@ char *concat3(char *x, char *y, char *z) { int yn = strlen(y); int zn = strlen(z); char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + assert(res != NULL); strncpy(res, x, xn); strncpy(res + xn, y, yn); strncpy(res + xn + yn, z, zn); diff --git a/pkgs/test/make-binary-wrapper/add-flags.c b/pkgs/test/make-binary-wrapper/add-flags.c index 70d43e0bec081..fccd5aa9402a7 100644 --- a/pkgs/test/make-binary-wrapper/add-flags.c +++ b/pkgs/test/make-binary-wrapper/add-flags.c @@ -4,9 +4,11 @@ #include #include +#include int main(int argc, char **argv) { char **argv_tmp = malloc(sizeof(*argv_tmp) * (5 + argc)); + assert(argv_tmp != NULL); argv_tmp[0] = argv[0]; argv_tmp[1] = "-x"; argv_tmp[2] = "-y"; diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index 925fdf1ccfb4a..5e4e1168f4a02 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -9,12 +9,14 @@ #include #include #include +#include char *concat3(char *x, char *y, char *z) { int xn = strlen(x); int yn = strlen(y); int zn = strlen(z); char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + assert(res != NULL); strncpy(res, x, xn); strncpy(res + xn, y, yn); strncpy(res + xn + yn, z, zn); @@ -43,6 +45,7 @@ int main(int argc, char **argv) { putenv("MESSAGE2=WORLD"); char **argv_tmp = malloc(sizeof(*argv_tmp) * (4 + argc)); + assert(argv_tmp != NULL); argv_tmp[0] = argv[0]; argv_tmp[1] = "-x"; argv_tmp[2] = "-y"; diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c index 914fd851bb7e7..fa333013cd02e 100644 --- a/pkgs/test/make-binary-wrapper/prefix.c +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -5,12 +5,14 @@ #include #include #include +#include char *concat3(char *x, char *y, char *z) { int xn = strlen(x); int yn = strlen(y); int zn = strlen(z); char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + assert(res != NULL); strncpy(res, x, xn); strncpy(res + xn, y, yn); strncpy(res + xn + yn, z, zn); diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c index 865d76fe34e2a..a299f1fa0bd66 100644 --- a/pkgs/test/make-binary-wrapper/suffix.c +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -5,12 +5,14 @@ #include #include #include +#include char *concat3(char *x, char *y, char *z) { int xn = strlen(x); int yn = strlen(y); int zn = strlen(z); char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); + assert(res != NULL); strncpy(res, x, xn); strncpy(res + xn, y, yn); strncpy(res + xn + yn, z, zn); -- cgit 1.4.1 From 4e55d34535ae278b6130cba43edab6fd6c95e67d Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Wed, 1 Dec 2021 22:49:20 +0100 Subject: Add assertValidEnvName and check that variable name is valid during code generation. Add assert_success, and assert that setenv/unsetenv succeeds to crash if they don't --- .../setup-hooks/make-binary-wrapper.sh | 28 ++++++++++++++++++---- pkgs/test/make-binary-wrapper/combination.c | 9 ++++--- pkgs/test/make-binary-wrapper/default.nix | 1 + pkgs/test/make-binary-wrapper/env.c | 7 ++++-- pkgs/test/make-binary-wrapper/invalid-env.c | 18 ++++++++++++++ pkgs/test/make-binary-wrapper/prefix.c | 7 ++++-- pkgs/test/make-binary-wrapper/suffix.c | 5 +++- 7 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 pkgs/test/make-binary-wrapper/invalid-env.c (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index d7b888292d581..90b9576740b15 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -64,7 +64,7 @@ makeDocumentedCWrapper() { # ARGS: same as makeBinaryWrapper makeCWrapper() { local argv0 n params cmd main flagsBefore flags executable params length - local uses_prefix uses_suffix uses_concat3 uses_assert + local uses_prefix uses_suffix uses_assert uses_assert_success uses_concat3 executable=$(escapeStringLiteral "$1") params=("$@") length=${#params[*]} @@ -80,12 +80,14 @@ makeCWrapper() { --set-default) cmd=$(setDefaultEnv "${params[n + 1]}" "${params[n + 2]}") main="$main $cmd"$'\n' + uses_assert_success=1 n=$((n + 2)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 2 arguments"$'\n' ;; --unset) cmd=$(unsetEnv "${params[n + 1]}") main="$main $cmd"$'\n' + uses_assert_success=1 n=$((n + 1)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 1 argument"$'\n' ;; @@ -94,6 +96,7 @@ makeCWrapper() { main="$main $cmd"$'\n' uses_prefix=1 uses_concat3=1 + uses_assert_success=1 uses_assert=1 n=$((n + 3)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 3 arguments"$'\n' @@ -103,6 +106,7 @@ makeCWrapper() { main="$main $cmd"$'\n' uses_suffix=1 uses_concat3=1 + uses_assert_success=1 uses_assert=1 n=$((n + 3)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 3 arguments"$'\n' @@ -133,6 +137,8 @@ makeCWrapper() { printf '%s\n' "#include " [ -z "$uses_concat3" ] || printf '%s\n' "#include " [ -z "$uses_assert" ] || printf '%s\n' "#include " + [ -z "$uses_assert_success" ] || printf '%s\n' "#include " + [ -z "$uses_assert_success" ] || printf '\n%s\n' "#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0)" [ -z "$uses_concat3" ] || printf '\n%s\n' "$(concat3Fn)" [ -z "$uses_prefix" ] || printf '\n%s\n' "$(setEnvPrefixFn)" [ -z "$uses_suffix" ] || printf '\n%s\n' "$(setEnvSuffixFn)" @@ -167,6 +173,7 @@ setEnvPrefix() { sep=$(escapeStringLiteral "$2") val=$(escapeStringLiteral "$3") printf '%s' "set_env_prefix(\"$env\", \"$sep\", \"$val\");" + assertValidEnvName "$1" } # suffix ENV SEP VAL @@ -176,6 +183,7 @@ setEnvSuffix() { sep=$(escapeStringLiteral "$2") val=$(escapeStringLiteral "$3") printf '%s' "set_env_suffix(\"$env\", \"$sep\", \"$val\");" + assertValidEnvName "$1" } # setEnv KEY VALUE @@ -184,6 +192,7 @@ setEnv() { key=$(escapeStringLiteral "$1") value=$(escapeStringLiteral "$2") printf '%s' "putenv(\"$key=$value\");" + assertValidEnvName "$1" } # setDefaultEnv KEY VALUE @@ -191,14 +200,16 @@ setDefaultEnv() { local key value key=$(escapeStringLiteral "$1") value=$(escapeStringLiteral "$2") - printf '%s' "setenv(\"$key\", \"$value\", 0);" + printf '%s' "assert_success(setenv(\"$key\", \"$value\", 0));" + assertValidEnvName "$1" } # unsetEnv KEY unsetEnv() { local key key=$(escapeStringLiteral "$1") - printf '%s' "unsetenv(\"$key\");" + printf '%s' "assert_success(unsetenv(\"$key\"));" + assertValidEnvName "$1" } # Put the entire source code into const char* SOURCE_CODE to make it readable after compilation. @@ -220,6 +231,13 @@ escapeStringLiteral() { printf '%s' "$result" } +assertValidEnvName() { + case "$1" in + *=*) printf '\n%s\n' " #error Illegal environment variable name \`$1\` (cannot contain \`=\`)";; + "") printf '\n%s\n' " #error Environment variable name can't be empty.";; + esac +} + concat3Fn() { printf '%s' "\ char *concat3(char *x, char *y, char *z) { @@ -242,7 +260,7 @@ setEnvPrefixFn() { void set_env_prefix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(val, sep, existing); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } " @@ -253,7 +271,7 @@ setEnvSuffixFn() { void set_env_suffix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(existing, sep, val); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } " diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index 5e4e1168f4a02..a4082ac4aea05 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -10,6 +10,9 @@ #include #include #include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); @@ -27,19 +30,19 @@ char *concat3(char *x, char *y, char *z) { void set_env_prefix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(val, sep, existing); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } void set_env_suffix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(existing, sep, val); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } int main(int argc, char **argv) { - setenv("MESSAGE", "HELLO", 0); + assert_success(setenv("MESSAGE", "HELLO", 0)); set_env_prefix("PATH", ":", "/usr/bin/"); set_env_suffix("PATH", ":", "/usr/local/bin/"); putenv("MESSAGE2=WORLD"); diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index 72e7fb094a482..1972b03da25ba 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -29,6 +29,7 @@ let env = makeGoldenTest { name = "env"; filename = ./env.c; }; prefix = makeGoldenTest { name = "prefix"; filename = ./prefix.c; }; suffix = makeGoldenTest { name = "suffix"; filename = ./suffix.c; }; + invalid-env = makeGoldenTest { name = "invalid-env"; filename = ./invalid-env.c; }; }; in runCommand "make-binary-wrapper-test" { passthru = tests; diff --git a/pkgs/test/make-binary-wrapper/env.c b/pkgs/test/make-binary-wrapper/env.c index 89f1f496b3497..a1b50b1c3630c 100644 --- a/pkgs/test/make-binary-wrapper/env.c +++ b/pkgs/test/make-binary-wrapper/env.c @@ -6,11 +6,14 @@ #include #include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) int main(int argc, char **argv) { putenv("PART1=HELLO"); - setenv("PART2", "WORLD", 0); - unsetenv("SOME_OTHER_VARIABLE"); + assert_success(setenv("PART2", "WORLD", 0)); + assert_success(unsetenv("SOME_OTHER_VARIABLE")); putenv("PART3=\"!!\n\""); argv[0] = "/hello/world"; return execv("/hello/world", argv); diff --git a/pkgs/test/make-binary-wrapper/invalid-env.c b/pkgs/test/make-binary-wrapper/invalid-env.c new file mode 100644 index 0000000000000..02f7cd01a5944 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/invalid-env.c @@ -0,0 +1,18 @@ +// makeCWrapper /bad/env/example \ + --set "=" "TEST1" \ + --set-default "" "TEST2" + +#include +#include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) + +int main(int argc, char **argv) { + putenv("==TEST1"); + #error Illegal environment variable name `=` (cannot contain `=`) + assert_success(setenv("", "TEST2", 0)); + #error Environment variable name can't be empty. + argv[0] = "/bad/env/example"; + return execv("/bad/env/example", argv); +} \ No newline at end of file diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c index fa333013cd02e..8f7dd9b679c45 100644 --- a/pkgs/test/make-binary-wrapper/prefix.c +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -6,6 +6,9 @@ #include #include #include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); @@ -23,7 +26,7 @@ char *concat3(char *x, char *y, char *z) { void set_env_prefix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(val, sep, existing); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } @@ -32,4 +35,4 @@ int main(int argc, char **argv) { set_env_prefix("PATH", ":", "/usr/local/bin/"); argv[0] = "/path/to/executable"; return execv("/path/to/executable", argv); -} \ No newline at end of file +} diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c index a299f1fa0bd66..17160465b41e1 100644 --- a/pkgs/test/make-binary-wrapper/suffix.c +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -6,6 +6,9 @@ #include #include #include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); @@ -23,7 +26,7 @@ char *concat3(char *x, char *y, char *z) { void set_env_suffix(char *env, char *sep, char *val) { char *existing = getenv(env); if (existing) val = concat3(existing, sep, val); - setenv(env, val, 1); + assert_success(setenv(env, val, 1)); if (existing) free(val); } -- cgit 1.4.1 From 97d62a90f5ba28d6f16f40d20a679862394be8c2 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Wed, 1 Dec 2021 22:56:18 +0100 Subject: Switch from exit(1) to abort() in assert_success --- pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 2 +- pkgs/test/make-binary-wrapper/combination.c | 2 +- pkgs/test/make-binary-wrapper/env.c | 2 +- pkgs/test/make-binary-wrapper/invalid-env.c | 2 +- pkgs/test/make-binary-wrapper/prefix.c | 2 +- pkgs/test/make-binary-wrapper/suffix.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index 90b9576740b15..29b7c2d845e14 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -138,7 +138,7 @@ makeCWrapper() { [ -z "$uses_concat3" ] || printf '%s\n' "#include " [ -z "$uses_assert" ] || printf '%s\n' "#include " [ -z "$uses_assert_success" ] || printf '%s\n' "#include " - [ -z "$uses_assert_success" ] || printf '\n%s\n' "#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0)" + [ -z "$uses_assert_success" ] || printf '\n%s\n' "#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0)" [ -z "$uses_concat3" ] || printf '\n%s\n' "$(concat3Fn)" [ -z "$uses_prefix" ] || printf '\n%s\n' "$(setEnvPrefixFn)" [ -z "$uses_suffix" ] || printf '\n%s\n' "$(setEnvSuffixFn)" diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index a4082ac4aea05..c476b24394d84 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -12,7 +12,7 @@ #include #include -#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); diff --git a/pkgs/test/make-binary-wrapper/env.c b/pkgs/test/make-binary-wrapper/env.c index a1b50b1c3630c..fa2e6fc4dd294 100644 --- a/pkgs/test/make-binary-wrapper/env.c +++ b/pkgs/test/make-binary-wrapper/env.c @@ -8,7 +8,7 @@ #include #include -#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) int main(int argc, char **argv) { putenv("PART1=HELLO"); diff --git a/pkgs/test/make-binary-wrapper/invalid-env.c b/pkgs/test/make-binary-wrapper/invalid-env.c index 02f7cd01a5944..bad647bd13a28 100644 --- a/pkgs/test/make-binary-wrapper/invalid-env.c +++ b/pkgs/test/make-binary-wrapper/invalid-env.c @@ -6,7 +6,7 @@ #include #include -#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) int main(int argc, char **argv) { putenv("==TEST1"); diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c index 8f7dd9b679c45..8ca0ad94a6d70 100644 --- a/pkgs/test/make-binary-wrapper/prefix.c +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -8,7 +8,7 @@ #include #include -#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c index 17160465b41e1..31059c86e7a8e 100644 --- a/pkgs/test/make-binary-wrapper/suffix.c +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -8,7 +8,7 @@ #include #include -#define assert_success(e) do { if ((e) < 0) { perror(#e); exit(1); } } while (0) +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) char *concat3(char *x, char *y, char *z) { int xn = strlen(x); -- cgit 1.4.1 From 3997e9de6794e3227aa0c852647abda42d8a8fe6 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Wed, 1 Dec 2021 23:07:30 +0100 Subject: Switch from malloc to calloc in addFlags --- pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 2 +- pkgs/test/make-binary-wrapper/add-flags.c | 2 +- pkgs/test/make-binary-wrapper/combination.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index 29b7c2d845e14..659a0293703ec 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -155,7 +155,7 @@ addFlags() { flag=$(escapeStringLiteral "${flags[$n]}") result="$result ${var}[$((n+1))] = \"$flag\";"$'\n' done - printf ' %s\n' "char **$var = malloc(sizeof(*$var) * ($((n+1)) + argc));" + printf ' %s\n' "char **$var = calloc($((n+1)) + argc, sizeof(*$var));" printf ' %s\n' "assert($var != NULL);" printf ' %s\n' "${var}[0] = argv[0];" printf '%s' "$result" diff --git a/pkgs/test/make-binary-wrapper/add-flags.c b/pkgs/test/make-binary-wrapper/add-flags.c index fccd5aa9402a7..20d3b7508c05c 100644 --- a/pkgs/test/make-binary-wrapper/add-flags.c +++ b/pkgs/test/make-binary-wrapper/add-flags.c @@ -7,7 +7,7 @@ #include int main(int argc, char **argv) { - char **argv_tmp = malloc(sizeof(*argv_tmp) * (5 + argc)); + char **argv_tmp = calloc(5 + argc, sizeof(*argv_tmp)); assert(argv_tmp != NULL); argv_tmp[0] = argv[0]; argv_tmp[1] = "-x"; diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index c476b24394d84..4ab44281ef143 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -47,7 +47,7 @@ int main(int argc, char **argv) { set_env_suffix("PATH", ":", "/usr/local/bin/"); putenv("MESSAGE2=WORLD"); - char **argv_tmp = malloc(sizeof(*argv_tmp) * (4 + argc)); + char **argv_tmp = calloc(4 + argc, sizeof(*argv_tmp)); assert(argv_tmp != NULL); argv_tmp[0] = argv[0]; argv_tmp[1] = "-x"; -- cgit 1.4.1 From a1e62262bc5b1a7a3f528b48369e88846ba5cd3f Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Wed, 1 Dec 2021 23:27:26 +0100 Subject: Replace concat3 with asprintf in set_env_prefix and set_env_suffix. --- .../setup-hooks/make-binary-wrapper.sh | 64 ++++++++++------------ pkgs/test/make-binary-wrapper/combination.c | 41 +++++++------- pkgs/test/make-binary-wrapper/prefix.c | 28 ++++------ pkgs/test/make-binary-wrapper/suffix.c | 30 ++++------ 4 files changed, 70 insertions(+), 93 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index 659a0293703ec..f507f8c70cf8f 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -64,7 +64,7 @@ makeDocumentedCWrapper() { # ARGS: same as makeBinaryWrapper makeCWrapper() { local argv0 n params cmd main flagsBefore flags executable params length - local uses_prefix uses_suffix uses_assert uses_assert_success uses_concat3 + local uses_prefix uses_suffix uses_assert uses_assert_success uses_stdio uses_asprintf executable=$(escapeStringLiteral "$1") params=("$@") length=${#params[*]} @@ -80,6 +80,7 @@ makeCWrapper() { --set-default) cmd=$(setDefaultEnv "${params[n + 1]}" "${params[n + 2]}") main="$main $cmd"$'\n' + uses_stdio=1 uses_assert_success=1 n=$((n + 2)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 2 arguments"$'\n' @@ -87,6 +88,7 @@ makeCWrapper() { --unset) cmd=$(unsetEnv "${params[n + 1]}") main="$main $cmd"$'\n' + uses_stdio=1 uses_assert_success=1 n=$((n + 1)) [ $n -ge "$length" ] && main="$main #error makeCWrapper: $p takes 1 argument"$'\n' @@ -95,7 +97,8 @@ makeCWrapper() { cmd=$(setEnvPrefix "${params[n + 1]}" "${params[n + 2]}" "${params[n + 3]}") main="$main $cmd"$'\n' uses_prefix=1 - uses_concat3=1 + uses_asprintf=1 + uses_stdio=1 uses_assert_success=1 uses_assert=1 n=$((n + 3)) @@ -105,7 +108,8 @@ makeCWrapper() { cmd=$(setEnvSuffix "${params[n + 1]}" "${params[n + 2]}" "${params[n + 3]}") main="$main $cmd"$'\n' uses_suffix=1 - uses_concat3=1 + uses_asprintf=1 + uses_stdio=1 uses_assert_success=1 uses_assert=1 n=$((n + 3)) @@ -133,15 +137,14 @@ makeCWrapper() { main="$main argv[0] = \"${argv0:-${executable}}\";"$'\n' main="$main return execv(\"${executable}\", argv);"$'\n' + [ -z "$uses_asprintf" ] || printf '%s\n' "#define _GNU_SOURCE /* See feature_test_macros(7) */" printf '%s\n' "#include " printf '%s\n' "#include " - [ -z "$uses_concat3" ] || printf '%s\n' "#include " - [ -z "$uses_assert" ] || printf '%s\n' "#include " - [ -z "$uses_assert_success" ] || printf '%s\n' "#include " + [ -z "$uses_assert" ] || printf '%s\n' "#include " + [ -z "$uses_stdio" ] || printf '%s\n' "#include " [ -z "$uses_assert_success" ] || printf '\n%s\n' "#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0)" - [ -z "$uses_concat3" ] || printf '\n%s\n' "$(concat3Fn)" - [ -z "$uses_prefix" ] || printf '\n%s\n' "$(setEnvPrefixFn)" - [ -z "$uses_suffix" ] || printf '\n%s\n' "$(setEnvSuffixFn)" + [ -z "$uses_prefix" ] || printf '\n%s\n' "$(setEnvPrefixFn)" + [ -z "$uses_suffix" ] || printf '\n%s\n' "$(setEnvSuffixFn)" printf '\n%s' "int main(int argc, char **argv) {" printf '\n%s' "$main" printf '%s\n' "}" @@ -238,41 +241,34 @@ assertValidEnvName() { esac } -concat3Fn() { - printf '%s' "\ -char *concat3(char *x, char *y, char *z) { - int xn = strlen(x); - int yn = strlen(y); - int zn = strlen(z); - char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); - assert(res != NULL); - strncpy(res, x, xn); - strncpy(res + xn, y, yn); - strncpy(res + xn + yn, z, zn); - res[xn + yn + zn] = '\0'; - return res; -} -" -} - setEnvPrefixFn() { printf '%s' "\ -void set_env_prefix(char *env, char *sep, char *val) { +void set_env_prefix(char *env, char *sep, char *prefix) { char *existing = getenv(env); - if (existing) val = concat3(val, sep, existing); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, \"%s%s%s\", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } } " } setEnvSuffixFn() { printf '%s' "\ -void set_env_suffix(char *env, char *sep, char *val) { +void set_env_suffix(char *env, char *sep, char *suffix) { char *existing = getenv(env); - if (existing) val = concat3(existing, sep, val); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, \"%s%s%s\", existing, sep, suffix)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, suffix, 1)); + } } " } diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index 4ab44281ef143..bb35d0d99f314 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -6,39 +6,36 @@ --add-flags "-x -y -z" \ --set MESSAGE2 WORLD +#define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include -#include #include #include #define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) -char *concat3(char *x, char *y, char *z) { - int xn = strlen(x); - int yn = strlen(y); - int zn = strlen(z); - char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); - assert(res != NULL); - strncpy(res, x, xn); - strncpy(res + xn, y, yn); - strncpy(res + xn + yn, z, zn); - res[xn + yn + zn] = '\0'; - return res; -} - -void set_env_prefix(char *env, char *sep, char *val) { +void set_env_prefix(char *env, char *sep, char *prefix) { char *existing = getenv(env); - if (existing) val = concat3(val, sep, existing); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } } -void set_env_suffix(char *env, char *sep, char *val) { +void set_env_suffix(char *env, char *sep, char *suffix) { char *existing = getenv(env); - if (existing) val = concat3(existing, sep, val); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", existing, sep, suffix)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, suffix, 1)); + } } int main(int argc, char **argv) { diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c index 8ca0ad94a6d70..de431168bffc0 100644 --- a/pkgs/test/make-binary-wrapper/prefix.c +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -2,32 +2,24 @@ --prefix PATH : /usr/bin/ \ --prefix PATH : /usr/local/bin/ +#define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include -#include #include #include #define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) -char *concat3(char *x, char *y, char *z) { - int xn = strlen(x); - int yn = strlen(y); - int zn = strlen(z); - char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); - assert(res != NULL); - strncpy(res, x, xn); - strncpy(res + xn, y, yn); - strncpy(res + xn + yn, z, zn); - res[xn + yn + zn] = '\0'; - return res; -} - -void set_env_prefix(char *env, char *sep, char *val) { +void set_env_prefix(char *env, char *sep, char *prefix) { char *existing = getenv(env); - if (existing) val = concat3(val, sep, existing); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", prefix, sep, existing)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, prefix, 1)); + } } int main(int argc, char **argv) { diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c index 31059c86e7a8e..3fcb338a61045 100644 --- a/pkgs/test/make-binary-wrapper/suffix.c +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -2,32 +2,24 @@ --suffix PATH : /usr/bin/ \ --suffix PATH : /usr/local/bin/ +#define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include -#include #include #include #define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) -char *concat3(char *x, char *y, char *z) { - int xn = strlen(x); - int yn = strlen(y); - int zn = strlen(z); - char *res = malloc(sizeof(*res)*(xn + yn + zn + 1)); - assert(res != NULL); - strncpy(res, x, xn); - strncpy(res + xn, y, yn); - strncpy(res + xn + yn, z, zn); - res[xn + yn + zn] = '\0'; - return res; -} - -void set_env_suffix(char *env, char *sep, char *val) { +void set_env_suffix(char *env, char *sep, char *suffix) { char *existing = getenv(env); - if (existing) val = concat3(existing, sep, val); - assert_success(setenv(env, val, 1)); - if (existing) free(val); + if (existing) { + char *val; + assert_success(asprintf(&val, "%s%s%s", existing, sep, suffix)); + assert_success(setenv(env, val, 1)); + free(val); + } else { + assert_success(setenv(env, suffix, 1)); + } } int main(int argc, char **argv) { @@ -35,4 +27,4 @@ int main(int argc, char **argv) { set_env_suffix("PATH", ":", "/usr/local/bin/"); argv[0] = "/path/to/executable"; return execv("/path/to/executable", argv); -} \ No newline at end of file +} -- cgit 1.4.1 From d8375fbccb2d8f7b8279374fa84645494e1a0942 Mon Sep 17 00:00:00 2001 From: Tobias Bergkvist Date: Thu, 2 Dec 2021 04:03:36 +0100 Subject: Add tests for `--inherit-argv0` and `--chdir DIR` --- pkgs/test/make-binary-wrapper/chdir.c | 14 ++++++++++++++ pkgs/test/make-binary-wrapper/default.nix | 10 ++++++---- pkgs/test/make-binary-wrapper/inherit-argv0.c | 9 +++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 pkgs/test/make-binary-wrapper/chdir.c create mode 100644 pkgs/test/make-binary-wrapper/inherit-argv0.c (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/chdir.c b/pkgs/test/make-binary-wrapper/chdir.c new file mode 100644 index 0000000000000..ff1f91a03babd --- /dev/null +++ b/pkgs/test/make-binary-wrapper/chdir.c @@ -0,0 +1,14 @@ +// makeCWrapper /path/to/executable \ + --chdir /usr/local/bin + +#include +#include +#include + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + assert_success(chdir("/usr/local/bin")); + argv[0] = "/path/to/executable"; + return execv("/path/to/executable", argv); +} \ No newline at end of file diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index 1972b03da25ba..eddab15fd31d9 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -22,14 +22,16 @@ let }; }; tests = { - add-flags = makeGoldenTest { name = "add-flags"; filename = ./add-flags.c; }; - argv0 = makeGoldenTest { name = "argv0"; filename = ./argv0.c; }; basic = makeGoldenTest { name = "basic"; filename = ./basic.c; }; - combination = makeGoldenTest { name = "combination"; filename = ./combination.c; }; + argv0 = makeGoldenTest { name = "argv0"; filename = ./argv0.c; }; + inherit_argv0 = makeGoldenTest { name = "inherit-argv0"; filename = ./inherit-argv0.c; }; env = makeGoldenTest { name = "env"; filename = ./env.c; }; + invalid_env = makeGoldenTest { name = "invalid-env"; filename = ./invalid-env.c; }; prefix = makeGoldenTest { name = "prefix"; filename = ./prefix.c; }; suffix = makeGoldenTest { name = "suffix"; filename = ./suffix.c; }; - invalid-env = makeGoldenTest { name = "invalid-env"; filename = ./invalid-env.c; }; + add_flags = makeGoldenTest { name = "add-flags"; filename = ./add-flags.c; }; + chdir = makeGoldenTest { name = "chdir"; filename = ./chdir.c; }; + combination = makeGoldenTest { name = "combination"; filename = ./combination.c; }; }; in runCommand "make-binary-wrapper-test" { passthru = tests; diff --git a/pkgs/test/make-binary-wrapper/inherit-argv0.c b/pkgs/test/make-binary-wrapper/inherit-argv0.c new file mode 100644 index 0000000000000..71e12d9b024a5 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/inherit-argv0.c @@ -0,0 +1,9 @@ +// makeCWrapper /path/to/executable \ + --inherit-argv0 + +#include +#include + +int main(int argc, char **argv) { + return execv("/path/to/executable", argv); +} \ No newline at end of file -- cgit 1.4.1 From 2bc7345064f5fc454282f044589e9f4b288257d4 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Tue, 7 Dec 2021 17:39:38 +0000 Subject: Add golden effects test --- pkgs/test/make-binary-wrapper/add-flags.c | 6 +- pkgs/test/make-binary-wrapper/add-flags.cmdline | 2 + pkgs/test/make-binary-wrapper/add-flags.env | 6 ++ pkgs/test/make-binary-wrapper/argv0.c | 5 +- pkgs/test/make-binary-wrapper/argv0.cmdline | 1 + pkgs/test/make-binary-wrapper/argv0.env | 2 + pkgs/test/make-binary-wrapper/basic.c | 6 +- pkgs/test/make-binary-wrapper/basic.cmdline | 0 pkgs/test/make-binary-wrapper/basic.env | 2 + pkgs/test/make-binary-wrapper/chdir.c | 11 +- pkgs/test/make-binary-wrapper/chdir.cmdline | 1 + pkgs/test/make-binary-wrapper/chdir.env | 2 + pkgs/test/make-binary-wrapper/combination.c | 10 +- pkgs/test/make-binary-wrapper/combination.cmdline | 6 ++ pkgs/test/make-binary-wrapper/combination.env | 8 ++ pkgs/test/make-binary-wrapper/default.nix | 113 +++++++++------------ pkgs/test/make-binary-wrapper/env.c | 12 +-- pkgs/test/make-binary-wrapper/env.cmdline | 4 + pkgs/test/make-binary-wrapper/env.env | 6 ++ pkgs/test/make-binary-wrapper/envcheck.c | 22 ++++ pkgs/test/make-binary-wrapper/golden-test-utils.sh | 44 -------- pkgs/test/make-binary-wrapper/inherit-argv0.c | 7 +- .../test/make-binary-wrapper/inherit-argv0.cmdline | 1 + pkgs/test/make-binary-wrapper/inherit-argv0.env | 2 + pkgs/test/make-binary-wrapper/invalid-env.c | 10 +- pkgs/test/make-binary-wrapper/invalid-env.cmdline | 2 + pkgs/test/make-binary-wrapper/prefix.c | 8 +- pkgs/test/make-binary-wrapper/prefix.cmdline | 2 + pkgs/test/make-binary-wrapper/prefix.env | 3 + pkgs/test/make-binary-wrapper/suffix.c | 8 +- pkgs/test/make-binary-wrapper/suffix.cmdline | 2 + pkgs/test/make-binary-wrapper/suffix.env | 3 + 32 files changed, 145 insertions(+), 172 deletions(-) create mode 100644 pkgs/test/make-binary-wrapper/add-flags.cmdline create mode 100644 pkgs/test/make-binary-wrapper/add-flags.env create mode 100644 pkgs/test/make-binary-wrapper/argv0.cmdline create mode 100644 pkgs/test/make-binary-wrapper/argv0.env create mode 100644 pkgs/test/make-binary-wrapper/basic.cmdline create mode 100644 pkgs/test/make-binary-wrapper/basic.env create mode 100644 pkgs/test/make-binary-wrapper/chdir.cmdline create mode 100644 pkgs/test/make-binary-wrapper/chdir.env create mode 100644 pkgs/test/make-binary-wrapper/combination.cmdline create mode 100644 pkgs/test/make-binary-wrapper/combination.env create mode 100644 pkgs/test/make-binary-wrapper/env.cmdline create mode 100644 pkgs/test/make-binary-wrapper/env.env create mode 100644 pkgs/test/make-binary-wrapper/envcheck.c delete mode 100644 pkgs/test/make-binary-wrapper/golden-test-utils.sh create mode 100644 pkgs/test/make-binary-wrapper/inherit-argv0.cmdline create mode 100644 pkgs/test/make-binary-wrapper/inherit-argv0.env create mode 100644 pkgs/test/make-binary-wrapper/invalid-env.cmdline create mode 100644 pkgs/test/make-binary-wrapper/prefix.cmdline create mode 100644 pkgs/test/make-binary-wrapper/prefix.env create mode 100644 pkgs/test/make-binary-wrapper/suffix.cmdline create mode 100644 pkgs/test/make-binary-wrapper/suffix.env (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/add-flags.c b/pkgs/test/make-binary-wrapper/add-flags.c index 20d3b7508c05c..7ce682c6be647 100644 --- a/pkgs/test/make-binary-wrapper/add-flags.c +++ b/pkgs/test/make-binary-wrapper/add-flags.c @@ -1,7 +1,3 @@ -// makeCWrapper /send/me/flags \ - --add-flags "-x -y -z" \ - --add-flags -abc - #include #include #include @@ -22,4 +18,4 @@ int main(int argc, char **argv) { argv[0] = "/send/me/flags"; return execv("/send/me/flags", argv); -} \ No newline at end of file +} diff --git a/pkgs/test/make-binary-wrapper/add-flags.cmdline b/pkgs/test/make-binary-wrapper/add-flags.cmdline new file mode 100644 index 0000000000000..f840c772e3494 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/add-flags.cmdline @@ -0,0 +1,2 @@ + --add-flags "-x -y -z" \ + --add-flags -abc diff --git a/pkgs/test/make-binary-wrapper/add-flags.env b/pkgs/test/make-binary-wrapper/add-flags.env new file mode 100644 index 0000000000000..9b8d1fb9f6a5d --- /dev/null +++ b/pkgs/test/make-binary-wrapper/add-flags.env @@ -0,0 +1,6 @@ +CWD=SUBST_CWD +SUBST_ARGV0 +-x +-y +-z +-abc diff --git a/pkgs/test/make-binary-wrapper/argv0.c b/pkgs/test/make-binary-wrapper/argv0.c index 8e3e1f2987b5b..70c36889dc890 100644 --- a/pkgs/test/make-binary-wrapper/argv0.c +++ b/pkgs/test/make-binary-wrapper/argv0.c @@ -1,10 +1,7 @@ -// makeCWrapper /path/to/some/executable \ - --argv0 alternative-name - #include #include int main(int argc, char **argv) { argv[0] = "alternative-name"; - return execv("/path/to/some/executable", argv); + return execv("/send/me/flags", argv); } diff --git a/pkgs/test/make-binary-wrapper/argv0.cmdline b/pkgs/test/make-binary-wrapper/argv0.cmdline new file mode 100644 index 0000000000000..1cadce8312a44 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/argv0.cmdline @@ -0,0 +1 @@ + --argv0 alternative-name diff --git a/pkgs/test/make-binary-wrapper/argv0.env b/pkgs/test/make-binary-wrapper/argv0.env new file mode 100644 index 0000000000000..04c13d32ee6d6 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/argv0.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +alternative-name diff --git a/pkgs/test/make-binary-wrapper/basic.c b/pkgs/test/make-binary-wrapper/basic.c index de366c5196306..1c1266181377a 100644 --- a/pkgs/test/make-binary-wrapper/basic.c +++ b/pkgs/test/make-binary-wrapper/basic.c @@ -1,9 +1,7 @@ -// makeCWrapper /path/to/executable - #include #include int main(int argc, char **argv) { - argv[0] = "/path/to/executable"; - return execv("/path/to/executable", argv); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); } diff --git a/pkgs/test/make-binary-wrapper/basic.cmdline b/pkgs/test/make-binary-wrapper/basic.cmdline new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/pkgs/test/make-binary-wrapper/basic.env b/pkgs/test/make-binary-wrapper/basic.env new file mode 100644 index 0000000000000..b0da31959447c --- /dev/null +++ b/pkgs/test/make-binary-wrapper/basic.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/pkgs/test/make-binary-wrapper/chdir.c b/pkgs/test/make-binary-wrapper/chdir.c index ff1f91a03babd..c67c695b1c3b9 100644 --- a/pkgs/test/make-binary-wrapper/chdir.c +++ b/pkgs/test/make-binary-wrapper/chdir.c @@ -1,6 +1,3 @@ -// makeCWrapper /path/to/executable \ - --chdir /usr/local/bin - #include #include #include @@ -8,7 +5,7 @@ #define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) int main(int argc, char **argv) { - assert_success(chdir("/usr/local/bin")); - argv[0] = "/path/to/executable"; - return execv("/path/to/executable", argv); -} \ No newline at end of file + assert_success(chdir("/tmp/foo")); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/pkgs/test/make-binary-wrapper/chdir.cmdline b/pkgs/test/make-binary-wrapper/chdir.cmdline new file mode 100644 index 0000000000000..15235f20621c8 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/chdir.cmdline @@ -0,0 +1 @@ + --chdir /tmp/foo diff --git a/pkgs/test/make-binary-wrapper/chdir.env b/pkgs/test/make-binary-wrapper/chdir.env new file mode 100644 index 0000000000000..db129d68af741 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/chdir.env @@ -0,0 +1,2 @@ +CWD=/tmp/foo +SUBST_ARGV0 diff --git a/pkgs/test/make-binary-wrapper/combination.c b/pkgs/test/make-binary-wrapper/combination.c index bb35d0d99f314..e9ce5f1d72440 100644 --- a/pkgs/test/make-binary-wrapper/combination.c +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -1,11 +1,3 @@ -// makeCWrapper /path/to/executable \ - --argv0 my-wrapper \ - --set-default MESSAGE HELLO \ - --prefix PATH : /usr/bin/ \ - --suffix PATH : /usr/local/bin/ \ - --add-flags "-x -y -z" \ - --set MESSAGE2 WORLD - #define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include @@ -57,5 +49,5 @@ int main(int argc, char **argv) { argv = argv_tmp; argv[0] = "my-wrapper"; - return execv("/path/to/executable", argv); + return execv("/send/me/flags", argv); } diff --git a/pkgs/test/make-binary-wrapper/combination.cmdline b/pkgs/test/make-binary-wrapper/combination.cmdline new file mode 100644 index 0000000000000..fb3861235c8b4 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/combination.cmdline @@ -0,0 +1,6 @@ + --argv0 my-wrapper \ + --set-default MESSAGE HELLO \ + --prefix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ \ + --add-flags "-x -y -z" \ + --set MESSAGE2 WORLD diff --git a/pkgs/test/make-binary-wrapper/combination.env b/pkgs/test/make-binary-wrapper/combination.env new file mode 100644 index 0000000000000..886420c01d1ea --- /dev/null +++ b/pkgs/test/make-binary-wrapper/combination.env @@ -0,0 +1,8 @@ +MESSAGE=HELLO +PATH=/usr/bin/:/usr/local/bin/ +MESSAGE2=WORLD +CWD=SUBST_CWD +my-wrapper +-x +-y +-z diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index eddab15fd31d9..6f3b3ef4ae12b 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -1,73 +1,54 @@ -{ lib, stdenv, runCommand, makeBinaryWrapper }: +{ lib, coreutils, python3, gcc, writeText, writeScript, runCommand, makeBinaryWrapper }: let - makeGoldenTest = { name, filename }: stdenv.mkDerivation { - name = name; - dontUnpack = true; - strictDeps = true; - nativeBuildInputs = [ makeBinaryWrapper ]; - phases = [ "installPhase" ]; - installPhase = '' - source ${./golden-test-utils.sh} - mkdir -p $out/bin - command=$(getInputCommand "${filename}") - eval "$command" > "$out/bin/result" - ''; - passthru = { - assertion = '' - source ${./golden-test-utils.sh} - contents=$(getOutputText "${filename}") - echo "$contents" | diff $out/bin/result - - ''; - }; - }; - tests = { - basic = makeGoldenTest { name = "basic"; filename = ./basic.c; }; - argv0 = makeGoldenTest { name = "argv0"; filename = ./argv0.c; }; - inherit_argv0 = makeGoldenTest { name = "inherit-argv0"; filename = ./inherit-argv0.c; }; - env = makeGoldenTest { name = "env"; filename = ./env.c; }; - invalid_env = makeGoldenTest { name = "invalid-env"; filename = ./invalid-env.c; }; - prefix = makeGoldenTest { name = "prefix"; filename = ./prefix.c; }; - suffix = makeGoldenTest { name = "suffix"; filename = ./suffix.c; }; - add_flags = makeGoldenTest { name = "add-flags"; filename = ./add-flags.c; }; - chdir = makeGoldenTest { name = "chdir"; filename = ./chdir.c; }; - combination = makeGoldenTest { name = "combination"; filename = ./combination.c; }; - }; -in runCommand "make-binary-wrapper-test" { - passthru = tests; - meta.platforms = lib.platforms.all; -} '' - validate() { - local name=$1 - local testout=$2 - local assertion=$3 - - echo -n "... $name: " >&2 - - local rc=0 - (out=$testout eval "$assertion") || rc=1 - - if [ "$rc" -eq 0 ]; then - echo "yes" >&2 + env = { nativeBuildInputs = [ makeBinaryWrapper gcc ]; }; + envCheck = runCommand "envcheck" env '' + cc -o $out ${./envcheck.c} + ''; + makeGoldenTest = testname: runCommand "test-wrapper_${testname}" env '' + mkdir -p /tmp/foo + + params=$(<"${./.}/${testname}.cmdline") + eval "makeCWrapper /send/me/flags $params" > wrapper.c + + diff wrapper.c "${./.}/${testname}.c" + + if [ -f "${./.}/${testname}.env" ]; then + eval "makeBinaryWrapper ${envCheck} wrapped $params" + env -i ./wrapped > env.txt + sed "s#SUBST_ARGV0#${envCheck}#;s#SUBST_CWD#$PWD#" \ + "${./.}/${testname}.env" > golden-env.txt + if ! diff env.txt golden-env.txt; then + echo "env/argv should be:" + cat golden-env.txt + echo "env/argv output is:" + cat env.txt + exit 1 + fi else - echo "no" >&2 + # without a golden env, we expect the wrapper compilation to fail + ! eval "makeBinaryWrapper ${envCheck} wrapped $params" &> error.txt fi - return "$rc" - } - - echo "checking whether makeCWrapper works properly... ">&2 - - fail= + cp wrapper.c $out + ''; + tests = let + names = [ + "add-flags" + "argv0" + "basic" + "chdir" + "combination" + "env" + "inherit-argv0" + "invalid-env" + "prefix" + "suffix" + ]; + f = name: lib.nameValuePair name (makeGoldenTest name); + in builtins.listToAttrs (builtins.map f names); +in writeText "make-binary-wrapper-test" '' ${lib.concatStringsSep "\n" (lib.mapAttrsToList (_: test: '' - validate "${test.name}" "${test}" ${lib.escapeShellArg test.assertion} || fail=1 + "${test.name}" "${test}" '') tests)} - - if [ "$fail" ]; then - echo "failed" - exit 1 - else - echo "succeeded" - touch $out - fi -'' +'' // tests diff --git a/pkgs/test/make-binary-wrapper/env.c b/pkgs/test/make-binary-wrapper/env.c index fa2e6fc4dd294..7e0422dee3bdc 100644 --- a/pkgs/test/make-binary-wrapper/env.c +++ b/pkgs/test/make-binary-wrapper/env.c @@ -1,9 +1,3 @@ -// makeCWrapper /hello/world \ - --set PART1 HELLO \ - --set-default PART2 WORLD \ - --unset SOME_OTHER_VARIABLE \ - --set PART3 $'"!!\n"' - #include #include #include @@ -15,6 +9,6 @@ int main(int argc, char **argv) { assert_success(setenv("PART2", "WORLD", 0)); assert_success(unsetenv("SOME_OTHER_VARIABLE")); putenv("PART3=\"!!\n\""); - argv[0] = "/hello/world"; - return execv("/hello/world", argv); -} \ No newline at end of file + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/pkgs/test/make-binary-wrapper/env.cmdline b/pkgs/test/make-binary-wrapper/env.cmdline new file mode 100644 index 0000000000000..3c89f33e2dceb --- /dev/null +++ b/pkgs/test/make-binary-wrapper/env.cmdline @@ -0,0 +1,4 @@ + --set PART1 HELLO \ + --set-default PART2 WORLD \ + --unset SOME_OTHER_VARIABLE \ + --set PART3 $'"!!\n"' diff --git a/pkgs/test/make-binary-wrapper/env.env b/pkgs/test/make-binary-wrapper/env.env new file mode 100644 index 0000000000000..c7661e165e09e --- /dev/null +++ b/pkgs/test/make-binary-wrapper/env.env @@ -0,0 +1,6 @@ +PART1=HELLO +PART2=WORLD +PART3="!! +" +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/pkgs/test/make-binary-wrapper/envcheck.c b/pkgs/test/make-binary-wrapper/envcheck.c new file mode 100644 index 0000000000000..848fbdaa80f26 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/envcheck.c @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char **argv, char **envp) { + for (char **env = envp; *env != 0; ++env) { + puts(*env); + } + + char cwd[PATH_MAX]; + if (getcwd(cwd, sizeof(cwd))) { + printf("CWD=%s\n", cwd); + } else { + perror("getcwd() error"); + return 1; + } + + for (int i=0; i < argc; ++i) { + puts(argv[i]); + } + return 0; +} diff --git a/pkgs/test/make-binary-wrapper/golden-test-utils.sh b/pkgs/test/make-binary-wrapper/golden-test-utils.sh deleted file mode 100644 index 80e880e11e485..0000000000000 --- a/pkgs/test/make-binary-wrapper/golden-test-utils.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -# Split a generated C-file into the command used to generate it, -# and the outputted code itself. - -# This is useful because it allows input and output to be inside the same file - -# How it works: -# - The first line needs to start with '//' (and becomes the command). -# - Whitespace/padding between the comment and the generated code is ignored -# - To write a command using multiple lines, end each line with backslash (\) - -# Count the number of lines before the output text starts -# commandLineCount FILE -commandLineCount() { - local n state - n=0 - state="init" - while IFS="" read -r p || [ -n "$p" ]; do - case $state in - init) - if [[ $p =~ ^//.*\\$ ]]; then state="comment" - elif [[ $p =~ ^//.* ]]; then state="padding" - else break - fi - ;; - comment) [[ ! $p =~ ^.*\\$ ]] && state="padding";; - padding) [ -n "${p// }" ] && break;; - esac - n=$((n+1)) - done < "$1" - printf '%s' "$n" -} - -# getInputCommand FILE -getInputCommand() { - n=$(commandLineCount "$1") - head -n "$n" "$1" | awk '{ if (NR == 1) print substr($0, 3); else print $0 }' -} - -# getOutputText FILE -getOutputText() { - n=$(commandLineCount "$1") - sed "1,${n}d" "$1" -} diff --git a/pkgs/test/make-binary-wrapper/inherit-argv0.c b/pkgs/test/make-binary-wrapper/inherit-argv0.c index 71e12d9b024a5..e1c2bc926aa72 100644 --- a/pkgs/test/make-binary-wrapper/inherit-argv0.c +++ b/pkgs/test/make-binary-wrapper/inherit-argv0.c @@ -1,9 +1,6 @@ -// makeCWrapper /path/to/executable \ - --inherit-argv0 - #include #include int main(int argc, char **argv) { - return execv("/path/to/executable", argv); -} \ No newline at end of file + return execv("/send/me/flags", argv); +} diff --git a/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline b/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline new file mode 100644 index 0000000000000..0880767998357 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/inherit-argv0.cmdline @@ -0,0 +1 @@ + --inherit-argv0 diff --git a/pkgs/test/make-binary-wrapper/inherit-argv0.env b/pkgs/test/make-binary-wrapper/inherit-argv0.env new file mode 100644 index 0000000000000..c46ca95eefbc7 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/inherit-argv0.env @@ -0,0 +1,2 @@ +CWD=SUBST_CWD +./wrapped diff --git a/pkgs/test/make-binary-wrapper/invalid-env.c b/pkgs/test/make-binary-wrapper/invalid-env.c index bad647bd13a28..4dfd36fb68a0b 100644 --- a/pkgs/test/make-binary-wrapper/invalid-env.c +++ b/pkgs/test/make-binary-wrapper/invalid-env.c @@ -1,7 +1,3 @@ -// makeCWrapper /bad/env/example \ - --set "=" "TEST1" \ - --set-default "" "TEST2" - #include #include #include @@ -13,6 +9,6 @@ int main(int argc, char **argv) { #error Illegal environment variable name `=` (cannot contain `=`) assert_success(setenv("", "TEST2", 0)); #error Environment variable name can't be empty. - argv[0] = "/bad/env/example"; - return execv("/bad/env/example", argv); -} \ No newline at end of file + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); +} diff --git a/pkgs/test/make-binary-wrapper/invalid-env.cmdline b/pkgs/test/make-binary-wrapper/invalid-env.cmdline new file mode 100644 index 0000000000000..a03b001e754e3 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/invalid-env.cmdline @@ -0,0 +1,2 @@ + --set "=" "TEST1" \ + --set-default "" "TEST2" diff --git a/pkgs/test/make-binary-wrapper/prefix.c b/pkgs/test/make-binary-wrapper/prefix.c index de431168bffc0..ea8fbdc64a84e 100644 --- a/pkgs/test/make-binary-wrapper/prefix.c +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -1,7 +1,3 @@ -// makeCWrapper /path/to/executable \ - --prefix PATH : /usr/bin/ \ - --prefix PATH : /usr/local/bin/ - #define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include @@ -25,6 +21,6 @@ void set_env_prefix(char *env, char *sep, char *prefix) { int main(int argc, char **argv) { set_env_prefix("PATH", ":", "/usr/bin/"); set_env_prefix("PATH", ":", "/usr/local/bin/"); - argv[0] = "/path/to/executable"; - return execv("/path/to/executable", argv); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); } diff --git a/pkgs/test/make-binary-wrapper/prefix.cmdline b/pkgs/test/make-binary-wrapper/prefix.cmdline new file mode 100644 index 0000000000000..99cebf9503f47 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/prefix.cmdline @@ -0,0 +1,2 @@ + --prefix PATH : /usr/bin/ \ + --prefix PATH : /usr/local/bin/ diff --git a/pkgs/test/make-binary-wrapper/prefix.env b/pkgs/test/make-binary-wrapper/prefix.env new file mode 100644 index 0000000000000..033676457c57c --- /dev/null +++ b/pkgs/test/make-binary-wrapper/prefix.env @@ -0,0 +1,3 @@ +PATH=/usr/local/bin/:/usr/bin/ +CWD=SUBST_CWD +SUBST_ARGV0 diff --git a/pkgs/test/make-binary-wrapper/suffix.c b/pkgs/test/make-binary-wrapper/suffix.c index 3fcb338a61045..d33f86c070ca5 100644 --- a/pkgs/test/make-binary-wrapper/suffix.c +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -1,7 +1,3 @@ -// makeCWrapper /path/to/executable \ - --suffix PATH : /usr/bin/ \ - --suffix PATH : /usr/local/bin/ - #define _GNU_SOURCE /* See feature_test_macros(7) */ #include #include @@ -25,6 +21,6 @@ void set_env_suffix(char *env, char *sep, char *suffix) { int main(int argc, char **argv) { set_env_suffix("PATH", ":", "/usr/bin/"); set_env_suffix("PATH", ":", "/usr/local/bin/"); - argv[0] = "/path/to/executable"; - return execv("/path/to/executable", argv); + argv[0] = "/send/me/flags"; + return execv("/send/me/flags", argv); } diff --git a/pkgs/test/make-binary-wrapper/suffix.cmdline b/pkgs/test/make-binary-wrapper/suffix.cmdline new file mode 100644 index 0000000000000..95d291f3c169e --- /dev/null +++ b/pkgs/test/make-binary-wrapper/suffix.cmdline @@ -0,0 +1,2 @@ + --suffix PATH : /usr/bin/ \ + --suffix PATH : /usr/local/bin/ diff --git a/pkgs/test/make-binary-wrapper/suffix.env b/pkgs/test/make-binary-wrapper/suffix.env new file mode 100644 index 0000000000000..3ce4cc54de41b --- /dev/null +++ b/pkgs/test/make-binary-wrapper/suffix.env @@ -0,0 +1,3 @@ +PATH=/usr/bin/:/usr/local/bin/ +CWD=SUBST_CWD +SUBST_ARGV0 -- cgit 1.4.1 From e7c70ce5c8cfb139adcbec73ec518031bfc8f211 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Thu, 9 Dec 2021 12:27:29 +0100 Subject: Inject gcc path into makewrapper script --- pkgs/test/make-binary-wrapper/default.nix | 4 ++-- pkgs/top-level/all-packages.nix | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index 6f3b3ef4ae12b..04f0059ae153e 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -1,9 +1,9 @@ { lib, coreutils, python3, gcc, writeText, writeScript, runCommand, makeBinaryWrapper }: let - env = { nativeBuildInputs = [ makeBinaryWrapper gcc ]; }; + env = { nativeBuildInputs = [ makeBinaryWrapper ]; }; envCheck = runCommand "envcheck" env '' - cc -o $out ${./envcheck.c} + ${gcc}/bin/cc -o $out ${./envcheck.c} ''; makeGoldenTest = testname: runCommand "test-wrapper_${testname}" env '' mkdir -p /tmp/foo diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 0e1dd457d8405..80e9275f98ed6 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -608,7 +608,9 @@ in makeBinaryWrapper = makeSetupHook { deps = [ dieHook ]; - } ../build-support/setup-hooks/make-binary-wrapper.sh; + } (runCommand "make-binary-wrapper.sh" {} '' + substitute ${../build-support/setup-hooks/make-binary-wrapper.sh} $out --replace " cc " " ${gcc}/bin/cc " + ''); makeModulesClosure = { kernel, firmware, rootModules, allowMissing ? false }: callPackage ../build-support/kernel/modules-closure.nix { -- cgit 1.4.1 From 177f0a6eedcf0b0ab74b845fd7cf77bde0997fbe Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Thu, 9 Dec 2021 11:31:35 +0000 Subject: make makeWrapper and makeBinaryWrapper drop-in-replaceable --- pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 14 +++++++------- pkgs/test/make-binary-wrapper/default.nix | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index ba9efa05191a3..a0c8cf59501e9 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -9,7 +9,7 @@ assertExecutable() { # Generate a binary executable wrapper for wrapping an executable. # The binary is compiled from generated C-code using gcc. -# makeBinaryWrapper EXECUTABLE OUT_PATH ARGS +# makeWrapper EXECUTABLE OUT_PATH ARGS # ARGS: # --argv0 NAME : set name of executed process to NAME @@ -29,13 +29,13 @@ assertExecutable() { # To troubleshoot a binary wrapper after you compiled it, # use the `strings` command or open the binary file in a text editor. -makeBinaryWrapper() { +makeWrapper() { assertExecutable "$1" makeDocumentedCWrapper "$1" "${@:3}" | cc -Os -x c -o "$2" - } -# Syntax: wrapProgramBinary -wrapProgramBinary() { +# Syntax: wrapProgram +wrapProgram() { local prog="$1" local hidden @@ -48,13 +48,13 @@ wrapProgramBinary() { mv "$prog" "$hidden" # Silence warning about unexpanded $0: # shellcheck disable=SC2016 - makeBinaryWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}" + makeWrapper "$hidden" "$prog" --inherit-argv0 "${@:2}" } # Generate source code for the wrapper in such a way that the wrapper source code # will still be readable even after compilation # makeDocumentedCWrapper EXECUTABLE ARGS -# ARGS: same as makeBinaryWrapper +# ARGS: same as makeWrapper makeDocumentedCWrapper() { local src docs src=$(makeCWrapper "$@") @@ -64,7 +64,7 @@ makeDocumentedCWrapper() { } # makeCWrapper EXECUTABLE ARGS -# ARGS: same as makeBinaryWrapper +# ARGS: same as makeWrapper makeCWrapper() { local argv0 inherit_argv0 n params cmd main flagsBefore flags executable params length local uses_prefix uses_suffix uses_assert uses_assert_success uses_stdio uses_asprintf diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index 04f0059ae153e..c9e045a4d9818 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -14,7 +14,7 @@ let diff wrapper.c "${./.}/${testname}.c" if [ -f "${./.}/${testname}.env" ]; then - eval "makeBinaryWrapper ${envCheck} wrapped $params" + eval "makeWrapper ${envCheck} wrapped $params" env -i ./wrapped > env.txt sed "s#SUBST_ARGV0#${envCheck}#;s#SUBST_CWD#$PWD#" \ "${./.}/${testname}.env" > golden-env.txt @@ -27,7 +27,7 @@ let fi else # without a golden env, we expect the wrapper compilation to fail - ! eval "makeBinaryWrapper ${envCheck} wrapped $params" &> error.txt + ! eval "makeWrapper ${envCheck} wrapped $params" &> error.txt fi cp wrapper.c $out -- cgit 1.4.1 From b7e00ed89ecf726f0860d2e305bbc12ca78398af Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Thu, 9 Dec 2021 15:45:35 +0000 Subject: make-binary-wrapper: Add -Wall -Werror -Wpedantic --- pkgs/build-support/setup-hooks/make-binary-wrapper.sh | 7 ++++++- pkgs/test/make-binary-wrapper/default.nix | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'pkgs/test') diff --git a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh index 2b6d316d81eb5..b0ed01de4cfa3 100644 --- a/pkgs/build-support/setup-hooks/make-binary-wrapper.sh +++ b/pkgs/build-support/setup-hooks/make-binary-wrapper.sh @@ -31,7 +31,12 @@ assertExecutable() { # use the `strings` command or open the binary file in a text editor. makeWrapper() { assertExecutable "$1" - makeDocumentedCWrapper "$1" "${@:3}" | cc -Os -x c -o "$2" - + makeDocumentedCWrapper "$1" "${@:3}" | \ + cc \ + -Wall -Werror -Wpedantic \ + -Os \ + -x c \ + -o "$2" - } # Syntax: wrapProgram diff --git a/pkgs/test/make-binary-wrapper/default.nix b/pkgs/test/make-binary-wrapper/default.nix index c9e045a4d9818..c5bb6970aac07 100644 --- a/pkgs/test/make-binary-wrapper/default.nix +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -3,7 +3,7 @@ let env = { nativeBuildInputs = [ makeBinaryWrapper ]; }; envCheck = runCommand "envcheck" env '' - ${gcc}/bin/cc -o $out ${./envcheck.c} + ${gcc}/bin/cc -Wall -Werror -Wpedantic -o $out ${./envcheck.c} ''; makeGoldenTest = testname: runCommand "test-wrapper_${testname}" env '' mkdir -p /tmp/foo -- cgit 1.4.1