exec-util: in execute_directories, support initial exec environment
This commit is contained in:
parent
f11aae7151
commit
78ec1bb436
|
@ -71,11 +71,12 @@ static int do_execute(
|
|||
gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
|
||||
void* const callback_args[_STDOUT_CONSUME_MAX],
|
||||
int output_fd,
|
||||
char *argv[]) {
|
||||
char *argv[],
|
||||
char *envp[]) {
|
||||
|
||||
_cleanup_hashmap_free_free_ Hashmap *pids = NULL;
|
||||
_cleanup_strv_free_ char **paths = NULL;
|
||||
char **path;
|
||||
char **path, **e;
|
||||
int r;
|
||||
|
||||
/* We fork this all off from a child process so that we can somewhat cleanly make
|
||||
|
@ -100,6 +101,9 @@ static int do_execute(
|
|||
if (timeout != USEC_INFINITY)
|
||||
alarm(DIV_ROUND_UP(timeout, USEC_PER_SEC));
|
||||
|
||||
STRV_FOREACH(e, envp)
|
||||
putenv(*e);
|
||||
|
||||
STRV_FOREACH(path, paths) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
@ -166,7 +170,8 @@ int execute_directories(
|
|||
usec_t timeout,
|
||||
gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
|
||||
void* const callback_args[_STDOUT_CONSUME_MAX],
|
||||
char *argv[]) {
|
||||
char *argv[],
|
||||
char *envp[]) {
|
||||
|
||||
char **dirs = (char**) directories;
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
@ -197,7 +202,7 @@ int execute_directories(
|
|||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv);
|
||||
r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv, envp);
|
||||
_exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ int execute_directories(
|
|||
usec_t timeout,
|
||||
gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
|
||||
void* const callback_args[_STDOUT_CONSUME_MAX],
|
||||
char *argv[]);
|
||||
char *argv[],
|
||||
char *envp[]);
|
||||
|
||||
extern const gather_stdout_callback_t gather_environment[_STDOUT_CONSUME_MAX];
|
||||
|
|
|
@ -3788,7 +3788,7 @@ static int manager_run_environment_generators(Manager *m) {
|
|||
if (!generator_path_any(paths))
|
||||
return 0;
|
||||
|
||||
return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
|
||||
return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, NULL);
|
||||
}
|
||||
|
||||
static int manager_run_generators(Manager *m) {
|
||||
|
@ -3820,7 +3820,7 @@ static int manager_run_generators(Manager *m) {
|
|||
|
||||
RUN_WITH_UMASK(0022)
|
||||
execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC,
|
||||
NULL, NULL, (char**) argv);
|
||||
NULL, NULL, (char**) argv, NULL);
|
||||
|
||||
finish:
|
||||
lookup_paths_trim_generator(&m->lookup_paths);
|
||||
|
|
|
@ -435,7 +435,7 @@ int main(int argc, char *argv[]) {
|
|||
arguments[0] = NULL;
|
||||
arguments[1] = arg_verb;
|
||||
arguments[2] = NULL;
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL);
|
||||
|
||||
if (can_initrd) {
|
||||
r = switch_root_initramfs();
|
||||
|
|
|
@ -167,7 +167,7 @@ static int execute(char **modes, char **states) {
|
|||
return log_error_errno(r, "Failed to write mode to /sys/power/disk: %m");;
|
||||
}
|
||||
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL);
|
||||
|
||||
log_struct(LOG_INFO,
|
||||
"MESSAGE_ID=" SD_MESSAGE_SLEEP_START_STR,
|
||||
|
@ -184,7 +184,7 @@ static int execute(char **modes, char **states) {
|
|||
"SLEEP=%s", arg_verb);
|
||||
|
||||
arguments[1] = (char*) "post";
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
@ -116,9 +117,9 @@ static void test_execute_directory(bool gather_stdout) {
|
|||
assert_se(chmod(mask2e, 0755) == 0);
|
||||
|
||||
if (gather_stdout)
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL, NULL);
|
||||
else
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL, NULL);
|
||||
|
||||
assert_se(chdir(template_lo) == 0);
|
||||
assert_se(access("it_works", F_OK) >= 0);
|
||||
|
@ -183,7 +184,7 @@ static void test_execution_order(void) {
|
|||
assert_se(chmod(override, 0755) == 0);
|
||||
assert_se(chmod(masked, 0755) == 0);
|
||||
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
|
||||
execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL, NULL);
|
||||
|
||||
assert_se(read_full_file(output, &contents, NULL) >= 0);
|
||||
assert_se(streq(contents, "30-override\n80-foo\n90-bar\nlast\n"));
|
||||
|
@ -265,7 +266,7 @@ static void test_stdout_gathering(void) {
|
|||
assert_se(chmod(name2, 0755) == 0);
|
||||
assert_se(chmod(name3, 0755) == 0);
|
||||
|
||||
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL);
|
||||
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
log_info("got: %s", output);
|
||||
|
@ -276,7 +277,7 @@ static void test_stdout_gathering(void) {
|
|||
static void test_environment_gathering(void) {
|
||||
char template[] = "/tmp/test-exec-util.XXXXXXX", **p;
|
||||
const char *dirs[] = {template, NULL};
|
||||
const char *name, *name2, *name3;
|
||||
const char *name, *name2, *name3, *old;
|
||||
int r;
|
||||
|
||||
char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
|
||||
|
@ -322,7 +323,16 @@ static void test_environment_gathering(void) {
|
|||
assert_se(chmod(name2, 0755) == 0);
|
||||
assert_se(chmod(name3, 0755) == 0);
|
||||
|
||||
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
|
||||
/* When booting in containers or without initramfs there might not be
|
||||
* any PATH in the environ and if there is no PATH /bin/sh built-in
|
||||
* PATH may leak and override systemd's DEFAULT_PATH which is not
|
||||
* good. Force our own PATH in environment, to prevent expansion of sh
|
||||
* built-in $PATH */
|
||||
old = getenv("PATH");
|
||||
r = setenv("PATH", "no-sh-built-in-path", 1);
|
||||
assert_se(r >= 0);
|
||||
|
||||
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
STRV_FOREACH(p, env)
|
||||
|
@ -331,7 +341,26 @@ static void test_environment_gathering(void) {
|
|||
assert_se(streq(strv_env_get(env, "A"), "22:23:24"));
|
||||
assert_se(streq(strv_env_get(env, "B"), "12"));
|
||||
assert_se(streq(strv_env_get(env, "C"), "001"));
|
||||
assert_se(endswith(strv_env_get(env, "PATH"), ":/no/such/file"));
|
||||
assert_se(streq(strv_env_get(env, "PATH"), "no-sh-built-in-path:/no/such/file"));
|
||||
|
||||
/* now retest with "default" path passed in, as created by
|
||||
* manager_default_environment */
|
||||
env = strv_free(env);
|
||||
env = strv_new("PATH=" DEFAULT_PATH, NULL);
|
||||
|
||||
r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, env);
|
||||
assert_se(r >= 0);
|
||||
|
||||
STRV_FOREACH(p, env)
|
||||
log_info("got env: \"%s\"", *p);
|
||||
|
||||
assert_se(streq(strv_env_get(env, "A"), "22:23:24"));
|
||||
assert_se(streq(strv_env_get(env, "B"), "12"));
|
||||
assert_se(streq(strv_env_get(env, "C"), "001"));
|
||||
assert_se(streq(strv_env_get(env, "PATH"), DEFAULT_PATH ":/no/such/file"));
|
||||
|
||||
/* reset environ PATH */
|
||||
(void) setenv("PATH", old, 1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
|
Loading…
Reference in New Issue