From abb11fca1bcd7932d14c911d63fb7c6c347dcbcd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 8 Mar 2011 14:07:33 +0100 Subject: make fork_execv_on_steroids capable of setting env vars too Before, it could only unset them. Signed-off-by: Denys Vlasenko --- src/daemon/Daemon.cpp | 2 +- src/include/abrtlib.h | 9 +++++++-- src/lib/run_event.c | 14 +++++++++----- src/lib/spawn.c | 12 +++++++----- src/plugins/abrt-action-analyze-c.c | 2 +- src/plugins/abrt-action-generate-backtrace.c | 11 +++++------ src/plugins/abrt-action-mailx.c | 2 +- 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp index f791fb38..2d2c85ed 100644 --- a/src/daemon/Daemon.cpp +++ b/src/daemon/Daemon.cpp @@ -719,7 +719,7 @@ int main(int argc, char** argv) log_scanner_pid = fork_execv_on_steroids(EXECFLG_INPUT_NUL, (char**)scanner_argv, /*pipefds:*/ NULL, - /*unsetenv_vec:*/ NULL, + /*env_vec:*/ NULL, /*dir:*/ NULL, /*uid:*/ 0); VERB1 log("Started log scanner, pid:%d", (int)log_scanner_pid); diff --git a/src/include/abrtlib.h b/src/include/abrtlib.h index 435c4def..f64046d9 100644 --- a/src/include/abrtlib.h +++ b/src/include/abrtlib.h @@ -170,12 +170,17 @@ enum { EXECFLG_SETGUID = 1 << 7, EXECFLG_SETSID = 1 << 8, }; -/* Returns pid */ +/* + * env_vec: list of variables to set in environment (if string has + * "VAR=VAL" form) or unset in environment (if string has no '=' char). + * + * Returns pid. + */ #define fork_execv_on_steroids abrt_fork_execv_on_steroids pid_t fork_execv_on_steroids(int flags, char **argv, int *pipefds, - char **unsetenv_vec, + char **env_vec, const char *dir, uid_t uid); /* Returns malloc'ed string. NULs are retained, and extra one is appended diff --git a/src/lib/run_event.c b/src/lib/run_event.c index a2bbc76b..3d2b3a22 100644 --- a/src/lib/run_event.c +++ b/src/lib/run_event.c @@ -245,18 +245,19 @@ int spawn_next_command(struct run_event_state *state, VERB1 log("Executing '%s'", cmd); /* Export some useful environment variables for children */ + char *env_vec[3]; /* Just exporting dump_dir_name isn't always ok: it can be "." * and some children want to cd to other directory but still * be able to find dump directory by using $DUMP_DIR... */ char *full_name = realpath(dump_dir_name, NULL); - setenv("DUMP_DIR", (full_name ? full_name : dump_dir_name), 1); + env_vec[0] = xasprintf("DUMP_DIR=%s", (full_name ? full_name : dump_dir_name)); free(full_name); - setenv("EVENT", event, 1); -//FIXME: set vars in the child, not here! Need to improve fork_execv_on_steroids... + env_vec[1] = xasprintf("EVENT=%s", event); + env_vec[2] = NULL; char *argv[4]; - argv[0] = (char*)"/bin/sh"; + argv[0] = (char*)"/bin/sh"; // TODO: honor $SHELL? argv[1] = (char*)"-c"; argv[2] = cmd; argv[3] = NULL; @@ -266,12 +267,15 @@ int spawn_next_command(struct run_event_state *state, EXECFLG_INPUT_NUL + EXECFLG_OUTPUT + EXECFLG_ERR2OUT, argv, pipefds, - /* unsetenv_vec: */ NULL, + /* env_vec: */ env_vec, /* dir: */ dump_dir_name, /* uid(unused): */ 0 ); state->command_out_fd = pipefds[0]; + free(env_vec[0]); + free(env_vec[1]); + state->commands = g_list_remove(state->commands, cmd); return 0; diff --git a/src/lib/spawn.c b/src/lib/spawn.c index f6b7263c..188b63bd 100644 --- a/src/lib/spawn.c +++ b/src/lib/spawn.c @@ -32,7 +32,7 @@ static char *concat_str_vector(char **strings) pid_t fork_execv_on_steroids(int flags, char **argv, int *pipefds, - char **unsetenv_vec, + char **env_vec, const char *dir, uid_t uid) { @@ -69,9 +69,11 @@ pid_t fork_execv_on_steroids(int flags, xsetreuid(uid, uid); } - if (unsetenv_vec) { - while (*unsetenv_vec) - unsetenv(*unsetenv_vec++); + if (env_vec) { + /* Note: we use the glibc extension that putenv("var") + * *unsets* $var if "var" string has no '=' */ + while (*env_vec) + putenv(*env_vec++); } /* Play with stdio descriptors */ @@ -134,7 +136,7 @@ char *run_in_shell_and_save_output(int flags, const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; int pipeout[2]; pid_t child = fork_execv_on_steroids(flags, (char **)argv, pipeout, - /*unsetenv_vec:*/ NULL, dir, /*uid (unused):*/ 0); + /*env_vec:*/ NULL, dir, /*uid (unused):*/ 0); size_t pos = 0; char *result = NULL; diff --git a/src/plugins/abrt-action-analyze-c.c b/src/plugins/abrt-action-analyze-c.c index 5def9aa1..635a3316 100644 --- a/src/plugins/abrt-action-analyze-c.c +++ b/src/plugins/abrt-action-analyze-c.c @@ -63,7 +63,7 @@ static char *run_unstrip_n(const char *dump_dir_name, unsigned timeout_sec) args[1] = xasprintf("--core=%s/"FILENAME_COREDUMP, dump_dir_name); args[2] = (char*)"-n"; args[3] = NULL; - pid_t child = fork_execv_on_steroids(flags, args, pipeout, /*unsetenv_vec:*/ NULL, /*dir:*/ NULL, uid); + pid_t child = fork_execv_on_steroids(flags, args, pipeout, /*env_vec:*/ NULL, /*dir:*/ NULL, uid); free(args[1]); /* Bugs in unstrip or corrupted coredumps can cause it to enter infinite loop. diff --git a/src/plugins/abrt-action-generate-backtrace.c b/src/plugins/abrt-action-generate-backtrace.c index a8c18e36..7defc9c4 100644 --- a/src/plugins/abrt-action-generate-backtrace.c +++ b/src/plugins/abrt-action-generate-backtrace.c @@ -76,6 +76,11 @@ static char* exec_vp(char **args, uid_t uid, int redirect_stderr, int *status) "LC_MONETARY", "LC_NUMERIC", "LC_TIME", + /* Workaround for + * http://sourceware.org/bugzilla/show_bug.cgi?id=9622 + * (gdb emitting ESC sequences even with -batch) + */ + "TERM", NULL }; @@ -137,12 +142,6 @@ static char *get_backtrace(struct dump_dir *dd) char *executable = dd_load_text(dd, FILENAME_EXECUTABLE); dd_close(dd); - // Workaround for - // http://sourceware.org/bugzilla/show_bug.cgi?id=9622 - unsetenv("TERM"); - // This is not necessary - //putenv((char*)"TERM=dumb"); - char *args[21]; args[0] = (char*)"gdb"; args[1] = (char*)"-batch"; diff --git a/src/plugins/abrt-action-mailx.c b/src/plugins/abrt-action-mailx.c index 3debf449..06f81780 100644 --- a/src/plugins/abrt-action-mailx.c +++ b/src/plugins/abrt-action-mailx.c @@ -32,7 +32,7 @@ static void exec_and_feed_input(uid_t uid, const char* text, char **args) EXECFLG_INPUT | EXECFLG_QUIET | EXECFLG_SETGUID, args, pipein, - /*unsetenv_vec:*/ NULL, + /*env_vec:*/ NULL, /*dir:*/ NULL, uid); -- cgit