run.c revision e3e0314b56012f7febc279d268f2cadc1fcc0f25
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2013 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Lesser General Public License for more details.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmekstatic bool arg_scope = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic bool arg_remain_after_exit = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic const char *arg_description = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic bool arg_send_sighup = false;
de190aef08bb267b645205a747762df573b36834Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic bool arg_user = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int help(void) {
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poettering printf("%s [OPTIONS...] COMMAND [ARGS...]\n\n"
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering "Run the specified command in a transient scope or service unit.\n\n"
16e9f408fa9a9626059bdd6c89dc175e06b9e976Lennart Poettering " -h --help Show this help\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --version Show package version\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --user Run as user unit\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " -M --machine=CONTAINER Operate on local container\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --scope Run this as scope rather than service\n"
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering " --unit=UNIT Run under the specified unit name\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --description=TEXT Description for unit\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " --slice=SLICE Run in the specified slice\n"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering " -r --remain-after-exit Leave service around until explicitly stopped\n"
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering " --send-sighup Send SIGHUP when terminating\n",
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "version", no_argument, NULL, ARG_VERSION },
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier { "system", no_argument, NULL, ARG_SYSTEM },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering { "scope", no_argument, NULL, ARG_SCOPE },
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier { "unit", required_argument, NULL, ARG_UNIT },
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier { "description", required_argument, NULL, ARG_DESCRIPTION },
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier { "slice", required_argument, NULL, ARG_SLICE },
de190aef08bb267b645205a747762df573b36834Lennart Poettering { "remain-after-exit", no_argument, NULL, 'r' },
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP },
de190aef08bb267b645205a747762df573b36834Lennart Poettering { "machine", required_argument, NULL, 'M' },
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while ((c = getopt_long(argc, argv, "+hrH:M:", options, NULL)) >= 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek arg_transport = BUS_TRANSPORT_REMOTE;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek arg_transport = BUS_TRANSPORT_CONTAINER;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek assert_not_reached("Unhandled option");
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering log_error("Command line to execute required.");
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering if (arg_user && arg_transport != BUS_TRANSPORT_LOCAL) {
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering log_error("Execution in user context is not supported on non-local systems.");
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (arg_scope && arg_transport != BUS_TRANSPORT_LOCAL) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek log_error("Scope execution is not supported on non-local systems.");
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmekstatic int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bus_message **ret) {
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
if (!slice)
return -ENOMEM;
*ret = m;
m = NULL;
static int message_start_transient_unit_send(sd_bus *bus, sd_bus_message *m, sd_bus_error *error, sd_bus_message **reply) {
assert(m);
r = sd_bus_message_close_container(m);
static int start_transient_service(
char **argv,
if (arg_unit)
if (!name)
return -ENOMEM;
r = sd_bus_message_close_container(m);
r = sd_bus_message_close_container(m);
r = sd_bus_message_close_container(m);
r = sd_bus_message_close_container(m);
r = sd_bus_message_close_container(m);
static int start_transient_scope(
char **argv,
if (arg_unit)
if (!name)
return -ENOMEM;
return -errno;
log_open();
goto finish;
goto finish;
if (!arg_description) {
if (!description) {
r = log_oom();
goto finish;
goto finish;
if (arg_scope)