core: open up all ExecXYZ= fields of service units to transient units
authorLennart Poettering <lennart@poettering.net>
Thu, 23 Nov 2017 16:58:34 +0000 (17:58 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 29 Nov 2017 11:34:12 +0000 (12:34 +0100)
Fixes: #7400

src/core/dbus-service.c
src/shared/bus-unit-util.c

index f08d318..8121765 100644 (file)
@@ -93,6 +93,7 @@ static int bus_service_set_transient_property(
                 UnitWriteFlags flags,
                 sd_bus_error *error) {
 
+        ServiceExecCommand ci;
         int r;
 
         assert(s);
@@ -236,7 +237,7 @@ static int bus_service_set_transient_property(
 
                 return 1;
 
-        } else if (streq(name, "ExecStart")) {
+        } else if ((ci = service_exec_command_from_string(name)) >= 0) {
                 unsigned n = 0;
 
                 r = sd_bus_message_enter_container(message, 'a', "(sasb)");
@@ -286,7 +287,7 @@ static int bus_service_set_transient_property(
                                 c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
 
                                 path_kill_slashes(c->path);
-                                exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
+                                exec_command_append_list(&s->exec_command[ci], c);
                         }
 
                         n++;
@@ -306,7 +307,7 @@ static int bus_service_set_transient_property(
                         size_t size = 0;
 
                         if (n == 0)
-                                s->exec_command[SERVICE_EXEC_START] = exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
+                                s->exec_command[ci] = exec_command_free_list(s->exec_command[ci]);
 
                         f = open_memstream(&buf, &size);
                         if (!f)
@@ -314,7 +315,7 @@ static int bus_service_set_transient_property(
 
                         fputs_unlocked("ExecStart=\n", f);
 
-                        LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
+                        LIST_FOREACH(command, c, s->exec_command[ci]) {
                                 _cleanup_free_ char *a = NULL, *t = NULL;
                                 const char *p;
 
@@ -326,7 +327,8 @@ static int bus_service_set_transient_property(
                                 if (!a)
                                         return -ENOMEM;
 
-                                fprintf(f, "ExecStart=%s@%s %s\n",
+                                fprintf(f, "%s=%s@%s %s\n",
+                                        name,
                                         c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "",
                                         p,
                                         a);
index 78b9a68..5e88866 100644 (file)
@@ -1205,6 +1205,94 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         return r;
 
                 r = sd_bus_message_close_container(m);
+
+        } else if (STR_IN_SET(field, "ExecStartPre", "ExecStart", "ExecStartPost",
+                              "ExecReload", "ExecStop", "ExecStopPost")) {
+
+                bool ignore_failure = false, explicit_path = false, done = false;
+                _cleanup_strv_free_ char **l = NULL;
+                _cleanup_free_ char *path = NULL;
+
+                do {
+                        switch (*eq) {
+
+                        case '-':
+                                if (ignore_failure)
+                                        done = true;
+                                else {
+                                        ignore_failure = true;
+                                        eq++;
+                                }
+                                break;
+
+                        case '@':
+                                if (explicit_path)
+                                        done = true;
+                                else {
+                                        explicit_path = true;
+                                        eq++;
+                                }
+                                break;
+
+                        case '+':
+                        case '!':
+                                /* The bus API doesn't support +, ! and !! currently, unfortunately. :-( */
+                                log_error("Sorry, but +, ! and !! are currently not supported for transient services.");
+                                return -EOPNOTSUPP;
+
+                        default:
+                                done = true;
+                                break;
+                        }
+                } while(!done);
+
+                if (explicit_path) {
+                        r = extract_first_word(&eq, &path, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse path: %m");
+                }
+
+                r = strv_split_extract(&l, eq, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse command line: %m");
+
+                r = sd_bus_message_open_container(m, 'v', "a(sasb)");
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_open_container(m, 'a', "(sasb)");
+                if (r < 0)
+                        return r;
+
+                if (strv_length(l) > 0) {
+
+                        r = sd_bus_message_open_container(m, 'r', "sasb");
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append(m, "s", path ?: l[0]);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append_strv(m, l);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_append(m, "b", ignore_failure);
+                        if (r < 0)
+                                return r;
+
+                        r = sd_bus_message_close_container(m);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_close_container(m);
+
         } else {
                 log_error("Unknown assignment %s.", assignment);
                 return -EINVAL;