X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Frun%2Frun.c;h=724d67d84610d23d8580756de021e0edd95f65eb;hb=15bd5aee092572116886f0f9381f3477f48241fb;hp=ef2015fe3c3e753d7cc5f622c63b164550c43819;hpb=e3e0314b56012f7febc279d268f2cadc1fcc0f25;p=elogind.git diff --git a/src/run/run.c b/src/run/run.c index ef2015fe3..724d67d84 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -39,6 +39,12 @@ static bool arg_send_sighup = false; static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static char *arg_host = NULL; static bool arg_user = false; +static const char *arg_service_type = NULL; +static const char *arg_exec_user = NULL; +static const char *arg_exec_group = NULL; +static int arg_nice = 0; +static bool arg_nice_set = false; +static char **arg_environment = NULL; static int help(void) { @@ -54,7 +60,12 @@ static int help(void) { " --description=TEXT Description for unit\n" " --slice=SLICE Run in the specified slice\n" " -r --remain-after-exit Leave service around until explicitly stopped\n" - " --send-sighup Send SIGHUP when terminating\n", + " --send-sighup Send SIGHUP when terminating\n" + " --service-type=TYPE Service type\n" + " --uid=USER Run as system user\n" + " --gid=GROUP Run as system group\n" + " --nice=NICE Nice level\n" + " --setenv=NAME=VALUE Set environment\n", program_invocation_short_name); return 0; @@ -71,25 +82,35 @@ static int parse_argv(int argc, char *argv[]) { ARG_DESCRIPTION, ARG_SLICE, ARG_SEND_SIGHUP, + ARG_EXEC_USER, + ARG_EXEC_GROUP, + ARG_SERVICE_TYPE, + ARG_NICE, + ARG_SETENV }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "user", no_argument, NULL, ARG_USER }, - { "system", no_argument, NULL, ARG_SYSTEM }, - { "scope", no_argument, NULL, ARG_SCOPE }, - { "unit", required_argument, NULL, ARG_UNIT }, - { "description", required_argument, NULL, ARG_DESCRIPTION }, - { "slice", required_argument, NULL, ARG_SLICE }, - { "remain-after-exit", no_argument, NULL, 'r' }, - { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP }, - { "host", required_argument, NULL, 'H' }, - { "machine", required_argument, NULL, 'M' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "scope", no_argument, NULL, ARG_SCOPE }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "description", required_argument, NULL, ARG_DESCRIPTION }, + { "slice", required_argument, NULL, ARG_SLICE }, + { "remain-after-exit", no_argument, NULL, 'r' }, + { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP }, + { "host", required_argument, NULL, 'H' }, + { "machine", required_argument, NULL, 'M' }, + { "service-type", required_argument, NULL, ARG_SERVICE_TYPE }, + { "uid", required_argument, NULL, ARG_EXEC_USER }, + { "gid", required_argument, NULL, ARG_EXEC_GROUP }, + { "nice", required_argument, NULL, ARG_NICE }, + { "setenv", required_argument, NULL, ARG_SETENV }, {}, }; - int c; + int r, c; assert(argc >= 0); assert(argv); @@ -148,6 +169,35 @@ static int parse_argv(int argc, char *argv[]) { arg_host = optarg; break; + case ARG_SERVICE_TYPE: + arg_service_type = optarg; + break; + + case ARG_EXEC_USER: + arg_exec_user = optarg; + break; + + case ARG_EXEC_GROUP: + arg_exec_group = optarg; + break; + + case ARG_NICE: + r = safe_atoi(optarg, &arg_nice); + if (r < 0) { + log_error("Failed to parse nice value"); + return -EINVAL; + } + + arg_nice_set = true; + break; + + case ARG_SETENV: + + if (strv_extend(&arg_environment, optarg) < 0) + return log_oom(); + + break; + case '?': return -EINVAL; @@ -171,6 +221,11 @@ static int parse_argv(int argc, char *argv[]) { return -EINVAL; } + if (arg_scope && (arg_remain_after_exit || arg_service_type || arg_exec_user || arg_exec_group || arg_nice_set || arg_environment)) { + log_error("--remain-after-exit, --service-type=, --user=, --group=, --nice= and --setenv= are not supported in --scope mode."); + return -EINVAL; + } + return 1; } @@ -208,7 +263,7 @@ static int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bu if (!isempty(arg_slice)) { _cleanup_free_ char *slice; - slice = unit_name_mangle_with_suffix(arg_slice, false, ".slice"); + slice = unit_name_mangle_with_suffix(arg_slice, MANGLE_NOGLOB, ".slice"); if (!slice) return -ENOMEM; @@ -251,11 +306,10 @@ static int start_transient_service( _cleanup_bus_message_unref_ sd_bus_message *m = NULL; _cleanup_free_ char *name = NULL; - char **i; int r; if (arg_unit) - name = unit_name_mangle_with_suffix(arg_unit, false, ".service"); + name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".service"); else asprintf(&name, "run-%lu.service", (unsigned long) getpid()); if (!name) @@ -269,6 +323,56 @@ static int start_transient_service( if (r < 0) return r; + if (arg_service_type) { + r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type); + if (r < 0) + return r; + } + + if (arg_exec_user) { + r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user); + if (r < 0) + return r; + } + + if (arg_exec_group) { + r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group); + if (r < 0) + return r; + } + + if (arg_nice_set) { + r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice); + if (r < 0) + return r; + } + + if (!strv_isempty(arg_environment)) { + r = sd_bus_message_open_container(m, 'r', "sv"); + if (r < 0) + return r; + + r = sd_bus_message_append(m, "s", "Environment"); + if (r < 0) + return r; + + r = sd_bus_message_open_container(m, 'v', "as"); + if (r < 0) + return r; + + r = sd_bus_message_append_strv(m, arg_environment); + 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_open_container(m, 'r', "sv"); if (r < 0) return r; @@ -293,17 +397,7 @@ static int start_transient_service( if (r < 0) return r; - r = sd_bus_message_open_container(m, 'a', "s"); - if (r < 0) - return r; - - STRV_FOREACH(i, argv) { - r = sd_bus_message_append(m, "s", *i); - if (r < 0) - return r; - } - - r = sd_bus_message_close_container(m); + r = sd_bus_message_append_strv(m, argv); if (r < 0) return r; @@ -342,7 +436,7 @@ static int start_transient_scope( assert(bus); if (arg_unit) - name = unit_name_mangle_with_suffix(arg_unit, false, ".scope"); + name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".scope"); else asprintf(&name, "run-%lu.scope", (unsigned long) getpid()); if (!name)