chiark / gitweb /
systemd-run: properly escape arguments
[elogind.git] / src / core / dbus-service.c
index e93ac55115baa428ff5eb96818e6fb7c411622ff..696c4462fe257010dcd394afd4bea39e7060bdb6 100644 (file)
@@ -46,6 +46,7 @@
         "  <property name=\"StartLimitInterval\" type=\"t\" access=\"read\"/>\n" \
         "  <property name=\"StartLimitBurst\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"StartLimitAction\" type=\"s\" access=\"readwrite\"/>\n" \
+        BUS_UNIT_CGROUP_INTERFACE                                       \
         BUS_EXEC_COMMAND_INTERFACE("ExecStartPre")                      \
         BUS_EXEC_COMMAND_INTERFACE("ExecStart")                         \
         BUS_EXEC_COMMAND_INTERFACE("ExecStartPost")                     \
@@ -54,6 +55,7 @@
         BUS_EXEC_COMMAND_INTERFACE("ExecStopPost")                      \
         BUS_EXEC_CONTEXT_INTERFACE                                      \
         BUS_KILL_CONTEXT_INTERFACE                                      \
+        BUS_CGROUP_CONTEXT_INTERFACE                                    \
         "  <property name=\"PermissionsStartOnly\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"RootDirectoryStartOnly\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"RemainAfterExit\" type=\"b\" access=\"read\"/>\n" \
@@ -151,6 +153,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
 
         const BusBoundProperties bps[] = {
                 { "org.freedesktop.systemd1.Unit",    bus_unit_properties,             u },
+                { "org.freedesktop.systemd1.Service", bus_unit_cgroup_properties,      u },
                 { "org.freedesktop.systemd1.Service", bus_service_properties,          s },
                 { "org.freedesktop.systemd1.Service", bus_exec_context_properties,     &s->exec_context },
                 { "org.freedesktop.systemd1.Service", bus_kill_context_properties,     &s->kill_context },
@@ -164,7 +167,7 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio
         return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
 }
 
-static int bus_service_set_transient_properties(
+static int bus_service_set_transient_property(
                 Service *s,
                 const char *name,
                 DBusMessageIter *i,
@@ -177,7 +180,22 @@ static int bus_service_set_transient_properties(
         assert(s);
         assert(i);
 
-        if (streq(name, "ExecStart")) {
+        if (streq(name, "RemainAfterExit")) {
+                if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_BOOLEAN)
+                        return -EINVAL;
+
+                if (mode != UNIT_CHECK) {
+                        dbus_bool_t b;
+
+                        dbus_message_iter_get_basic(i, &b);
+
+                        s->remain_after_exit = b;
+                        unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
+                }
+
+                return 1;
+
+        } else if (streq(name, "ExecStart")) {
                 DBusMessageIter sub;
                 unsigned n = 0;
 
@@ -255,25 +273,20 @@ static int bus_service_set_transient_properties(
                         fputs("ExecStart=\n", f);
 
                         LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
-                                char **a;
-                                fputs("ExecStart=", f);
-
-                                if (c->ignore)
-                                        fputc('-', f);
+                                _cleanup_free_ char *a;
 
-                                fputc('@', f);
-                                fputs(c->path, f);
-
-                                STRV_FOREACH(a, c->argv) {
-                                        fputc(' ', f);
-                                        fputs(*a, f);
-                                }
+                                a = strv_join_quoted(c->argv);
+                                if (!a)
+                                        return -ENOMEM;
 
-                                fputc('\n', f);
+                                fprintf(f, "ExecStart=%s@%s %s\n",
+                                        c->ignore ? "-" : "",
+                                        c->path,
+                                        a);
                         }
 
                         fflush(f);
-                        unit_write_drop_in_private_section(UNIT(s), mode, "exec-start", buf);
+                        unit_write_drop_in_private(UNIT(s), mode, name, buf);
                 }
 
                 return 1;
@@ -303,7 +316,11 @@ int bus_service_set_property(
         if (u->transient && u->load_state == UNIT_STUB) {
                 /* This is a transient unit, let's load a little more */
 
-                r = bus_service_set_transient_properties(s, name, i, mode, error);
+                r = bus_service_set_transient_property(s, name, i, mode, error);
+                if (r != 0)
+                        return r;
+
+                r = bus_kill_context_set_transient_property(u, &s->kill_context, name, i, mode, error);
                 if (r != 0)
                         return r;
         }