summaryrefslogtreecommitdiff
path: root/src/shared/bus-unit-util.c
diff options
context:
space:
mode:
authorAnita Zhang <the.anitazha@gmail.com>2019-02-20 14:53:58 -0800
committerAnita Zhang <the.anitazha@gmail.com>2019-05-30 20:41:42 -0700
commitb3d593673c5b8b0b7d781fd26ab2062ca6e7dbdb (patch)
treeb8c32bff31ac2b3336ceaeee6bc8588b4a09e4dd /src/shared/bus-unit-util.c
parent9e90465539345b25628edaa39f55489a9cfb7479 (diff)
downloadsystemd-b3d593673c5b8b0b7d781fd26ab2062ca6e7dbdb.tar.gz
core: add ExecStartXYZEx= with dbus support for executable prefixes
Closes #11654
Diffstat (limited to 'src/shared/bus-unit-util.c')
-rw-r--r--src/shared/bus-unit-util.c70
1 files changed, 56 insertions, 14 deletions
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index fb86391975..fd26b86359 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -9,6 +9,7 @@
#include "condition.h"
#include "cpu-set-util.h"
#include "escape.h"
+#include "exec-util.h"
#include "hexdecoct.h"
#include "hostname-util.h"
#include "in-addr-util.h"
@@ -244,19 +245,21 @@ static int bus_append_parse_size(sd_bus_message *m, const char *field, const cha
}
static int bus_append_exec_command(sd_bus_message *m, const char *field, const char *eq) {
- bool ignore_failure = false, explicit_path = false, done = false;
- _cleanup_strv_free_ char **l = NULL;
- _cleanup_free_ char *path = NULL;
+ bool explicit_path = false, done = false;
+ _cleanup_strv_free_ char **l = NULL, **ex_opts = NULL;
+ _cleanup_free_ char *path = NULL, *upgraded_name = NULL;
+ ExecCommandFlags flags = 0;
+ bool is_ex_prop = endswith(field, "Ex");
int r;
do {
switch (*eq) {
case '-':
- if (ignore_failure)
+ if (FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE))
done = true;
else {
- ignore_failure = true;
+ flags |= EXEC_COMMAND_IGNORE_FAILURE;
eq++;
}
break;
@@ -270,11 +273,36 @@ static int bus_append_exec_command(sd_bus_message *m, const char *field, const c
}
break;
+ case ':':
+ if (FLAGS_SET(flags, EXEC_COMMAND_NO_ENV_EXPAND))
+ done = true;
+ else {
+ flags |= EXEC_COMMAND_NO_ENV_EXPAND;
+ eq++;
+ }
+ break;
+
case '+':
+ if (flags & (EXEC_COMMAND_FULLY_PRIVILEGED|EXEC_COMMAND_NO_SETUID|EXEC_COMMAND_AMBIENT_MAGIC))
+ done = true;
+ else {
+ flags |= EXEC_COMMAND_FULLY_PRIVILEGED;
+ eq++;
+ }
+ break;
+
case '!':
- /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */
- return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
- "Sorry, but +, ! and !! are currently not supported for transient services.");
+ if (flags & (EXEC_COMMAND_FULLY_PRIVILEGED|EXEC_COMMAND_AMBIENT_MAGIC))
+ done = true;
+ else if (FLAGS_SET(flags, EXEC_COMMAND_NO_SETUID)) {
+ flags &= ~EXEC_COMMAND_NO_SETUID;
+ flags |= EXEC_COMMAND_AMBIENT_MAGIC;
+ eq++;
+ } else {
+ flags |= EXEC_COMMAND_NO_SETUID;
+ eq++;
+ }
+ break;
default:
done = true;
@@ -282,6 +310,20 @@ static int bus_append_exec_command(sd_bus_message *m, const char *field, const c
}
} while (!done);
+ if (!is_ex_prop && (flags & (EXEC_COMMAND_NO_ENV_EXPAND|EXEC_COMMAND_FULLY_PRIVILEGED|EXEC_COMMAND_NO_SETUID|EXEC_COMMAND_AMBIENT_MAGIC))) {
+ /* Upgrade the ExecXYZ= property to ExecXYZEx= for convenience */
+ is_ex_prop = true;
+ upgraded_name = strappend(field, "Ex");
+ if (!upgraded_name)
+ return log_oom();
+ }
+
+ if (is_ex_prop) {
+ r = exec_command_flags_to_strv(flags, &ex_opts);
+ if (r < 0)
+ return log_error_errno(r, "Failed to convert ExecCommandFlags to strv: %m");
+ }
+
if (explicit_path) {
r = extract_first_word(&eq, &path, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
if (r < 0)
@@ -296,21 +338,21 @@ static int bus_append_exec_command(sd_bus_message *m, const char *field, const c
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, upgraded_name ?: field);
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_message_open_container(m, 'v', "a(sasb)");
+ r = sd_bus_message_open_container(m, 'v', is_ex_prop ? "a(sasas)" : "a(sasb)");
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_message_open_container(m, 'a', "(sasb)");
+ r = sd_bus_message_open_container(m, 'a', is_ex_prop ? "(sasas)" : "(sasb)");
if (r < 0)
return bus_log_create_error(r);
if (!strv_isempty(l)) {
- r = sd_bus_message_open_container(m, 'r', "sasb");
+ r = sd_bus_message_open_container(m, 'r', is_ex_prop ? "sasas" : "sasb");
if (r < 0)
return bus_log_create_error(r);
@@ -322,7 +364,7 @@ static int bus_append_exec_command(sd_bus_message *m, const char *field, const c
if (r < 0)
return bus_log_create_error(r);
- r = sd_bus_message_append(m, "b", ignore_failure);
+ r = is_ex_prop ? sd_bus_message_append_strv(m, ex_opts) : sd_bus_message_append(m, "b", FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE));
if (r < 0)
return bus_log_create_error(r);
@@ -1351,8 +1393,8 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
if (STR_IN_SET(field,
"ExecStartPre", "ExecStart", "ExecStartPost",
+ "ExecStartPreEx", "ExecStartEx", "ExecStartPostEx",
"ExecReload", "ExecStop", "ExecStopPost"))
-
return bus_append_exec_command(m, field, eq);
if (STR_IN_SET(field, "RestartPreventExitStatus", "RestartForceExitStatus", "SuccessExitStatus")) {