Bug Summary

File:build-scan/../src/run/run.c
Warning:line 1336, column 40
Potential leak of memory pointed to by 'trigger'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name run.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I systemd-run.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/run/run.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <getopt.h>
4#include <stdio.h>
5
6#include "sd-bus.h"
7#include "sd-event.h"
8
9#include "alloc-util.h"
10#include "bus-error.h"
11#include "bus-unit-util.h"
12#include "bus-util.h"
13#include "calendarspec.h"
14#include "env-util.h"
15#include "fd-util.h"
16#include "format-util.h"
17#include "parse-util.h"
18#include "path-util.h"
19#include "process-util.h"
20#include "ptyfwd.h"
21#include "signal-util.h"
22#include "spawn-polkit-agent.h"
23#include "strv.h"
24#include "terminal-util.h"
25#include "unit-def.h"
26#include "unit-name.h"
27#include "user-util.h"
28
29static bool_Bool arg_ask_password = true1;
30static bool_Bool arg_scope = false0;
31static bool_Bool arg_remain_after_exit = false0;
32static bool_Bool arg_no_block = false0;
33static bool_Bool arg_wait = false0;
34static const char *arg_unit = NULL((void*)0);
35static const char *arg_description = NULL((void*)0);
36static const char *arg_slice = NULL((void*)0);
37static bool_Bool arg_send_sighup = false0;
38static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
39static const char *arg_host = NULL((void*)0);
40static bool_Bool arg_user = false0;
41static const char *arg_service_type = NULL((void*)0);
42static const char *arg_exec_user = NULL((void*)0);
43static const char *arg_exec_group = NULL((void*)0);
44static int arg_nice = 0;
45static bool_Bool arg_nice_set = false0;
46static char **arg_environment = NULL((void*)0);
47static char **arg_property = NULL((void*)0);
48static enum {
49 ARG_STDIO_NONE, /* The default, as it is for normal services, stdin connected to /dev/null, and stdout+stderr to the journal */
50 ARG_STDIO_PTY, /* Interactive behaviour, requested by --pty: we allocate a pty and connect it to the TTY we are invoked from */
51 ARG_STDIO_DIRECT, /* Directly pass our stdin/stdout/stderr to the activated service, useful for usage in shell pipelines, requested by --pipe */
52 ARG_STDIO_AUTO, /* If --pipe and --pty are used together we use --pty when invoked on a TTY, and --pipe otherwise */
53} arg_stdio = ARG_STDIO_NONE;
54static char **arg_path_property = NULL((void*)0);
55static char **arg_socket_property = NULL((void*)0);
56static char **arg_timer_property = NULL((void*)0);
57static bool_Bool with_timer = false0;
58static bool_Bool arg_quiet = false0;
59static bool_Bool arg_aggressive_gc = false0;
60
61static void help(void) {
62 printf("%s [OPTIONS...] {COMMAND} [ARGS...]\n\n"
63 "Run the specified command in a transient scope or service.\n\n"
64 " -h --help Show this help\n"
65 " --version Show package version\n"
66 " --no-ask-password Do not prompt for password\n"
67 " --user Run as user unit\n"
68 " -H --host=[USER@]HOST Operate on remote host\n"
69 " -M --machine=CONTAINER Operate on local container\n"
70 " --scope Run this as scope rather than service\n"
71 " --unit=UNIT Run under the specified unit name\n"
72 " -p --property=NAME=VALUE Set service or scope unit property\n"
73 " --description=TEXT Description for unit\n"
74 " --slice=SLICE Run in the specified slice\n"
75 " --no-block Do not wait until operation finished\n"
76 " -r --remain-after-exit Leave service around until explicitly stopped\n"
77 " --wait Wait until service stopped again\n"
78 " --send-sighup Send SIGHUP when terminating\n"
79 " --service-type=TYPE Service type\n"
80 " --uid=USER Run as system user\n"
81 " --gid=GROUP Run as system group\n"
82 " --nice=NICE Nice level\n"
83 " -E --setenv=NAME=VALUE Set environment\n"
84 " -t --pty Run service on pseudo TTY as STDIN/STDOUT/\n"
85 " STDERR\n"
86 " -P --pipe Pass STDIN/STDOUT/STDERR directly to service\n"
87 " -q --quiet Suppress information messages during runtime\n"
88 " -G --collect Unload unit after it ran, even when failed\n\n"
89 "Path options:\n"
90 " --path-property=NAME=VALUE Set path unit property\n\n"
91 "Socket options:\n"
92 " --socket-property=NAME=VALUE Set socket unit property\n\n"
93 "Timer options:\n"
94 " --on-active=SECONDS Run after SECONDS delay\n"
95 " --on-boot=SECONDS Run SECONDS after machine was booted up\n"
96 " --on-startup=SECONDS Run SECONDS after systemd activation\n"
97 " --on-unit-active=SECONDS Run SECONDS after the last activation\n"
98 " --on-unit-inactive=SECONDS Run SECONDS after the last deactivation\n"
99 " --on-calendar=SPEC Realtime timer\n"
100 " --timer-property=NAME=VALUE Set timer unit property\n"
101 , program_invocation_short_name);
102}
103
104static int add_timer_property(const char *name, const char *val) {
105 char *p;
106
107 assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/run/run.c", 107, __PRETTY_FUNCTION__
); } while (0)
;
108 assert(val)do { if ((__builtin_expect(!!(!(val)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("val"), "../src/run/run.c", 108, __PRETTY_FUNCTION__
); } while (0)
;
109
110 p = strjoin(name, "=", val)strjoin_real((name), "=", val, ((void*)0));
111 if (!p)
112 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 112, __func__
)
;
113
114 if (strv_consume(&arg_timer_property, p) < 0)
115 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 115, __func__
)
;
116
117 return 0;
118}
119
120static int parse_argv(int argc, char *argv[]) {
121
122 enum {
123 ARG_VERSION = 0x100,
124 ARG_USER,
125 ARG_SYSTEM,
126 ARG_SCOPE,
127 ARG_UNIT,
128 ARG_DESCRIPTION,
129 ARG_SLICE,
130 ARG_SEND_SIGHUP,
131 ARG_SERVICE_TYPE,
132 ARG_EXEC_USER,
133 ARG_EXEC_GROUP,
134 ARG_NICE,
135 ARG_ON_ACTIVE,
136 ARG_ON_BOOT,
137 ARG_ON_STARTUP,
138 ARG_ON_UNIT_ACTIVE,
139 ARG_ON_UNIT_INACTIVE,
140 ARG_ON_CALENDAR,
141 ARG_TIMER_PROPERTY,
142 ARG_PATH_PROPERTY,
143 ARG_SOCKET_PROPERTY,
144 ARG_NO_BLOCK,
145 ARG_NO_ASK_PASSWORD,
146 ARG_WAIT,
147 };
148
149 static const struct option options[] = {
150 { "help", no_argument0, NULL((void*)0), 'h' },
151 { "version", no_argument0, NULL((void*)0), ARG_VERSION },
152 { "user", no_argument0, NULL((void*)0), ARG_USER },
153 { "system", no_argument0, NULL((void*)0), ARG_SYSTEM },
154 { "scope", no_argument0, NULL((void*)0), ARG_SCOPE },
155 { "unit", required_argument1, NULL((void*)0), ARG_UNIT },
156 { "description", required_argument1, NULL((void*)0), ARG_DESCRIPTION },
157 { "slice", required_argument1, NULL((void*)0), ARG_SLICE },
158 { "remain-after-exit", no_argument0, NULL((void*)0), 'r' },
159 { "send-sighup", no_argument0, NULL((void*)0), ARG_SEND_SIGHUP },
160 { "host", required_argument1, NULL((void*)0), 'H' },
161 { "machine", required_argument1, NULL((void*)0), 'M' },
162 { "service-type", required_argument1, NULL((void*)0), ARG_SERVICE_TYPE },
163 { "wait", no_argument0, NULL((void*)0), ARG_WAIT },
164 { "uid", required_argument1, NULL((void*)0), ARG_EXEC_USER },
165 { "gid", required_argument1, NULL((void*)0), ARG_EXEC_GROUP },
166 { "nice", required_argument1, NULL((void*)0), ARG_NICE },
167 { "setenv", required_argument1, NULL((void*)0), 'E' },
168 { "property", required_argument1, NULL((void*)0), 'p' },
169 { "tty", no_argument0, NULL((void*)0), 't' }, /* deprecated alias */
170 { "pty", no_argument0, NULL((void*)0), 't' },
171 { "pipe", no_argument0, NULL((void*)0), 'P' },
172 { "quiet", no_argument0, NULL((void*)0), 'q' },
173 { "on-active", required_argument1, NULL((void*)0), ARG_ON_ACTIVE },
174 { "on-boot", required_argument1, NULL((void*)0), ARG_ON_BOOT },
175 { "on-startup", required_argument1, NULL((void*)0), ARG_ON_STARTUP },
176 { "on-unit-active", required_argument1, NULL((void*)0), ARG_ON_UNIT_ACTIVE },
177 { "on-unit-inactive", required_argument1, NULL((void*)0), ARG_ON_UNIT_INACTIVE },
178 { "on-calendar", required_argument1, NULL((void*)0), ARG_ON_CALENDAR },
179 { "timer-property", required_argument1, NULL((void*)0), ARG_TIMER_PROPERTY },
180 { "path-property", required_argument1, NULL((void*)0), ARG_PATH_PROPERTY },
181 { "socket-property", required_argument1, NULL((void*)0), ARG_SOCKET_PROPERTY },
182 { "no-block", no_argument0, NULL((void*)0), ARG_NO_BLOCK },
183 { "no-ask-password", no_argument0, NULL((void*)0), ARG_NO_ASK_PASSWORD },
184 { "collect", no_argument0, NULL((void*)0), 'G' },
185 {},
186 };
187
188 bool_Bool with_trigger = false0;
189 int r, c;
190
191 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/run/run.c", 191
, __PRETTY_FUNCTION__); } while (0)
;
192 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/run/run.c", 192, __PRETTY_FUNCTION__
); } while (0)
;
193
194 while ((c = getopt_long(argc, argv, "+hrH:M:E:p:tPqG", options, NULL((void*)0))) >= 0)
195
196 switch (c) {
197
198 case 'h':
199 help();
200 return 0;
201
202 case ARG_VERSION:
203 return version();
204
205 case ARG_NO_ASK_PASSWORD:
206 arg_ask_password = false0;
207 break;
208
209 case ARG_USER:
210 arg_user = true1;
211 break;
212
213 case ARG_SYSTEM:
214 arg_user = false0;
215 break;
216
217 case ARG_SCOPE:
218 arg_scope = true1;
219 break;
220
221 case ARG_UNIT:
222 arg_unit = optarg;
223 break;
224
225 case ARG_DESCRIPTION:
226 arg_description = optarg;
227 break;
228
229 case ARG_SLICE:
230 arg_slice = optarg;
231 break;
232
233 case ARG_SEND_SIGHUP:
234 arg_send_sighup = true1;
235 break;
236
237 case 'r':
238 arg_remain_after_exit = true1;
239 break;
240
241 case 'H':
242 arg_transport = BUS_TRANSPORT_REMOTE;
243 arg_host = optarg;
244 break;
245
246 case 'M':
247 arg_transport = BUS_TRANSPORT_MACHINE;
248 arg_host = optarg;
249 break;
250
251 case ARG_SERVICE_TYPE:
252 arg_service_type = optarg;
253 break;
254
255 case ARG_EXEC_USER:
256 arg_exec_user = optarg;
257 break;
258
259 case ARG_EXEC_GROUP:
260 arg_exec_group = optarg;
261 break;
262
263 case ARG_NICE:
264 r = parse_nice(optarg, &arg_nice);
265 if (r < 0)
266 return log_error_errno(r, "Failed to parse nice value: %s", optarg)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 266, __func__, "Failed to parse nice value: %s"
, optarg) : -abs(_e); })
;
267
268 arg_nice_set = true1;
269 break;
270
271 case 'E':
272 if (strv_extend(&arg_environment, optarg) < 0)
273 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 273, __func__
)
;
274
275 break;
276
277 case 'p':
278 if (strv_extend(&arg_property, optarg) < 0)
279 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 279, __func__
)
;
280
281 break;
282
283 case 't': /* --pty */
284 if (IN_SET(arg_stdio, ARG_STDIO_DIRECT, ARG_STDIO_AUTO)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){ARG_STDIO_DIRECT, ARG_STDIO_AUTO})/sizeof
(int)]; switch(arg_stdio) { case ARG_STDIO_DIRECT: case ARG_STDIO_AUTO
: _found = 1; break; default: break; } _found; })
) /* if --pipe is already used, upgrade to auto mode */
285 arg_stdio = ARG_STDIO_AUTO;
286 else
287 arg_stdio = ARG_STDIO_PTY;
288 break;
289
290 case 'P': /* --pipe */
291 if (IN_SET(arg_stdio, ARG_STDIO_PTY, ARG_STDIO_AUTO)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){ARG_STDIO_PTY, ARG_STDIO_AUTO})/sizeof(int
)]; switch(arg_stdio) { case ARG_STDIO_PTY: case ARG_STDIO_AUTO
: _found = 1; break; default: break; } _found; })
) /* If --pty is already used, upgrade to auto mode */
292 arg_stdio = ARG_STDIO_AUTO;
293 else
294 arg_stdio = ARG_STDIO_DIRECT;
295 break;
296
297 case 'q':
298 arg_quiet = true1;
299 break;
300
301 case ARG_ON_ACTIVE:
302 r = add_timer_property("OnActiveSec", optarg);
303 if (r < 0)
304 return r;
305
306 with_timer = true1;
307 break;
308
309 case ARG_ON_BOOT:
310 r = add_timer_property("OnBootSec", optarg);
311 if (r < 0)
312 return r;
313
314 with_timer = true1;
315 break;
316
317 case ARG_ON_STARTUP:
318 r = add_timer_property("OnStartupSec", optarg);
319 if (r < 0)
320 return r;
321
322 with_timer = true1;
323 break;
324
325 case ARG_ON_UNIT_ACTIVE:
326 r = add_timer_property("OnUnitActiveSec", optarg);
327 if (r < 0)
328 return r;
329
330 with_timer = true1;
331 break;
332
333 case ARG_ON_UNIT_INACTIVE:
334 r = add_timer_property("OnUnitInactiveSec", optarg);
335 if (r < 0)
336 return r;
337
338 with_timer = true1;
339 break;
340
341 case ARG_ON_CALENDAR:
342 r = add_timer_property("OnCalendar", optarg);
343 if (r < 0)
344 return r;
345
346 with_timer = true1;
347 break;
348
349 case ARG_TIMER_PROPERTY:
350
351 if (strv_extend(&arg_timer_property, optarg) < 0)
352 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 352, __func__
)
;
353
354 with_timer = with_timer ||
355 !!startswith(optarg, "OnActiveSec=") ||
356 !!startswith(optarg, "OnBootSec=") ||
357 !!startswith(optarg, "OnStartupSec=") ||
358 !!startswith(optarg, "OnUnitActiveSec=") ||
359 !!startswith(optarg, "OnUnitInactiveSec=") ||
360 !!startswith(optarg, "OnCalendar=");
361 break;
362
363 case ARG_PATH_PROPERTY:
364
365 if (strv_extend(&arg_path_property, optarg) < 0)
366 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 366, __func__
)
;
367
368 break;
369
370 case ARG_SOCKET_PROPERTY:
371
372 if (strv_extend(&arg_socket_property, optarg) < 0)
373 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 373, __func__
)
;
374
375 break;
376
377 case ARG_NO_BLOCK:
378 arg_no_block = true1;
379 break;
380
381 case ARG_WAIT:
382 arg_wait = true1;
383 break;
384
385 case 'G':
386 arg_aggressive_gc = true1;
387 break;
388
389 case '?':
390 return -EINVAL22;
391
392 default:
393 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled option"), "../src/run/run.c", 393, __PRETTY_FUNCTION__
); } while (0)
;
394 }
395
396 with_trigger = !!arg_path_property || !!arg_socket_property || with_timer;
397
398 /* currently, only single trigger (path, socket, timer) unit can be created simultaneously */
399 if ((int) !!arg_path_property + (int) !!arg_socket_property + (int) with_timer > 1) {
400 log_error("Only single trigger (path, socket, timer) unit can be created.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 400, __func__, "Only single trigger (path, socket, timer) unit can be created."
) : -abs(_e); })
;
401 return -EINVAL22;
402 }
403
404 if (arg_stdio == ARG_STDIO_AUTO) {
405 /* If we both --pty and --pipe are specified we'll automatically pick --pty if we are connected fully
406 * to a TTY and pick direct fd passing otherwise. This way, we automatically adapt to usage in a shell
407 * pipeline, but we are neatly interactive with tty-level isolation otherwise. */
408 arg_stdio = isatty(STDIN_FILENO0) && isatty(STDOUT_FILENO1) && isatty(STDERR_FILENO2) ?
409 ARG_STDIO_PTY :
410 ARG_STDIO_DIRECT;
411 }
412
413 if ((optind >= argc) && (!arg_unit || !with_trigger)) {
414 log_error("Command line to execute required.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 414, __func__, "Command line to execute required."
) : -abs(_e); })
;
415 return -EINVAL22;
416 }
417
418 if (arg_user && arg_transport != BUS_TRANSPORT_LOCAL) {
419 log_error("Execution in user context is not supported on non-local systems.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 419, __func__, "Execution in user context is not supported on non-local systems."
) : -abs(_e); })
;
420 return -EINVAL22;
421 }
422
423 if (arg_scope && arg_transport != BUS_TRANSPORT_LOCAL) {
424 log_error("Scope execution is not supported on non-local systems.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 424, __func__, "Scope execution is not supported on non-local systems."
) : -abs(_e); })
;
425 return -EINVAL22;
426 }
427
428 if (arg_scope && (arg_remain_after_exit || arg_service_type)) {
429 log_error("--remain-after-exit and --service-type= are not supported in --scope mode.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 429, __func__, "--remain-after-exit and --service-type= are not supported in --scope mode."
) : -abs(_e); })
;
430 return -EINVAL22;
431 }
432
433 if (arg_stdio != ARG_STDIO_NONE && (with_trigger || arg_scope)) {
434 log_error("--pty/--pipe is not compatible in timer or --scope mode.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 434, __func__, "--pty/--pipe is not compatible in timer or --scope mode."
) : -abs(_e); })
;
435 return -EINVAL22;
436 }
437
438 if (arg_stdio != ARG_STDIO_NONE && arg_transport == BUS_TRANSPORT_REMOTE) {
439 log_error("--pty/--pipe is only supported when connecting to the local system or containers.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 439, __func__, "--pty/--pipe is only supported when connecting to the local system or containers."
) : -abs(_e); })
;
440 return -EINVAL22;
441 }
442
443 if (arg_stdio != ARG_STDIO_NONE && arg_no_block) {
444 log_error("--pty/--pipe is not compatible with --no-block.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 444, __func__, "--pty/--pipe is not compatible with --no-block."
) : -abs(_e); })
;
445 return -EINVAL22;
446 }
447
448 if (arg_scope && with_trigger) {
449 log_error("Path, socket or timer options are not supported in --scope mode.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 449, __func__, "Path, socket or timer options are not supported in --scope mode."
) : -abs(_e); })
;
450 return -EINVAL22;
451 }
452
453 if (arg_timer_property && !with_timer) {
454 log_error("--timer-property= has no effect without any other timer options.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 454, __func__, "--timer-property= has no effect without any other timer options."
) : -abs(_e); })
;
455 return -EINVAL22;
456 }
457
458 if (arg_wait) {
459 if (arg_no_block) {
460 log_error("--wait may not be combined with --no-block.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 460, __func__, "--wait may not be combined with --no-block."
) : -abs(_e); })
;
461 return -EINVAL22;
462 }
463
464 if (with_trigger) {
465 log_error("--wait may not be combined with path, socket or timer operations.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 465, __func__, "--wait may not be combined with path, socket or timer operations."
) : -abs(_e); })
;
466 return -EINVAL22;
467 }
468
469 if (arg_scope) {
470 log_error("--wait may not be combined with --scope.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 470, __func__, "--wait may not be combined with --scope."
) : -abs(_e); })
;
471 return -EINVAL22;
472 }
473 }
474
475 return 1;
476}
477
478static int transient_unit_set_properties(sd_bus_message *m, UnitType t, char **properties) {
479 int r;
480
481 r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description);
482 if (r < 0)
483 return bus_log_create_error(r);
484
485 if (arg_aggressive_gc) {
486 r = sd_bus_message_append(m, "(sv)", "CollectMode", "s", "inactive-or-failed");
487 if (r < 0)
488 return bus_log_create_error(r);
489 }
490
491 r = bus_append_unit_property_assignment_many(m, t, properties);
492 if (r < 0)
493 return r;
494
495 return 0;
496}
497
498static int transient_cgroup_set_properties(sd_bus_message *m) {
499 int r;
500 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 500, __PRETTY_FUNCTION__
); } while (0)
;
501
502 if (!isempty(arg_slice)) {
503 _cleanup_free___attribute__((cleanup(freep))) char *slice = NULL((void*)0);
504
505 r = unit_name_mangle_with_suffix(arg_slice, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".slice", &slice);
506 if (r < 0)
507 return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 507, __func__, "Failed to mangle name '%s': %m"
, arg_slice) : -abs(_e); })
;
508
509 r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
510 if (r < 0)
511 return bus_log_create_error(r);
512 }
513
514 return 0;
515}
516
517static int transient_kill_set_properties(sd_bus_message *m) {
518 int r;
519
520 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 520, __PRETTY_FUNCTION__
); } while (0)
;
521
522 if (arg_send_sighup) {
523 r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
524 if (r < 0)
525 return bus_log_create_error(r);
526 }
527
528 return 0;
529}
530
531static int transient_service_set_properties(sd_bus_message *m, char **argv, const char *pty_path) {
532 bool_Bool send_term = false0;
533 int r;
534
535 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 535, __PRETTY_FUNCTION__
); } while (0)
;
536
537 r = transient_unit_set_properties(m, UNIT_SERVICE, arg_property);
538 if (r < 0)
539 return r;
540
541 r = transient_kill_set_properties(m);
542 if (r < 0)
543 return r;
544
545 r = transient_cgroup_set_properties(m);
546 if (r < 0)
547 return r;
548
549 if (arg_wait || arg_stdio != ARG_STDIO_NONE) {
550 r = sd_bus_message_append(m, "(sv)", "AddRef", "b", 1);
551 if (r < 0)
552 return bus_log_create_error(r);
553 }
554
555 if (arg_remain_after_exit) {
556 r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
557 if (r < 0)
558 return bus_log_create_error(r);
559 }
560
561 if (arg_service_type) {
562 r = sd_bus_message_append(m, "(sv)", "Type", "s", arg_service_type);
563 if (r < 0)
564 return bus_log_create_error(r);
565 }
566
567 if (arg_exec_user) {
568 r = sd_bus_message_append(m, "(sv)", "User", "s", arg_exec_user);
569 if (r < 0)
570 return bus_log_create_error(r);
571 }
572
573 if (arg_exec_group) {
574 r = sd_bus_message_append(m, "(sv)", "Group", "s", arg_exec_group);
575 if (r < 0)
576 return bus_log_create_error(r);
577 }
578
579 if (arg_nice_set) {
580 r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice);
581 if (r < 0)
582 return bus_log_create_error(r);
583 }
584
585 if (pty_path) {
586 r = sd_bus_message_append(m,
587 "(sv)(sv)(sv)(sv)",
588 "StandardInput", "s", "tty",
589 "StandardOutput", "s", "tty",
590 "StandardError", "s", "tty",
591 "TTYPath", "s", pty_path);
592 if (r < 0)
593 return bus_log_create_error(r);
594
595 send_term = true1;
596
597 } else if (arg_stdio == ARG_STDIO_DIRECT) {
598 r = sd_bus_message_append(m,
599 "(sv)(sv)(sv)",
600 "StandardInputFileDescriptor", "h", STDIN_FILENO0,
601 "StandardOutputFileDescriptor", "h", STDOUT_FILENO1,
602 "StandardErrorFileDescriptor", "h", STDERR_FILENO2);
603 if (r < 0)
604 return bus_log_create_error(r);
605
606 send_term = isatty(STDIN_FILENO0) || isatty(STDOUT_FILENO1) || isatty(STDERR_FILENO2);
607 }
608
609 if (send_term) {
610 const char *e;
611
612 e = getenv("TERM");
613 if (e) {
614 char *n;
615
616 n = strjoina("TERM=", e)({ const char *_appendees_[] = { "TERM=", e }; char *_d_, *_p_
; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
617 r = sd_bus_message_append(m,
618 "(sv)",
619 "Environment", "as", 1, n);
620 if (r < 0)
621 return bus_log_create_error(r);
622 }
623 }
624
625 if (!strv_isempty(arg_environment)) {
626 r = sd_bus_message_open_container(m, 'r', "sv");
627 if (r < 0)
628 return bus_log_create_error(r);
629
630 r = sd_bus_message_append(m, "s", "Environment");
631 if (r < 0)
632 return bus_log_create_error(r);
633
634 r = sd_bus_message_open_container(m, 'v', "as");
635 if (r < 0)
636 return bus_log_create_error(r);
637
638 r = sd_bus_message_append_strv(m, arg_environment);
639 if (r < 0)
640 return bus_log_create_error(r);
641
642 r = sd_bus_message_close_container(m);
643 if (r < 0)
644 return bus_log_create_error(r);
645
646 r = sd_bus_message_close_container(m);
647 if (r < 0)
648 return bus_log_create_error(r);
649 }
650
651 /* Exec container */
652 {
653 r = sd_bus_message_open_container(m, 'r', "sv");
654 if (r < 0)
655 return bus_log_create_error(r);
656
657 r = sd_bus_message_append(m, "s", "ExecStart");
658 if (r < 0)
659 return bus_log_create_error(r);
660
661 r = sd_bus_message_open_container(m, 'v', "a(sasb)");
662 if (r < 0)
663 return bus_log_create_error(r);
664
665 r = sd_bus_message_open_container(m, 'a', "(sasb)");
666 if (r < 0)
667 return bus_log_create_error(r);
668
669 r = sd_bus_message_open_container(m, 'r', "sasb");
670 if (r < 0)
671 return bus_log_create_error(r);
672
673 r = sd_bus_message_append(m, "s", argv[0]);
674 if (r < 0)
675 return bus_log_create_error(r);
676
677 r = sd_bus_message_append_strv(m, argv);
678 if (r < 0)
679 return bus_log_create_error(r);
680
681 r = sd_bus_message_append(m, "b", false0);
682 if (r < 0)
683 return bus_log_create_error(r);
684
685 r = sd_bus_message_close_container(m);
686 if (r < 0)
687 return bus_log_create_error(r);
688
689 r = sd_bus_message_close_container(m);
690 if (r < 0)
691 return bus_log_create_error(r);
692
693 r = sd_bus_message_close_container(m);
694 if (r < 0)
695 return bus_log_create_error(r);
696
697 r = sd_bus_message_close_container(m);
698 if (r < 0)
699 return bus_log_create_error(r);
700 }
701
702 return 0;
703}
704
705static int transient_scope_set_properties(sd_bus_message *m) {
706 int r;
707
708 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 708, __PRETTY_FUNCTION__
); } while (0)
;
709
710 r = transient_unit_set_properties(m, UNIT_SCOPE, arg_property);
711 if (r < 0)
712 return r;
713
714 r = transient_kill_set_properties(m);
715 if (r < 0)
716 return r;
717
718 r = transient_cgroup_set_properties(m);
719 if (r < 0)
720 return r;
721
722 r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid_cached());
723 if (r < 0)
724 return bus_log_create_error(r);
725
726 return 0;
727}
728
729static int transient_timer_set_properties(sd_bus_message *m) {
730 int r;
731
732 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 732, __PRETTY_FUNCTION__
); } while (0)
;
733
734 r = transient_unit_set_properties(m, UNIT_TIMER, arg_timer_property);
735 if (r < 0)
736 return r;
737
738 /* Automatically clean up our transient timers */
739 r = sd_bus_message_append(m, "(sv)", "RemainAfterElapse", "b", false0);
740 if (r < 0)
741 return bus_log_create_error(r);
742
743 return 0;
744}
745
746static int make_unit_name(sd_bus *bus, UnitType t, char **ret) {
747 const char *unique, *id;
748 char *p;
749 int r;
750
751 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/run/run.c", 751, __PRETTY_FUNCTION__
); } while (0)
;
752 assert(t >= 0)do { if ((__builtin_expect(!!(!(t >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t >= 0"), "../src/run/run.c", 752, __PRETTY_FUNCTION__
); } while (0)
;
753 assert(t < _UNIT_TYPE_MAX)do { if ((__builtin_expect(!!(!(t < _UNIT_TYPE_MAX)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("t < _UNIT_TYPE_MAX"), "../src/run/run.c"
, 753, __PRETTY_FUNCTION__); } while (0)
;
754
755 r = sd_bus_get_unique_name(bus, &unique);
756 if (r < 0) {
757 sd_id128_t rnd;
758
759 /* We couldn't get the unique name, which is a pretty
760 * common case if we are connected to systemd
761 * directly. In that case, just pick a random uuid as
762 * name */
763
764 r = sd_id128_randomize(&rnd);
765 if (r < 0)
766 return log_error_errno(r, "Failed to generate random run unit name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 766, __func__, "Failed to generate random run unit name: %m"
) : -abs(_e); })
;
767
768 if (asprintf(ret, "run-r" SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ".%s", SD_ID128_FORMAT_VAL(rnd)(rnd).bytes[0], (rnd).bytes[1], (rnd).bytes[2], (rnd).bytes[3
], (rnd).bytes[4], (rnd).bytes[5], (rnd).bytes[6], (rnd).bytes
[7], (rnd).bytes[8], (rnd).bytes[9], (rnd).bytes[10], (rnd).bytes
[11], (rnd).bytes[12], (rnd).bytes[13], (rnd).bytes[14], (rnd
).bytes[15]
, unit_type_to_string(t)) < 0)
769 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 769, __func__
)
;
770
771 return 0;
772 }
773
774 /* We managed to get the unique name, then let's use that to
775 * name our transient units. */
776
777 id = startswith(unique, ":1.");
778 if (!id) {
779 log_error("Unique name %s has unexpected format.", unique)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 779, __func__, "Unique name %s has unexpected format."
, unique) : -abs(_e); })
;
780 return -EINVAL22;
781 }
782
783 p = strjoin("run-u", id, ".", unit_type_to_string(t))strjoin_real(("run-u"), id, ".", unit_type_to_string(t), ((void
*)0))
;
784 if (!p)
785 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 785, __func__
)
;
786
787 *ret = p;
788 return 0;
789}
790
791typedef struct RunContext {
792 sd_bus *bus;
793 sd_event *event;
794 PTYForward *forward;
795 sd_bus_slot *match;
796
797 /* The exit data of the unit */
798 char *active_state;
799 uint64_t inactive_exit_usec;
800 uint64_t inactive_enter_usec;
801 char *result;
802 uint64_t cpu_usage_nsec;
803 uint64_t ip_ingress_bytes;
804 uint64_t ip_egress_bytes;
805 uint32_t exit_code;
806 uint32_t exit_status;
807} RunContext;
808
809static void run_context_free(RunContext *c) {
810 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/run/run.c", 810, __PRETTY_FUNCTION__
); } while (0)
;
811
812 c->forward = pty_forward_free(c->forward);
813 c->match = sd_bus_slot_unref(c->match);
814 c->bus = sd_bus_unref(c->bus);
815 c->event = sd_event_unref(c->event);
816
817 free(c->active_state);
818 free(c->result);
819}
820
821static void run_context_check_done(RunContext *c) {
822 bool_Bool done;
823
824 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/run/run.c", 824, __PRETTY_FUNCTION__
); } while (0)
;
825
826 if (c->match)
827 done = STRPTR_IN_SET(c->active_state, "inactive", "failed")({ const char* _x = (c->active_state); _x && (!!strv_find
((((char**) ((const char*[]) { "inactive", "failed", ((void*)
0) }))), (_x))); })
;
828 else
829 done = true1;
830
831 if (c->forward && done) /* If the service is gone, it's time to drain the output */
832 done = pty_forward_drain(c->forward);
833
834 if (done)
835 sd_event_exit(c->event, EXIT_SUCCESS0);
836}
837
838static int run_context_update(RunContext *c, const char *path) {
839
840 static const struct bus_properties_map map[] = {
841 { "ActiveState", "s", NULL((void*)0), offsetof(RunContext, active_state)__builtin_offsetof(RunContext, active_state) },
842 { "InactiveExitTimestampMonotonic", "t", NULL((void*)0), offsetof(RunContext, inactive_exit_usec)__builtin_offsetof(RunContext, inactive_exit_usec) },
843 { "InactiveEnterTimestampMonotonic", "t", NULL((void*)0), offsetof(RunContext, inactive_enter_usec)__builtin_offsetof(RunContext, inactive_enter_usec) },
844 { "Result", "s", NULL((void*)0), offsetof(RunContext, result)__builtin_offsetof(RunContext, result) },
845 { "ExecMainCode", "i", NULL((void*)0), offsetof(RunContext, exit_code)__builtin_offsetof(RunContext, exit_code) },
846 { "ExecMainStatus", "i", NULL((void*)0), offsetof(RunContext, exit_status)__builtin_offsetof(RunContext, exit_status) },
847 { "CPUUsageNSec", "t", NULL((void*)0), offsetof(RunContext, cpu_usage_nsec)__builtin_offsetof(RunContext, cpu_usage_nsec) },
848 { "IPIngressBytes", "t", NULL((void*)0), offsetof(RunContext, ip_ingress_bytes)__builtin_offsetof(RunContext, ip_ingress_bytes) },
849 { "IPEgressBytes", "t", NULL((void*)0), offsetof(RunContext, ip_egress_bytes)__builtin_offsetof(RunContext, ip_egress_bytes) },
850 {}
851 };
852
853 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
854 int r;
855
856 r = bus_map_all_properties(c->bus,
857 "org.freedesktop.systemd1",
858 path,
859 map,
860 BUS_MAP_STRDUP,
861 &error,
862 NULL((void*)0),
863 c);
864 if (r < 0) {
865 sd_event_exit(c->event, EXIT_FAILURE1);
866 return log_error_errno(r, "Failed to query unit state: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 866, __func__, "Failed to query unit state: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
867 }
868
869 run_context_check_done(c);
870 return 0;
871}
872
873static int on_properties_changed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
874 RunContext *c = userdata;
875
876 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/run/run.c", 876, __PRETTY_FUNCTION__
); } while (0)
;
877 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/run/run.c", 877, __PRETTY_FUNCTION__
); } while (0)
;
878
879 return run_context_update(c, sd_bus_message_get_path(m));
880}
881
882static int pty_forward_handler(PTYForward *f, int rcode, void *userdata) {
883 RunContext *c = userdata;
884
885 assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("f"), "../src/run/run.c", 885, __PRETTY_FUNCTION__
); } while (0)
;
886
887 if (rcode < 0) {
888 sd_event_exit(c->event, EXIT_FAILURE1);
889 return log_error_errno(rcode, "Error on PTY forwarding logic: %m")({ int _level = ((3)), _e = ((rcode)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 889, __func__, "Error on PTY forwarding logic: %m"
) : -abs(_e); })
;
890 }
891
892 run_context_check_done(c);
893 return 0;
894}
895
896static int start_transient_service(
897 sd_bus *bus,
898 char **argv,
899 int *retval) {
900
901 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0), *reply = NULL((void*)0);
902 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
903 _cleanup_(bus_wait_for_jobs_freep)__attribute__((cleanup(bus_wait_for_jobs_freep))) BusWaitForJobs *w = NULL((void*)0);
904 _cleanup_free___attribute__((cleanup(freep))) char *service = NULL((void*)0), *pty_path = NULL((void*)0);
905 _cleanup_close___attribute__((cleanup(closep))) int master = -1;
906 int r;
907
908 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/run/run.c", 908, __PRETTY_FUNCTION__
); } while (0)
;
909 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/run/run.c", 909, __PRETTY_FUNCTION__
); } while (0)
;
910 assert(retval)do { if ((__builtin_expect(!!(!(retval)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("retval"), "../src/run/run.c", 910, __PRETTY_FUNCTION__
); } while (0)
;
911
912 if (arg_stdio == ARG_STDIO_PTY) {
913
914 if (arg_transport == BUS_TRANSPORT_LOCAL) {
915 master = posix_openpt(O_RDWR02|O_NOCTTY0400|O_CLOEXEC02000000|O_NONBLOCK04000);
916 if (master < 0)
917 return log_error_errno(errno, "Failed to acquire pseudo tty: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 917, __func__, "Failed to acquire pseudo tty: %m"
) : -abs(_e); })
;
918
919 r = ptsname_malloc(master, &pty_path);
920 if (r < 0)
921 return log_error_errno(r, "Failed to determine tty name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 921, __func__, "Failed to determine tty name: %m"
) : -abs(_e); })
;
922
923 if (unlockpt(master) < 0)
924 return log_error_errno(errno, "Failed to unlock tty: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 924, __func__, "Failed to unlock tty: %m"
) : -abs(_e); })
;
925
926 } else if (arg_transport == BUS_TRANSPORT_MACHINE) {
927 _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *system_bus = NULL((void*)0);
928 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *pty_reply = NULL((void*)0);
929 const char *s;
930
931 r = sd_bus_default_system(&system_bus);
932 if (r < 0)
933 return log_error_errno(r, "Failed to connect to system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 933, __func__, "Failed to connect to system bus: %m"
) : -abs(_e); })
;
934
935 r = sd_bus_call_method(system_bus,
936 "org.freedesktop.machine1",
937 "/org/freedesktop/machine1",
938 "org.freedesktop.machine1.Manager",
939 "OpenMachinePTY",
940 &error,
941 &pty_reply,
942 "s", arg_host);
943 if (r < 0)
944 return log_error_errno(r, "Failed to get machine PTY: %s", bus_error_message(&error, -r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 944, __func__, "Failed to get machine PTY: %s"
, bus_error_message(&error, -r)) : -abs(_e); })
;
945
946 r = sd_bus_message_read(pty_reply, "hs", &master, &s);
947 if (r < 0)
948 return bus_log_parse_error(r);
949
950 master = fcntl(master, F_DUPFD_CLOEXEC1030, 3);
951 if (master < 0)
952 return log_error_errno(errno, "Failed to duplicate master fd: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 952, __func__, "Failed to duplicate master fd: %m"
) : -abs(_e); })
;
953
954 pty_path = strdup(s);
955 if (!pty_path)
956 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 956, __func__
)
;
957 } else
958 assert_not_reached("Can't allocate tty via ssh")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Can't allocate tty via ssh"), "../src/run/run.c", 958, __PRETTY_FUNCTION__
); } while (0)
;
959 }
960
961 if (!arg_no_block) {
962 r = bus_wait_for_jobs_new(bus, &w);
963 if (r < 0)
964 return log_error_errno(r, "Could not watch jobs: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 964, __func__, "Could not watch jobs: %m"
) : -abs(_e); })
;
965 }
966
967 if (arg_unit) {
968 r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".service", &service);
969 if (r < 0)
970 return log_error_errno(r, "Failed to mangle unit name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 970, __func__, "Failed to mangle unit name: %m"
) : -abs(_e); })
;
971 } else {
972 r = make_unit_name(bus, UNIT_SERVICE, &service);
973 if (r < 0)
974 return r;
975 }
976
977 r = sd_bus_message_new_method_call(
978 bus,
979 &m,
980 "org.freedesktop.systemd1",
981 "/org/freedesktop/systemd1",
982 "org.freedesktop.systemd1.Manager",
983 "StartTransientUnit");
984 if (r < 0)
985 return bus_log_create_error(r);
986
987 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
988 if (r < 0)
989 return bus_log_create_error(r);
990
991 /* Name and mode */
992 r = sd_bus_message_append(m, "ss", service, "fail");
993 if (r < 0)
994 return bus_log_create_error(r);
995
996 /* Properties */
997 r = sd_bus_message_open_container(m, 'a', "(sv)");
998 if (r < 0)
999 return bus_log_create_error(r);
1000
1001 r = transient_service_set_properties(m, argv, pty_path);
1002 if (r < 0)
1003 return r;
1004
1005 r = sd_bus_message_close_container(m);
1006 if (r < 0)
1007 return bus_log_create_error(r);
1008
1009 /* Auxiliary units */
1010 r = sd_bus_message_append(m, "a(sa(sv))", 0);
1011 if (r < 0)
1012 return bus_log_create_error(r);
1013
1014 polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
1015
1016 r = sd_bus_call(bus, m, 0, &error, &reply);
1017 if (r < 0)
1018 return log_error_errno(r, "Failed to start transient service unit: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1018, __func__, "Failed to start transient service unit: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1019
1020 if (w) {
1021 const char *object;
1022
1023 r = sd_bus_message_read(reply, "o", &object);
1024 if (r < 0)
1025 return bus_log_parse_error(r);
1026
1027 r = bus_wait_for_jobs_one(w, object, arg_quiet);
1028 if (r < 0)
1029 return r;
1030 }
1031
1032 if (!arg_quiet)
1033 log_info("Running as unit: %s", service)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1033, __func__, "Running as unit: %s", service
) : -abs(_e); })
;
1034
1035 if (arg_wait || arg_stdio != ARG_STDIO_NONE) {
1036 _cleanup_(run_context_free)__attribute__((cleanup(run_context_free))) RunContext c = {
1037 .cpu_usage_nsec = NSEC_INFINITY((nsec_t) -1),
1038 .ip_ingress_bytes = UINT64_MAX(18446744073709551615UL),
1039 .ip_egress_bytes = UINT64_MAX(18446744073709551615UL),
1040 .inactive_exit_usec = USEC_INFINITY((usec_t) -1),
1041 .inactive_enter_usec = USEC_INFINITY((usec_t) -1),
1042 };
1043 _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0);
1044
1045 c.bus = sd_bus_ref(bus);
1046
1047 r = sd_event_default(&c.event);
1048 if (r < 0)
1049 return log_error_errno(r, "Failed to get event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1049, __func__, "Failed to get event loop: %m"
) : -abs(_e); })
;
1050
1051 if (master >= 0) {
1052 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0)do { if ((__builtin_expect(!!(!(sigprocmask_many(0, ((void*)0
), 28, 15, 2, -1) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("sigprocmask_many(SIG_BLOCK, NULL, SIGWINCH, SIGTERM, SIGINT, -1) >= 0"
), "../src/run/run.c", 1052, __PRETTY_FUNCTION__); } while (0
)
;
1053 (void) sd_event_add_signal(c.event, NULL((void*)0), SIGINT2, NULL((void*)0), NULL((void*)0));
1054 (void) sd_event_add_signal(c.event, NULL((void*)0), SIGTERM15, NULL((void*)0), NULL((void*)0));
1055
1056 if (!arg_quiet)
1057 log_info("Press ^] three times within 1s to disconnect TTY.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1057, __func__, "Press ^] three times within 1s to disconnect TTY."
) : -abs(_e); })
;
1058
1059 r = pty_forward_new(c.event, master, PTY_FORWARD_IGNORE_INITIAL_VHANGUP, &c.forward);
1060 if (r < 0)
1061 return log_error_errno(r, "Failed to create PTY forwarder: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1061, __func__, "Failed to create PTY forwarder: %m"
) : -abs(_e); })
;
1062
1063 pty_forward_set_handler(c.forward, pty_forward_handler, &c);
1064
1065 /* Make sure to process any TTY events before we process bus events */
1066 (void) pty_forward_set_priority(c.forward, SD_EVENT_PRIORITY_IMPORTANT);
1067 }
1068
1069 path = unit_dbus_path_from_name(service);
1070 if (!path)
1071 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1071,
__func__)
;
1072
1073 r = sd_bus_match_signal_async(
1074 bus,
1075 &c.match,
1076 "org.freedesktop.systemd1",
1077 path,
1078 "org.freedesktop.DBus.Properties",
1079 "PropertiesChanged",
1080 on_properties_changed, NULL((void*)0), &c);
1081 if (r < 0)
1082 return log_error_errno(r, "Failed to request properties changed signal match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1082, __func__, "Failed to request properties changed signal match: %m"
) : -abs(_e); })
;
1083
1084 r = sd_bus_attach_event(bus, c.event, SD_EVENT_PRIORITY_NORMAL);
1085 if (r < 0)
1086 return log_error_errno(r, "Failed to attach bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1086, __func__, "Failed to attach bus to event loop: %m"
) : -abs(_e); })
;
1087
1088 r = run_context_update(&c, path);
1089 if (r < 0)
1090 return r;
1091
1092 r = sd_event_loop(c.event);
1093 if (r < 0)
1094 return log_error_errno(r, "Failed to run event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1094, __func__, "Failed to run event loop: %m"
) : -abs(_e); })
;
1095
1096 if (c.forward) {
1097 char last_char = 0;
1098
1099 r = pty_forward_get_last_char(c.forward, &last_char);
1100 if (r >= 0 && !arg_quiet && last_char != '\n')
1101 fputc('\n', stdoutstdout);
1102 }
1103
1104 if (arg_wait && !arg_quiet) {
1105
1106 /* Explicitly destroy the PTY forwarder, so that the PTY device is usable again, in its
1107 * original settings (i.e. proper line breaks), so that we can show the summary in a pretty
1108 * way. */
1109 c.forward = pty_forward_free(c.forward);
1110
1111 if (!isempty(c.result))
1112 log_info("Finished with result: %s", strna(c.result))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1112, __func__, "Finished with result: %s"
, strna(c.result)) : -abs(_e); })
;
1113
1114 if (c.exit_code == CLD_EXITEDCLD_EXITED)
1115 log_info("Main processes terminated with: code=%s/status=%i", sigchld_code_to_string(c.exit_code), c.exit_status)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1115, __func__, "Main processes terminated with: code=%s/status=%i"
, sigchld_code_to_string(c.exit_code), c.exit_status) : -abs(
_e); })
;
1116 else if (c.exit_code > 0)
1117 log_info("Main processes terminated with: code=%s/status=%s", sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1117, __func__, "Main processes terminated with: code=%s/status=%s"
, sigchld_code_to_string(c.exit_code), signal_to_string(c.exit_status
)) : -abs(_e); })
;
1118
1119 if (c.inactive_enter_usec > 0 && c.inactive_enter_usec != USEC_INFINITY((usec_t) -1) &&
1120 c.inactive_exit_usec > 0 && c.inactive_exit_usec != USEC_INFINITY((usec_t) -1) &&
1121 c.inactive_enter_usec > c.inactive_exit_usec) {
1122 char ts[FORMAT_TIMESPAN_MAX64];
1123 log_info("Service runtime: %s", format_timespan(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec, USEC_PER_MSEC))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1123, __func__, "Service runtime: %s", format_timespan
(ts, sizeof(ts), c.inactive_enter_usec - c.inactive_exit_usec
, ((usec_t) 1000ULL))) : -abs(_e); })
;
1124 }
1125
1126 if (c.cpu_usage_nsec != NSEC_INFINITY((nsec_t) -1)) {
1127 char ts[FORMAT_TIMESPAN_MAX64];
1128 log_info("CPU time consumed: %s", format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + NSEC_PER_USEC - 1) / NSEC_PER_USEC, USEC_PER_MSEC))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1128, __func__, "CPU time consumed: %s"
, format_timespan(ts, sizeof(ts), (c.cpu_usage_nsec + ((nsec_t
) 1000ULL) - 1) / ((nsec_t) 1000ULL), ((usec_t) 1000ULL))) : -
abs(_e); })
;
1129 }
1130
1131 if (c.ip_ingress_bytes != UINT64_MAX(18446744073709551615UL)) {
1132 char bytes[FORMAT_BYTES_MAX8];
1133 log_info("IP traffic received: %s", format_bytes(bytes, sizeof(bytes), c.ip_ingress_bytes))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1133, __func__, "IP traffic received: %s"
, format_bytes(bytes, sizeof(bytes), c.ip_ingress_bytes)) : -
abs(_e); })
;
1134 }
1135 if (c.ip_egress_bytes != UINT64_MAX(18446744073709551615UL)) {
1136 char bytes[FORMAT_BYTES_MAX8];
1137 log_info("IP traffic sent: %s", format_bytes(bytes, sizeof(bytes), c.ip_egress_bytes))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1137, __func__, "IP traffic sent: %s", format_bytes
(bytes, sizeof(bytes), c.ip_egress_bytes)) : -abs(_e); })
;
1138 }
1139 }
1140
1141 /* Try to propagate the service's return value */
1142 if (c.result && STR_IN_SET(c.result, "success", "exit-code")(!!strv_find((((char**) ((const char*[]) { "success", "exit-code"
, ((void*)0) }))), (c.result)))
&& c.exit_code == CLD_EXITEDCLD_EXITED)
1143 *retval = c.exit_status;
1144 else
1145 *retval = EXIT_FAILURE1;
1146 }
1147
1148 return 0;
1149}
1150
1151static int start_transient_scope(
1152 sd_bus *bus,
1153 char **argv) {
1154
1155 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1156 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0), *reply = NULL((void*)0);
1157 _cleanup_(bus_wait_for_jobs_freep)__attribute__((cleanup(bus_wait_for_jobs_freep))) BusWaitForJobs *w = NULL((void*)0);
1158 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **env = NULL((void*)0), **user_env = NULL((void*)0);
1159 _cleanup_free___attribute__((cleanup(freep))) char *scope = NULL((void*)0);
1160 const char *object = NULL((void*)0);
1161 int r;
1162
1163 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/run/run.c", 1163, __PRETTY_FUNCTION__
); } while (0)
;
1164 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/run/run.c", 1164, __PRETTY_FUNCTION__
); } while (0)
;
1165
1166 r = bus_wait_for_jobs_new(bus, &w);
1167 if (r < 0)
1168 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1168,
__func__)
;
1169
1170 if (arg_unit) {
1171 r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".scope", &scope);
1172 if (r < 0)
1173 return log_error_errno(r, "Failed to mangle scope name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1173, __func__, "Failed to mangle scope name: %m"
) : -abs(_e); })
;
1174 } else {
1175 r = make_unit_name(bus, UNIT_SCOPE, &scope);
1176 if (r < 0)
1177 return r;
1178 }
1179
1180 r = sd_bus_message_new_method_call(
1181 bus,
1182 &m,
1183 "org.freedesktop.systemd1",
1184 "/org/freedesktop/systemd1",
1185 "org.freedesktop.systemd1.Manager",
1186 "StartTransientUnit");
1187 if (r < 0)
1188 return bus_log_create_error(r);
1189
1190 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1191 if (r < 0)
1192 return bus_log_create_error(r);
1193
1194 /* Name and Mode */
1195 r = sd_bus_message_append(m, "ss", scope, "fail");
1196 if (r < 0)
1197 return bus_log_create_error(r);
1198
1199 /* Properties */
1200 r = sd_bus_message_open_container(m, 'a', "(sv)");
1201 if (r < 0)
1202 return bus_log_create_error(r);
1203
1204 r = transient_scope_set_properties(m);
1205 if (r < 0)
1206 return r;
1207
1208 r = sd_bus_message_close_container(m);
1209 if (r < 0)
1210 return bus_log_create_error(r);
1211
1212 /* Auxiliary units */
1213 r = sd_bus_message_append(m, "a(sa(sv))", 0);
1214 if (r < 0)
1215 return bus_log_create_error(r);
1216
1217 polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
1218
1219 r = sd_bus_call(bus, m, 0, &error, &reply);
1220 if (r < 0)
1221 return log_error_errno(r, "Failed to start transient scope unit: %s", bus_error_message(&error, -r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1221, __func__, "Failed to start transient scope unit: %s"
, bus_error_message(&error, -r)) : -abs(_e); })
;
1222
1223 if (arg_nice_set) {
1224 if (setpriority(PRIO_PROCESSPRIO_PROCESS, 0, arg_nice) < 0)
1225 return log_error_errno(errno, "Failed to set nice level: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 1225, __func__, "Failed to set nice level: %m"
) : -abs(_e); })
;
1226 }
1227
1228 if (arg_exec_group) {
1229 gid_t gid;
1230
1231 r = get_group_creds(&arg_exec_group, &gid);
1232 if (r < 0)
1233 return log_error_errno(r, "Failed to resolve group %s: %m", arg_exec_group)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1233, __func__, "Failed to resolve group %s: %m"
, arg_exec_group) : -abs(_e); })
;
1234
1235 if (setresgid(gid, gid, gid) < 0)
1236 return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 1236, __func__, "Failed to change GID to "
"%" "u" ": %m", gid) : -abs(_e); })
;
1237 }
1238
1239 if (arg_exec_user) {
1240 const char *home, *shell;
1241 uid_t uid;
1242 gid_t gid;
1243
1244 r = get_user_creds_clean(&arg_exec_user, &uid, &gid, &home, &shell);
1245 if (r < 0)
1246 return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1246, __func__, "Failed to resolve user %s: %m"
, arg_exec_user) : -abs(_e); })
;
1247
1248 if (home) {
1249 r = strv_extendf(&user_env, "HOME=%s", home);
1250 if (r < 0)
1251 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1251,
__func__)
;
1252 }
1253
1254 if (shell) {
1255 r = strv_extendf(&user_env, "SHELL=%s", shell);
1256 if (r < 0)
1257 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1257,
__func__)
;
1258 }
1259
1260 r = strv_extendf(&user_env, "USER=%s", arg_exec_user);
1261 if (r < 0)
1262 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1262,
__func__)
;
1263
1264 r = strv_extendf(&user_env, "LOGNAME=%s", arg_exec_user);
1265 if (r < 0)
1266 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1266,
__func__)
;
1267
1268 if (!arg_exec_group) {
1269 if (setresgid(gid, gid, gid) < 0)
1270 return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 1270, __func__, "Failed to change GID to "
"%" "u" ": %m", gid) : -abs(_e); })
;
1271 }
1272
1273 if (setresuid(uid, uid, uid) < 0)
1274 return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 1274, __func__, "Failed to change UID to "
"%" "u" ": %m", uid) : -abs(_e); })
;
1275 }
1276
1277 env = strv_env_merge(3, environ, user_env, arg_environment);
1278 if (!env)
1279 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1279,
__func__)
;
1280
1281 r = sd_bus_message_read(reply, "o", &object);
1282 if (r < 0)
1283 return bus_log_parse_error(r);
1284
1285 r = bus_wait_for_jobs_one(w, object, arg_quiet);
1286 if (r < 0)
1287 return r;
1288
1289 if (!arg_quiet)
1290 log_info("Running scope as unit: %s", scope)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1290, __func__, "Running scope as unit: %s"
, scope) : -abs(_e); })
;
1291
1292 execvpe(argv[0], argv, env);
1293
1294 return log_error_errno(errno, "Failed to execute: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/run/run.c", 1294, __func__, "Failed to execute: %m"
) : -abs(_e); })
;
1295}
1296
1297static int start_transient_trigger(
1298 sd_bus *bus,
1299 char **argv,
1300 const char *suffix) {
1301
1302 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1303 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0), *reply = NULL((void*)0);
1304 _cleanup_(bus_wait_for_jobs_freep)__attribute__((cleanup(bus_wait_for_jobs_freep))) BusWaitForJobs *w = NULL((void*)0);
1305 _cleanup_free___attribute__((cleanup(freep))) char *trigger = NULL((void*)0), *service = NULL((void*)0);
1306 const char *object = NULL((void*)0);
1307 int r;
1308
1309 assert(bus)do { if ((__builtin_expect(!!(!(bus)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bus"), "../src/run/run.c", 1309, __PRETTY_FUNCTION__
); } while (0)
;
1
Assuming 'bus' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
1310 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/run/run.c", 1310, __PRETTY_FUNCTION__
); } while (0)
;
4
Assuming 'argv' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
1311
1312 r = bus_wait_for_jobs_new(bus, &w);
1313 if (r < 0)
7
Assuming 'r' is >= 0
8
Taking false branch
1314 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1314,
__func__)
;
1315
1316 if (arg_unit) {
9
Assuming 'arg_unit' is non-null
10
Taking true branch
1317 switch (unit_name_to_type(arg_unit)) {
11
Control jumps to 'case UNIT_TIMER:' at line 1329
1318
1319 case UNIT_SERVICE:
1320 service = strdup(arg_unit);
1321 if (!service)
1322 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1322,
__func__)
;
1323
1324 r = unit_name_change_suffix(service, suffix, &trigger);
1325 if (r < 0)
1326 return log_error_errno(r, "Failed to change unit suffix: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1326, __func__, "Failed to change unit suffix: %m"
) : -abs(_e); })
;
1327 break;
1328
1329 case UNIT_TIMER:
1330 trigger = strdup(arg_unit);
12
Memory is allocated
1331 if (!trigger)
13
Assuming 'trigger' is non-null
14
Taking false branch
1332 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1332,
__func__)
;
1333
1334 r = unit_name_change_suffix(trigger, ".service", &service);
1335 if (r < 0)
15
Assuming 'r' is < 0
16
Taking true branch
1336 return log_error_errno(r, "Failed to change unit suffix: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1336, __func__, "Failed to change unit suffix: %m"
) : -abs(_e); })
;
17
Potential leak of memory pointed to by 'trigger'
1337 break;
1338
1339 default:
1340 r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, ".service", &service);
1341 if (r < 0)
1342 return log_error_errno(r, "Failed to mangle unit name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1342, __func__, "Failed to mangle unit name: %m"
) : -abs(_e); })
;
1343
1344 r = unit_name_mangle_with_suffix(arg_unit, arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, suffix, &trigger);
1345 if (r < 0)
1346 return log_error_errno(r, "Failed to mangle unit name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1346, __func__, "Failed to mangle unit name: %m"
) : -abs(_e); })
;
1347
1348 break;
1349 }
1350 } else {
1351 r = make_unit_name(bus, UNIT_SERVICE, &service);
1352 if (r < 0)
1353 return r;
1354
1355 r = unit_name_change_suffix(service, suffix, &trigger);
1356 if (r < 0)
1357 return log_error_errno(r, "Failed to change unit suffix: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1357, __func__, "Failed to change unit suffix: %m"
) : -abs(_e); })
;
1358 }
1359
1360 r = sd_bus_message_new_method_call(
1361 bus,
1362 &m,
1363 "org.freedesktop.systemd1",
1364 "/org/freedesktop/systemd1",
1365 "org.freedesktop.systemd1.Manager",
1366 "StartTransientUnit");
1367 if (r < 0)
1368 return bus_log_create_error(r);
1369
1370 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1371 if (r < 0)
1372 return bus_log_create_error(r);
1373
1374 /* Name and Mode */
1375 r = sd_bus_message_append(m, "ss", trigger, "fail");
1376 if (r < 0)
1377 return bus_log_create_error(r);
1378
1379 /* Properties */
1380 r = sd_bus_message_open_container(m, 'a', "(sv)");
1381 if (r < 0)
1382 return bus_log_create_error(r);
1383
1384 if (streq(suffix, ".path")(strcmp((suffix),(".path")) == 0))
1385 r = transient_unit_set_properties(m, UNIT_PATH, arg_path_property);
1386 else if (streq(suffix, ".socket")(strcmp((suffix),(".socket")) == 0))
1387 r = transient_unit_set_properties(m, UNIT_SOCKET, arg_socket_property);
1388 else if (streq(suffix, ".timer")(strcmp((suffix),(".timer")) == 0))
1389 r = transient_timer_set_properties(m);
1390 else
1391 assert_not_reached("Invalid suffix")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Invalid suffix"), "../src/run/run.c", 1391, __PRETTY_FUNCTION__
); } while (0)
;
1392 if (r < 0)
1393 return r;
1394
1395 r = sd_bus_message_close_container(m);
1396 if (r < 0)
1397 return bus_log_create_error(r);
1398
1399 r = sd_bus_message_open_container(m, 'a', "(sa(sv))");
1400 if (r < 0)
1401 return bus_log_create_error(r);
1402
1403 if (!strv_isempty(argv)) {
1404 r = sd_bus_message_open_container(m, 'r', "sa(sv)");
1405 if (r < 0)
1406 return bus_log_create_error(r);
1407
1408 r = sd_bus_message_append(m, "s", service);
1409 if (r < 0)
1410 return bus_log_create_error(r);
1411
1412 r = sd_bus_message_open_container(m, 'a', "(sv)");
1413 if (r < 0)
1414 return bus_log_create_error(r);
1415
1416 r = transient_service_set_properties(m, argv, NULL((void*)0));
1417 if (r < 0)
1418 return r;
1419
1420 r = sd_bus_message_close_container(m);
1421 if (r < 0)
1422 return bus_log_create_error(r);
1423
1424 r = sd_bus_message_close_container(m);
1425 if (r < 0)
1426 return bus_log_create_error(r);
1427 }
1428
1429 r = sd_bus_message_close_container(m);
1430 if (r < 0)
1431 return bus_log_create_error(r);
1432
1433 polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
1434
1435 r = sd_bus_call(bus, m, 0, &error, &reply);
1436 if (r < 0)
1437 return log_error_errno(r, "Failed to start transient %s unit: %s", suffix + 1, bus_error_message(&error, -r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1437, __func__, "Failed to start transient %s unit: %s"
, suffix + 1, bus_error_message(&error, -r)) : -abs(_e); }
)
;
1438
1439 r = sd_bus_message_read(reply, "o", &object);
1440 if (r < 0)
1441 return bus_log_parse_error(r);
1442
1443 r = bus_wait_for_jobs_one(w, object, arg_quiet);
1444 if (r < 0)
1445 return r;
1446
1447 if (!arg_quiet) {
1448 log_info("Running %s as unit: %s", suffix + 1, trigger)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1448, __func__, "Running %s as unit: %s"
, suffix + 1, trigger) : -abs(_e); })
;
1449 if (argv[0])
1450 log_info("Will run service as unit: %s", service)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1450, __func__, "Will run service as unit: %s"
, service) : -abs(_e); })
;
1451 }
1452
1453 return 0;
1454}
1455
1456int main(int argc, char* argv[]) {
1457 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
1458 _cleanup_free___attribute__((cleanup(freep))) char *description = NULL((void*)0), *command = NULL((void*)0);
1459 int r, retval = EXIT_SUCCESS0;
1460
1461 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
1462 log_open();
1463
1464 r = parse_argv(argc, argv);
1465 if (r <= 0)
1466 goto finish;
1467
1468 if (argc > optind && arg_transport == BUS_TRANSPORT_LOCAL) {
1469 /* Patch in an absolute path */
1470
1471 r = find_binary(argv[optind], &command);
1472 if (r < 0) {
1473 log_error_errno(r, "Failed to find executable %s: %m", argv[optind])({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1473, __func__, "Failed to find executable %s: %m"
, argv[optind]) : -abs(_e); })
;
1474 goto finish;
1475 }
1476
1477 argv[optind] = command;
1478 }
1479
1480 if (!arg_description) {
1481 description = strv_join(argv + optind, " ");
1482 if (!description) {
1483 r = log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/run/run.c", 1483,
__func__)
;
1484 goto finish;
1485 }
1486
1487 if (arg_unit && isempty(description)) {
1488 r = free_and_strdup(&description, arg_unit);
1489 if (r < 0)
1490 goto finish;
1491 }
1492
1493 arg_description = description;
1494 }
1495
1496 /* If --wait is used connect via the bus, unconditionally, as ref/unref is not supported via the limited direct
1497 * connection */
1498 if (arg_wait || arg_stdio != ARG_STDIO_NONE)
1499 r = bus_connect_transport(arg_transport, arg_host, arg_user, &bus);
1500 else
1501 r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
1502 if (r < 0) {
1503 log_error_errno(r, "Failed to create bus connection: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/run/run.c", 1503, __func__, "Failed to create bus connection: %m"
) : -abs(_e); })
;
1504 goto finish;
1505 }
1506
1507 if (arg_scope)
1508 r = start_transient_scope(bus, argv + optind);
1509 else if (arg_path_property)
1510 r = start_transient_trigger(bus, argv + optind, ".path");
1511 else if (arg_socket_property)
1512 r = start_transient_trigger(bus, argv + optind, ".socket");
1513 else if (with_timer)
1514 r = start_transient_trigger(bus, argv + optind, ".timer");
1515 else
1516 r = start_transient_service(bus, argv + optind, &retval);
1517
1518finish:
1519 strv_free(arg_environment);
1520 strv_free(arg_property);
1521 strv_free(arg_path_property);
1522 strv_free(arg_socket_property);
1523 strv_free(arg_timer_property);
1524
1525 return r < 0 ? EXIT_FAILURE1 : retval;
1526}