chiark / gitweb /
core: add transient units
[elogind.git] / src / run / run.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdio.h>
23
24 #include "sd-bus.h"
25 #include "bus-internal.h"
26 #include "bus-message.h"
27 #include "strv.h"
28
29 static int start_transient_service(
30                 sd_bus *bus,
31                 const char *name,
32                 char **argv,
33                 sd_bus_error *error) {
34
35         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
36         char **i;
37         int r;
38
39         r = sd_bus_message_new_method_call(
40                         bus,
41                         "org.freedesktop.systemd1",
42                         "/org/freedesktop/systemd1",
43                         "org.freedesktop.systemd1.Manager",
44                         "StartTransientUnit", &m);
45         if (r < 0)
46                 return r;
47
48         r = sd_bus_message_append(m, "ss", name, "fail");
49         if (r < 0)
50                 return r;
51
52         r = sd_bus_message_open_container(m, 'a', "(sv)");
53         if (r < 0)
54                 return r;
55
56         r = sd_bus_message_open_container(m, 'r', "sv");
57         if (r < 0)
58                 return r;
59
60         r = sd_bus_message_append(m, "s", "ExecStart");
61         if (r < 0)
62                 return r;
63
64         r = sd_bus_message_open_container(m, 'v', "a(sasb)");
65         if (r < 0)
66                 return r;
67
68         r = sd_bus_message_open_container(m, 'a', "(sasb)");
69         if (r < 0)
70                 return r;
71
72         r = sd_bus_message_open_container(m, 'r', "sasb");
73         if (r < 0)
74                 return r;
75
76         r = sd_bus_message_append(m, "s", argv[0]);
77         if (r < 0)
78                 return r;
79
80         r = sd_bus_message_open_container(m, 'a', "s");
81         if (r < 0)
82                 return r;
83
84         STRV_FOREACH(i, argv) {
85                 r = sd_bus_message_append(m, "s", *i);
86                 if (r < 0)
87                         return r;
88         }
89
90         r = sd_bus_message_close_container(m);
91         if (r < 0)
92                 return r;
93
94         r = sd_bus_message_append(m, "b", false);
95         if (r < 0)
96                 return r;
97
98         r = sd_bus_message_close_container(m);
99         if (r < 0)
100                 return r;
101
102         r = sd_bus_message_close_container(m);
103         if (r < 0)
104                 return r;
105
106         r = sd_bus_message_close_container(m);
107         if (r < 0)
108                 return r;
109
110         r = sd_bus_message_close_container(m);
111         if (r < 0)
112                 return r;
113
114         r = sd_bus_message_close_container(m);
115         if (r < 0)
116                 return r;
117
118         return sd_bus_send_with_reply_and_block(bus, m, 0, error, &reply);
119 }
120
121 int main(int argc, char* argv[]) {
122         sd_bus_error error = SD_BUS_ERROR_NULL;
123         _cleanup_bus_unref_ sd_bus *bus = NULL;
124         _cleanup_free_ char *name = NULL;
125         int r;
126
127         log_parse_environment();
128         log_open();
129
130         if (argc < 2) {
131                 log_error("Missing command line.");
132                 r = -EINVAL;
133                 goto fail;
134         }
135
136         r = sd_bus_open_user(&bus);
137         if (r < 0) {
138                 log_error("Failed to create new bus: %s", strerror(-r));
139                 goto fail;
140         }
141
142         if (asprintf(&name, "run-%lu.service", (unsigned long) getpid()) < 0) {
143                 r = log_oom();
144                 goto fail;
145         }
146
147         r = start_transient_service(bus, name, argv + 1, &error);
148         if (r < 0) {
149                 log_error("Failed start transient service: %s", error.message);
150                 sd_bus_error_free(&error);
151                 goto fail;
152         }
153
154 fail:
155         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
156 }