summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-05-19 21:51:53 +0200
committerLennart Poettering <lennart@poettering.net>2010-05-19 21:51:53 +0200
commit6c666e26c580c062c95035761deb7bef0885e7a5 (patch)
tree5f69f414760be3a3d562d0ff7ce2b912668e772a
parent8783d2feaeb74fa37494b84024521a6e8a9b9276 (diff)
load-fragment: add support for overriding argv[0] in parsed command lines
-rw-r--r--src/load-fragment.c50
-rw-r--r--units/fedora/reboot.service2
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