diff --git a/src/basic/util.h b/src/basic/util.h index 0d40db059ab..412563fa8e7 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -46,6 +46,11 @@ static inline const char* enable_disable(bool b) { extern int saved_argc; extern char **saved_argv; +static inline void save_argc_argv(int argc, char **argv) { + saved_argc = argc; + saved_argv = argv; +} + bool kexec_loaded(void); int prot_from_flags(int flags) _const_; diff --git a/src/core/main.c b/src/core/main.c index 981513bbc3b..6f6f4e5c5e5 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2380,8 +2380,7 @@ int main(int argc, char *argv[]) { (void) prctl(PR_SET_NAME, systemd); /* Save the original command line */ - saved_argv = argv; - saved_argc = argc; + save_argc_argv(argc, argv); /* Make sure that if the user says "syslog" we actually log to the journal. */ log_set_upgrade_syslog_to_journal(true); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f3842f70c65..dfc4f68ede4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4667,10 +4667,6 @@ static int run(int argc, char *argv[]) { log_parse_environment(); log_open(); - /* Make sure rename_process() in the stub init process can work */ - saved_argv = argv; - saved_argc = argc; - r = parse_argv(argc, argv); if (r <= 0) goto finish; diff --git a/src/shared/main-func.h b/src/shared/main-func.h index 3c182e802b9..1b77316d82e 100644 --- a/src/shared/main-func.h +++ b/src/shared/main-func.h @@ -8,17 +8,19 @@ #include "spawn-ask-password-agent.h" #include "spawn-polkit-agent.h" #include "static-destruct.h" +#include "util.h" #define _DEFINE_MAIN_FUNCTION(intro, impl, ret) \ int main(int argc, char *argv[]) { \ int r; \ + save_argc_argv(argc, argv); \ intro; \ r = impl; \ - static_destruct(); \ ask_password_agent_close(); \ polkit_agent_close(); \ - mac_selinux_finish(); \ pager_close(); \ + mac_selinux_finish(); \ + static_destruct(); \ return ret; \ } diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index afe6f84f774..9d2115b7121 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -141,7 +141,6 @@ static const char *arg_kill_who = NULL; static int arg_signal = SIGTERM; static char *arg_root = NULL; static usec_t arg_when = 0; -static char *argv_cmdline = NULL; static enum action { ACTION_SYSTEMCTL, ACTION_HALT, @@ -6177,10 +6176,11 @@ static int switch_root(int argc, char *argv[], void *userdata) { init = NULL; } - /* Instruct PID1 to exclude us from its killing spree applied during - * the transition. Otherwise we would exit with a failure status even - * though the switch to the new root has succeed. */ - argv_cmdline[0] = '@'; + /* Instruct PID1 to exclude us from its killing spree applied during the transition. Otherwise we + * would exit with a failure status even though the switch to the new root has succeed. */ + assert(saved_argv); + assert(saved_argv[0]); + saved_argv[0][0] = '@'; r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -6350,13 +6350,13 @@ static int enable_sysv_units(const char *verb, char **args) { const char *argv[] = { ROOTLIBEXECDIR "/systemd-sysv-install", - NULL, - NULL, - NULL, + NULL, /* --root= */ + NULL, /* verb */ + NULL, /* service */ NULL, }; - _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL; + _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL, *v = NULL; bool found_native = false, found_sysv; const char *name; unsigned c = 1; @@ -6397,10 +6397,21 @@ static int enable_sysv_units(const char *verb, char **args) { log_info("%s is not a native service, redirecting to systemd-sysv-install.", name); } - if (!isempty(arg_root)) - argv[c++] = q = strappend("--root=", arg_root); + if (!isempty(arg_root)) { + q = strappend("--root=", arg_root); + if (!q) + return log_oom(); - argv[c++] = verb; + argv[c++] = q; + } + + /* Let's copy the verb, since it's still pointing directly into the original argv[] array we + * got passed, but safe_fork() is likely going to rewrite that for the new child */ + v = strdup(verb); + if (!v) + return log_oom(); + + argv[c++] = v; argv[c++] = basename(p); argv[c] = NULL; @@ -6444,7 +6455,7 @@ static int enable_sysv_units(const char *verb, char **args) { assert(f > 0); f--; assert(args[f] == name); - strv_remove(args, name); + strv_remove(args + f, name); } #endif @@ -9161,8 +9172,6 @@ static int logind_cancel_shutdown(void) { static int run(int argc, char *argv[]) { int r; - argv_cmdline = argv[0]; - setlocale(LC_ALL, ""); log_parse_environment(); log_open(); diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index b5ba651d893..89f6618e2e8 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -603,8 +603,7 @@ static void test_ioprio_class_from_to_string(void) { int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); - saved_argc = argc; - saved_argv = argv; + save_argc_argv(argc, argv); if (argc > 1) { pid_t pid = 0;