diff options
author | Robert Hensing <roberth@users.noreply.github.com> | 2021-12-10 00:45:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-10 00:45:30 +0100 |
commit | 9fb7d91888fa24a7f96fd1915da2d4bc5e9b834e (patch) | |
tree | 2fcea539901c914ae08d574e8e88e32ffa1aca33 /pkgs/test | |
parent | 296081d9fa5a0606de52c72c3a9f2eb19f42a6ca (diff) | |
parent | 39b0aa415c67b6bcaabbb7110344503cc184575a (diff) |
Merge pull request #124556 from bergkvist/bergkvist/make-c-wrapper
Generate tiny compiled binary for wrapping executables
Diffstat (limited to 'pkgs/test')
32 files changed, 318 insertions, 0 deletions
diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index e3ef7839c4b4d..b73617daa8952 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 {}; php = recurseIntoAttrs (callPackages ./php {}); 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..7ce682c6be647 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/add-flags.c @@ -0,0 +1,21 @@ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> + +int main(int argc, char **argv) { + char **argv_tmp = calloc(5 + argc, sizeof(*argv_tmp)); + assert(argv_tmp != NULL); + 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); +} 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 new file mode 100644 index 0000000000000..70c36889dc890 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/argv0.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + argv[0] = "alternative-name"; + 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 new file mode 100644 index 0000000000000..1c1266181377a --- /dev/null +++ b/pkgs/test/make-binary-wrapper/basic.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **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 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/basic.cmdline 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 new file mode 100644 index 0000000000000..c67c695b1c3b9 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/chdir.c @@ -0,0 +1,11 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + 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 new file mode 100644 index 0000000000000..e9ce5f1d72440 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/combination.c @@ -0,0 +1,53 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_prefix(char *env, char *sep, char *prefix) { + char *existing = getenv(env); + 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 *suffix) { + char *existing = getenv(env); + 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) { + assert_success(setenv("MESSAGE", "HELLO", 0)); + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + putenv("MESSAGE2=WORLD"); + + char **argv_tmp = calloc(4 + argc, sizeof(*argv_tmp)); + assert(argv_tmp != NULL); + 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("/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 new file mode 100644 index 0000000000000..c5bb6970aac07 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/default.nix @@ -0,0 +1,54 @@ +{ lib, coreutils, python3, gcc, writeText, writeScript, runCommand, makeBinaryWrapper }: + +let + env = { nativeBuildInputs = [ makeBinaryWrapper ]; }; + envCheck = runCommand "envcheck" env '' + ${gcc}/bin/cc -Wall -Werror -Wpedantic -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 "makeWrapper ${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 + # without a golden env, we expect the wrapper compilation to fail + ! eval "makeWrapper ${envCheck} wrapped $params" &> error.txt + fi + + 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: '' + "${test.name}" "${test}" + '') tests)} +'' // tests diff --git a/pkgs/test/make-binary-wrapper/env.c b/pkgs/test/make-binary-wrapper/env.c new file mode 100644 index 0000000000000..7e0422dee3bdc --- /dev/null +++ b/pkgs/test/make-binary-wrapper/env.c @@ -0,0 +1,14 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +int main(int argc, char **argv) { + putenv("PART1=HELLO"); + assert_success(setenv("PART2", "WORLD", 0)); + assert_success(unsetenv("SOME_OTHER_VARIABLE")); + putenv("PART3=\"!!\n\""); + 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 <limits.h> +#include <stdio.h> +#include <unistd.h> + +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/inherit-argv0.c b/pkgs/test/make-binary-wrapper/inherit-argv0.c new file mode 100644 index 0000000000000..e1c2bc926aa72 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/inherit-argv0.c @@ -0,0 +1,6 @@ +#include <unistd.h> +#include <stdlib.h> + +int main(int argc, char **argv) { + 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 new file mode 100644 index 0000000000000..4dfd36fb68a0b --- /dev/null +++ b/pkgs/test/make-binary-wrapper/invalid-env.c @@ -0,0 +1,14 @@ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } 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] = "/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 new file mode 100644 index 0000000000000..ea8fbdc64a84e --- /dev/null +++ b/pkgs/test/make-binary-wrapper/prefix.c @@ -0,0 +1,26 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_prefix(char *env, char *sep, char *prefix) { + char *existing = getenv(env); + 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) { + set_env_prefix("PATH", ":", "/usr/bin/"); + set_env_prefix("PATH", ":", "/usr/local/bin/"); + 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 new file mode 100644 index 0000000000000..d33f86c070ca5 --- /dev/null +++ b/pkgs/test/make-binary-wrapper/suffix.c @@ -0,0 +1,26 @@ +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <unistd.h> +#include <stdlib.h> +#include <assert.h> +#include <stdio.h> + +#define assert_success(e) do { if ((e) < 0) { perror(#e); abort(); } } while (0) + +void set_env_suffix(char *env, char *sep, char *suffix) { + char *existing = getenv(env); + 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) { + set_env_suffix("PATH", ":", "/usr/bin/"); + set_env_suffix("PATH", ":", "/usr/local/bin/"); + 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 |