diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-05-19 21:51:53 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-05-19 21:51:53 +0200 |
commit | 6c666e26c580c062c95035761deb7bef0885e7a5 (patch) | |
tree | 5f69f414760be3a3d562d0ff7ce2b912668e772a | |
parent | 8783d2feaeb74fa37494b84024521a6e8a9b9276 (diff) |
load-fragment: add support for overriding argv[0] in parsed command lines
-rw-r--r-- | src/load-fragment.c | 50 | ||||
-rw-r--r-- | units/fedora/reboot.service | 2 |
2 files changed, 38 insertions, 14 deletions
diff --git a/src/load-fragment.c b/src/load-fragment.c index 148a579d99..5e0637de65 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -386,49 +386,73 @@ static int config_parse_exec( char *w; unsigned k; size_t l; - char *state; + char *state, *path = NULL; + bool honour_argv0, write_to_path; assert(filename); assert(lvalue); assert(rvalue); assert(data); + /* We accept an absolute path as first argument, or + * alternatively an absolute prefixed with @ to allow + * overriding of argv[0]. */ + + honour_argv0 = rvalue[0] == '@'; + + if (rvalue[honour_argv0 ? 1 : 0] != '/') { + log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue); + return -EINVAL; + } + k = 0; FOREACH_WORD_QUOTED(w, l, rvalue, state) k++; - if (!(n = new(char*, k+1))) + if (!(n = new(char*, k + (honour_argv0 ? 0 : 1)))) return -ENOMEM; k = 0; - FOREACH_WORD_QUOTED(w, l, rvalue, state) - if (!(n[k++] = strndup(w, l))) - goto fail; + write_to_path = honour_argv0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (write_to_path) { + if (!(path = strndup(w+1, l-1))) + goto fail; + write_to_path = false; + } else { + if (!(n[k++] = strndup(w, l))) + goto fail; + } + } n[k] = NULL; - if (!n[0] || !path_is_absolute(n[0])) { - log_error("[%s:%u] Invalid executable path in command line: %s", filename, line, rvalue); + if (!n[0]) { + log_error("[%s:%u] Invalid command line: %s", filename, line, rvalue); strv_free(n); return -EINVAL; } + if (!path) + if (!(path = strdup(n[0]))) + goto fail; + + assert(path_is_absolute(path)); + if (!(nce = new0(ExecCommand, 1))) goto fail; nce->argv = n; - if (!(nce->path = strdup(n[0]))) - goto fail; + nce->path = path; exec_command_append_list(e, nce); return 0; fail: - for (; k > 0; k--) - free(n[k-1]); - free(n); - + n[k] = NULL; + strv_free(n); + free(path); free(nce); return -ENOMEM; diff --git a/units/fedora/reboot.service b/units/fedora/reboot.service index da83fa067c..1b0df32581 100644 --- a/units/fedora/reboot.service +++ b/units/fedora/reboot.service @@ -24,4 +24,4 @@ After=shutdown.target killall.service Type=finish ValidNoProcess=yes Environment=RUNLEVEL=6 -ExecStart=/etc/init.d/reboot start +ExecStart=@/etc/init.d/halt reboot start |