From c7040b5d1c2c148f12b6a5eef3dfce1661805131 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Feb 2014 02:02:00 +0100 Subject: core: allow User=, Group=, Nice=, Environment=, Type= to be passed when creating a transient service --- src/core/dbus-execute.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++ src/core/dbus-execute.h | 2 + src/core/dbus-kill.c | 18 +++++++ src/core/dbus-service.c | 24 ++++++++++ 4 files changed, 168 insertions(+) (limited to 'src/core') diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index edf84f89fd..d2bbda2dba 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -30,6 +30,7 @@ #include "execute.h" #include "dbus-execute.h" #include "capability.h" +#include "env-util.h" BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput); @@ -513,3 +514,126 @@ int bus_property_get_exec_command_list( return sd_bus_message_close_container(reply); } + +int bus_exec_context_set_transient_property( + Unit *u, + ExecContext *c, + const char *name, + sd_bus_message *message, + UnitSetPropertiesMode mode, + sd_bus_error *error) { + + int r; + + assert(u); + assert(c); + assert(name); + assert(message); + + if (streq(name, "User")) { + const char *uu; + + r = sd_bus_message_read(message, "s", &uu); + if (r < 0) + return r; + + if (mode != UNIT_CHECK) { + + if (isempty(uu)) { + free(c->user); + c->user = NULL; + } else { + char *t; + + t = strdup(uu); + if (!t) + return -ENOMEM; + + free(c->user); + c->user = t; + } + + unit_write_drop_in_private_format(u, mode, name, "User=%s\n", uu); + } + + return 1; + + } else if (streq(name, "Group")) { + const char *gg; + + r = sd_bus_message_read(message, "s", &gg); + if (r < 0) + return r; + + if (mode != UNIT_CHECK) { + + if (isempty(gg)) { + free(c->group); + c->group = NULL; + } else { + char *t; + + t = strdup(gg); + if (!t) + return -ENOMEM; + + free(c->group); + c->group = t; + } + + unit_write_drop_in_private_format(u, mode, name, "Group=%s\n", gg); + } + + return 1; + + } else if (streq(name, "Nice")) { + int n; + + r = sd_bus_message_read(message, "i", &n); + if (r < 0) + return r; + + if (n < PRIO_MIN || n >= PRIO_MAX) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range"); + + if (mode != UNIT_CHECK) { + c->nice = n; + unit_write_drop_in_private_format(u, mode, name, "Nice=%i\n", n); + } + + return 1; + + } else if (streq(name, "Environment")) { + + _cleanup_strv_free_ char **l = NULL; + + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + if (!strv_env_is_valid(l)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block."); + + if (mode != UNIT_CHECK) { + _cleanup_free_ char *joined; + char **e; + + e = strv_env_merge(2, c->environment, l); + if (!e) + return -ENOMEM; + + strv_free(c->environment); + c->environment = e; + + joined = strv_join(c->environment, " "); + if (!joined) + return -ENOMEM; + + unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined); + } + + return 1; + } + + return 0; +} diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index 5c8bc3063d..e4c2d5ddf6 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -42,3 +42,5 @@ extern const sd_bus_vtable bus_exec_vtable[]; int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); + +int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index 8d3e149f33..f3cfb226e8 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -70,6 +70,24 @@ int bus_kill_context_set_transient_property( return 1; + } else if (streq(name, "KillSignal")) { + int sig; + + r = sd_bus_message_read(message, "i", &sig); + if (r < 0) + return r; + + if (sig <= 0 || sig >= _NSIG) + return sd_bus_error_setf(error, "Signal %i out of range", sig); + + if (mode != UNIT_CHECK) { + c->kill_signal = sig; + + unit_write_drop_in_private_format(u, mode, name, "KillSignal=%s\n", signal_to_string(sig)); + } + + return 1; + } else if (streq(name, "SendSIGHUP")) { int b; diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 3db9339d45..73cf17541a 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -96,6 +96,25 @@ static int bus_service_set_transient_property( return 1; + } else if (streq(name, "Type")) { + const char *t; + ServiceType k; + + r = sd_bus_message_read(message, "s", &t); + if (r < 0) + return r; + + k = service_type_from_string(t); + if (k < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t); + + if (mode != UNIT_CHECK) { + s->type = k; + unit_write_drop_in_private_format(UNIT(s), mode, name, "Type=%s\n", service_type_to_string(s->type)); + } + + return 1; + } else if (streq(name, "ExecStart")) { unsigned n = 0; @@ -151,6 +170,7 @@ static int bus_service_set_transient_property( n++; } + if (r < 0) return r; @@ -223,6 +243,10 @@ int bus_service_set_property( if (r != 0) return r; + r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, mode, error); + if (r != 0) + return r; + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error); if (r != 0) return r; -- cgit v1.2.3-54-g00ecf