From 237251ae9ca3a2f72cef9a92c590865660bcee8b Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Mon, 10 Jun 2013 17:10:44 +0200 Subject: [PATCH] Hook execvpe(), a GNU extension. --- configure.ac | 1 + src/coloredstderr.c | 10 ++++++++++ tests/example_exec.c | 32 ++++++++++++++++++++++++++++++++ tests/example_exec.expected | 10 ++++++++++ 4 files changed, 53 insertions(+) diff --git a/configure.ac b/configure.ac index 307b859..3efe25d 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,7 @@ AX_C___ATTRIBUTE__ AC_FUNC_FORK AC_CHECK_FUNCS([memmove setenv], [],[AC_MSG_ERROR([function is required])]) +AC_CHECK_FUNCS([execvpe]) dnl Thanks to gperftools' configure.ac (https://code.google.com/p/gperftools). AC_MSG_CHECKING([for __builtin_expect]) diff --git a/src/coloredstderr.c b/src/coloredstderr.c index e3cc1d6..d4ffdb6 100644 --- a/src/coloredstderr.c +++ b/src/coloredstderr.c @@ -536,3 +536,13 @@ int execvp(char const *file, char * const argv[]) { update_environment(); return real_execvp(file, argv); } + +#ifdef HAVE_EXECVPE +extern char **environ; +int execvpe(char const *file, char * const argv[], char * const envp[]) { + /* Fake the environment so we can reuse execvp(). */ + environ = (char **)envp; + + return execvp(file, argv); +} +#endif diff --git a/tests/example_exec.c b/tests/example_exec.c index bd12b5a..bd56700 100644 --- a/tests/example_exec.c +++ b/tests/example_exec.c @@ -19,6 +19,9 @@ #include +/* For execvpe(). */ +#define _GNU_SOURCE + #include #include #include @@ -269,6 +272,35 @@ int main(int argc unused, char **argv) { execvp(argv[0], args); return EXIT_FAILURE; + +#ifdef HAVE_EXECVPE + /* execvpe(3), but not testing the p(ath) part */ + } else if (!skip--) { + char *args[] = { argv0, NULL }; + char *envp[] = { "TEST=54", ldpreload, NULL }; + + execvpe(argv[0], args, envp); + return EXIT_FAILURE; + } else if (!skip--) { + char *args[] = { argv0, "foo", "bar", NULL }; + char *envp[] = { "TEST=55", ldpreload, NULL }; + + execvpe(argv[0], args, envp); + return EXIT_FAILURE; +#else + /* Fake output to let the test pass. */ + } else if (!skip--) { + puts("argv[0] = |./example_exec|"); + puts("environ[0] = |TEST=54|"); + puts("environ[2] = |COLORED_STDERR_FDS=2,|"); + puts(""); + puts("argv[0] = |./example_exec|"); + puts("argv[1] = |foo|"); + puts("argv[2] = |bar|"); + puts("environ[0] = |TEST=55|"); + puts("environ[2] = |COLORED_STDERR_FDS=2,|"); + puts(""); +#endif } printf("Done.\n"); diff --git a/tests/example_exec.expected b/tests/example_exec.expected index 9a8a6ce..c79a3de 100644 --- a/tests/example_exec.expected +++ b/tests/example_exec.expected @@ -101,4 +101,14 @@ environ[0] = |TEST=53| environ[1] = |FOO=| environ[3] = |COLORED_STDERR_FDS=2,| +argv[0] = |./example_exec| +environ[0] = |TEST=54| +environ[2] = |COLORED_STDERR_FDS=2,| + +argv[0] = |./example_exec| +argv[1] = |foo| +argv[2] = |bar| +environ[0] = |TEST=55| +environ[2] = |COLORED_STDERR_FDS=2,| + Done. -- 2.45.2