• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 19282013399

12 Nov 2025 12:00AM UTC coverage: 72.412% (+0.01%) from 72.402%
19282013399

push

github

web-flow
core/exec-credentials: port to new mount API, ensure atomicity for creds installation (#39637)

103 of 137 new or added lines in 4 files covered. (75.18%)

850 existing lines in 45 files now uncovered.

307170 of 424195 relevant lines covered (72.41%)

1105108.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.8
/src/systemctl/systemctl-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <fnmatch.h>
4
#include <unistd.h>
5

6
#include "sd-bus.h"
7
#include "sd-daemon.h"
8

9
#include "ask-password-agent.h"
10
#include "bus-common-errors.h"
11
#include "bus-locator.h"
12
#include "bus-map-properties.h"
13
#include "bus-unit-util.h"
14
#include "bus-util.h"
15
#include "chase.h"
16
#include "dropin.h"
17
#include "env-util.h"
18
#include "exit-status.h"
19
#include "format-table.h"
20
#include "format-util.h"
21
#include "glob-util.h"
22
#include "install.h"
23
#include "output-mode.h"
24
#include "path-lookup.h"
25
#include "path-util.h"
26
#include "pidref.h"
27
#include "polkit-agent.h"
28
#include "process-util.h"
29
#include "reboot-util.h"
30
#include "runtime-scope.h"
31
#include "set.h"
32
#include "stat-util.h"
33
#include "string-util.h"
34
#include "strv.h"
35
#include "systemctl.h"
36
#include "systemctl-util.h"
37
#include "unit-file.h"
38
#include "unit-name.h"
39
#include "verbs.h"
40

41
static sd_bus *buses[_BUS_FOCUS_MAX] = {};
42

43
int acquire_bus_full(BusFocus focus, bool graceful, sd_bus **ret) {
8,535✔
44
        int r;
8,535✔
45

46
        assert(focus < _BUS_FOCUS_MAX);
8,535✔
47
        assert(ret);
8,535✔
48

49
        if (!IN_SET(arg_runtime_scope, RUNTIME_SCOPE_SYSTEM, RUNTIME_SCOPE_USER))
8,535✔
UNCOV
50
                return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--global is not supported for this operation.");
×
51

52
        /* We only go directly to the manager, if we are using a local transport */
53
        if (!IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_CAPSULE))
8,535✔
54
                focus = BUS_FULL;
21✔
55

56
        if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0)
8,535✔
UNCOV
57
                focus = BUS_FULL;
×
58

59
        if (!buses[focus]) {
8,535✔
60
                if (focus == BUS_MANAGER)
8,421✔
61
                        r = bus_connect_transport_systemd(arg_transport, arg_host, arg_runtime_scope, &buses[focus]);
8,312✔
62
                else
63
                        r = bus_connect_transport(arg_transport, arg_host, arg_runtime_scope, &buses[focus]);
109✔
64
                if (r < 0)
8,421✔
UNCOV
65
                        return bus_log_connect_full(graceful && focus == BUS_FULL && r == -ECONNREFUSED ? LOG_DEBUG : LOG_ERR,
×
66
                                                    r, arg_transport, arg_runtime_scope);
67

68
                (void) sd_bus_set_allow_interactive_authorization(buses[focus], arg_ask_password);
8,421✔
69
        }
70

71
        *ret = buses[focus];
8,535✔
72
        return 0;
8,535✔
73
}
74

75
void release_busses(void) {
8,485✔
76
        FOREACH_ARRAY(w, buses, _BUS_FOCUS_MAX)
25,455✔
77
                *w = sd_bus_flush_close_unref(*w);
16,970✔
78
}
8,485✔
79

80
void ask_password_agent_open_maybe(void) {
2,639✔
81
        /* Open the password agent as a child process if necessary */
82

83
        if (arg_dry_run)
2,639✔
84
                return;
85

86
        if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)
2,635✔
87
                return;
88

89
        ask_password_agent_open_if_enabled(arg_transport, arg_ask_password);
2,618✔
90
}
91

92
void polkit_agent_open_maybe(void) {
3,518✔
93
        /* Open the polkit agent as a child process if necessary */
94

95
        if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)
3,518✔
96
                return;
97

98
        (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
3,312✔
99
}
100

101
int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
68✔
102
        assert(error);
68✔
103

104
        if (!sd_bus_error_is_set(error))
68✔
105
                return r;
106

107
        if (sd_bus_error_has_names(error, SD_BUS_ERROR_ACCESS_DENIED,
68✔
108
                                          BUS_ERROR_ONLY_BY_DEPENDENCY,
109
                                          BUS_ERROR_NO_ISOLATION,
110
                                          BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
111
                return EXIT_NOPERMISSION;
112

113
        if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
67✔
114
                return EXIT_NOTINSTALLED;
115

116
        if (sd_bus_error_has_names(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE,
30✔
117
                                          SD_BUS_ERROR_NOT_SUPPORTED))
118
                return EXIT_NOTIMPLEMENTED;
119

120
        if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
30✔
121
                return EXIT_NOTCONFIGURED;
122

123
        if (r != 0)
30✔
124
                return r;
30✔
125

126
        return EXIT_FAILURE;
127
}
128

129
int get_state_one_unit(sd_bus *bus, const char *unit, UnitActiveState *ret_active_state) {
4,027✔
UNCOV
130
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
131
        _cleanup_free_ char *buf = NULL, *dbus_path = NULL;
4,027✔
132
        UnitActiveState state;
4,027✔
133
        int r;
4,027✔
134

135
        assert(bus);
4,027✔
136
        assert(unit);
4,027✔
137
        assert(ret_active_state);
4,027✔
138

139
        dbus_path = unit_dbus_path_from_name(unit);
4,027✔
140
        if (!dbus_path)
4,027✔
UNCOV
141
                return log_oom();
×
142

143
        r = sd_bus_get_property_string(
4,027✔
144
                        bus,
145
                        "org.freedesktop.systemd1",
146
                        dbus_path,
147
                        "org.freedesktop.systemd1.Unit",
148
                        "ActiveState",
149
                        &error,
150
                        &buf);
151
        if (r < 0)
4,027✔
UNCOV
152
                return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r));
×
153

154
        state = unit_active_state_from_string(buf);
4,027✔
155
        if (state < 0)
4,027✔
UNCOV
156
                return log_error_errno(state, "Invalid unit state '%s' for: %s", buf, unit);
×
157

158
        *ret_active_state = state;
4,027✔
159
        return 0;
4,027✔
160
}
161

162
int get_sub_state_one_unit(sd_bus *bus, const char *unit, char **ret_sub_state) {
173✔
UNCOV
163
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
164
        _cleanup_free_ char *sub_state = NULL, *dbus_path = NULL;
173✔
165
        int r;
173✔
166

167
        assert(bus);
173✔
168
        assert(unit);
173✔
169
        assert(ret_sub_state);
173✔
170

171
        dbus_path = unit_dbus_path_from_name(unit);
173✔
172
        if (!dbus_path)
173✔
UNCOV
173
                return log_oom();
×
174

175
        r = sd_bus_get_property_string(
173✔
176
                        bus,
177
                        "org.freedesktop.systemd1",
178
                        dbus_path,
179
                        "org.freedesktop.systemd1.Unit",
180
                        "SubState",
181
                        &error,
182
                        &sub_state);
183
        if (r < 0)
173✔
UNCOV
184
                return log_error_errno(r, "Failed to retrieve unit sub state: %s", bus_error_message(&error, r));
×
185

186
        *ret_sub_state = TAKE_PTR(sub_state);
173✔
187
        return 0;
173✔
188
}
189

190
int get_unit_list(
107✔
191
                sd_bus *bus,
192
                const char *machine,
193
                char **patterns,
194
                UnitInfo **unit_infos,
195
                int c,
196
                sd_bus_message **ret_reply) {
197

198
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
107✔
UNCOV
199
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
200
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
107✔
201
        int r;
107✔
202
        bool fallback = false;
107✔
203

204
        assert(bus);
107✔
205
        assert(unit_infos);
107✔
206
        assert(ret_reply);
107✔
207

208
        r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "ListUnitsByPatterns");
107✔
209
        if (r < 0)
107✔
UNCOV
210
                return bus_log_create_error(r);
×
211

212
        r = sd_bus_message_append_strv(m, arg_states);
107✔
213
        if (r < 0)
107✔
UNCOV
214
                return bus_log_create_error(r);
×
215

216
        r = sd_bus_message_append_strv(m, patterns);
107✔
217
        if (r < 0)
107✔
UNCOV
218
                return bus_log_create_error(r);
×
219

220
        r = sd_bus_call(bus, m, 0, &error, &reply);
107✔
221
        if (r < 0 && (sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_METHOD,
107✔
222
                                                     SD_BUS_ERROR_ACCESS_DENIED))) {
223
                /* Fallback to legacy ListUnitsFiltered method */
224
                fallback = true;
×
225
                log_debug_errno(r, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error, r));
×
226
                m = sd_bus_message_unref(m);
×
UNCOV
227
                sd_bus_error_free(&error);
×
228

229
                r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "ListUnitsFiltered");
×
230
                if (r < 0)
×
UNCOV
231
                        return bus_log_create_error(r);
×
232

233
                r = sd_bus_message_append_strv(m, arg_states);
×
234
                if (r < 0)
×
UNCOV
235
                        return bus_log_create_error(r);
×
236

UNCOV
237
                r = sd_bus_call(bus, m, 0, &error, &reply);
×
238
        }
239
        if (r < 0)
×
UNCOV
240
                return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r));
×
241

242
        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
107✔
243
        if (r < 0)
107✔
UNCOV
244
                return bus_log_parse_error(r);
×
245

246
        for (;;) {
11,556✔
247
                UnitInfo u;
11,556✔
248

249
                r = bus_parse_unit_info(reply, &u);
11,556✔
250
                if (r < 0)
11,556✔
UNCOV
251
                        return bus_log_parse_error(r);
×
252
                if (r == 0)
11,556✔
253
                        break;
254

255
                u.machine = machine;
11,449✔
256

257
                if (!output_show_unit(&u, fallback ? patterns : NULL))
22,898✔
258
                        continue;
1,569✔
259

260
                if (!GREEDY_REALLOC(*unit_infos, c+1))
9,880✔
UNCOV
261
                        return log_oom();
×
262

263
                (*unit_infos)[c++] = u;
9,880✔
264
        }
265

266
        r = sd_bus_message_exit_container(reply);
107✔
267
        if (r < 0)
107✔
UNCOV
268
                return bus_log_parse_error(r);
×
269

270
        *ret_reply = TAKE_PTR(reply);
107✔
271
        return c;
107✔
272
}
273

274
int expand_unit_names(
7,101✔
275
                sd_bus *bus,
276
                char * const *names,
277
                const char *suffix,
278
                char ***ret,
279
                bool *ret_expanded) {
280

281
        _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
7,101✔
282
        int r;
7,101✔
283

284
        assert(bus);
7,101✔
285
        assert(ret);
7,101✔
286

287
        STRV_FOREACH(name, names) {
14,295✔
288
                UnitNameMangle options = UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN);
7,194✔
289
                char *t;
7,194✔
290

291
                r = unit_name_mangle_with_suffix(*name, NULL, options, suffix ?: ".service", &t);
14,386✔
292
                if (r < 0)
7,194✔
UNCOV
293
                        return log_error_errno(r, "Failed to mangle name: %m");
×
294

295
                if (string_is_glob(t))
7,194✔
296
                        r = strv_consume(&globs, t);
29✔
297
                else
298
                        r = strv_consume(&mangled, t);
7,165✔
299
                if (r < 0)
7,194✔
UNCOV
300
                        return log_oom();
×
301
        }
302

303
        /* Query the manager only if any of the names are a glob, since this is fairly expensive */
304
        bool expanded = !strv_isempty(globs);
7,101✔
305
        if (expanded) {
29✔
306
                _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
29✔
307
                _cleanup_free_ UnitInfo *unit_infos = NULL;
29✔
308

309
                r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
29✔
310
                if (r < 0)
29✔
311
                        return r;
312

313
                FOREACH_ARRAY(info, unit_infos, r)
145✔
314
                        if (strv_extend(&mangled, info->id) < 0)
116✔
UNCOV
315
                                return log_oom();
×
316
        }
317

318
        *ret = TAKE_PTR(mangled);
7,101✔
319
        if (ret_expanded)
7,101✔
320
                *ret_expanded = expanded;
2,634✔
321

322
        return 0;
323
}
324

325
int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_masked, char ***ret) {
1,559✔
326
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1,559✔
327
        _cleanup_strv_free_ char **triggered_by = NULL, **active = NULL;
1,559✔
328
        _cleanup_free_ char *name = NULL, *dbus_path = NULL;
1,559✔
329
        int r;
1,559✔
330

331
        assert(bus);
1,559✔
332
        assert(unit);
1,559✔
333
        assert(ret);
1,559✔
334

335
        r = unit_name_mangle(unit, 0, &name);
1,559✔
336
        if (r < 0)
1,559✔
337
                return r;
338

339
        if (unit_name_is_valid(name, UNIT_NAME_TEMPLATE))
1,559✔
340
                goto skip;
1✔
341

342
        if (ignore_masked) {
1,558✔
343
                r = unit_is_masked(bus, name);
1,547✔
344
                if (r < 0)
1,547✔
345
                        return r;
346
                if (r > 0)
1,547✔
347
                        goto skip;
6✔
348
        }
349

350
        dbus_path = unit_dbus_path_from_name(name);
1,552✔
351
        if (!dbus_path)
1,552✔
352
                return -ENOMEM;
353

354
        r = sd_bus_get_property_strv(
1,552✔
355
                        bus,
356
                        "org.freedesktop.systemd1",
357
                        dbus_path,
358
                        "org.freedesktop.systemd1.Unit",
359
                        "TriggeredBy",
360
                        &error,
361
                        &triggered_by);
362
        if (r < 0)
1,552✔
UNCOV
363
                return log_debug_errno(r, "Failed to get TriggeredBy property of unit '%s': %s",
×
364
                                       name, bus_error_message(&error, r));
365

366
        STRV_FOREACH(i, triggered_by) {
2,327✔
367
                UnitActiveState active_state;
775✔
368

369
                r = get_state_one_unit(bus, *i, &active_state);
775✔
370
                if (r < 0)
775✔
UNCOV
371
                        return r;
×
372

373
                if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING, UNIT_REFRESHING))
775✔
374
                        continue;
752✔
375

376
                r = strv_extend(&active, *i);
23✔
377
                if (r < 0)
23✔
378
                        return r;
379
        }
380

381
        *ret = TAKE_PTR(active);
1,552✔
382
        return 0;
1,552✔
383

384
skip:
7✔
385
        *ret = NULL;
7✔
386
        return 0;
7✔
387
}
388

389
void warn_triggering_units(sd_bus *bus, const char *unit, const char *operation, bool ignore_masked) {
1,559✔
UNCOV
390
        _cleanup_strv_free_ char **triggered_by = NULL;
×
391
        _cleanup_free_ char *joined = NULL;
1,559✔
392
        int r;
1,559✔
393

394
        assert(bus);
1,559✔
395
        assert(unit);
1,559✔
396
        assert(operation);
1,559✔
397

398
        r = get_active_triggering_units(bus, unit, ignore_masked, &triggered_by);
1,559✔
399
        if (r < 0) {
1,559✔
400
                if (r != -ENOENT) /* A linked unit might have disappeared after disabling */
×
401
                        log_warning_errno(r, "Failed to get triggering units for '%s', ignoring: %m", unit);
×
UNCOV
402
                return;
×
403
        }
404

405
        if (strv_isempty(triggered_by))
1,559✔
406
                return;
407

408
        joined = strv_join(triggered_by, ", ");
18✔
409
        if (!joined)
18✔
UNCOV
410
                return (void) log_oom();
×
411

412
        log_warning("%s '%s', but its triggering units are still active:\n"
18✔
413
                    "%s",
414
                    operation, unit, joined);
415
}
416

417
int need_daemon_reload(sd_bus *bus, const char *unit) {
2,750✔
418
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2,750✔
419
        const char *path;
2,750✔
420
        int b, r;
2,750✔
421

422
        /* We ignore all errors here, since this is used to show a
423
         * warning only */
424

425
        /* We don't use unit_dbus_path_from_name() directly since we
426
         * don't want to load the unit if it isn't loaded. */
427

428
        r = bus_call_method(bus, bus_systemd_mgr, "GetUnit", NULL, &reply, "s", unit);
2,750✔
429
        if (r < 0)
2,750✔
430
                return r;
431

432
        r = sd_bus_message_read(reply, "o", &path);
2,617✔
433
        if (r < 0)
2,617✔
434
                return r;
435

436
        r = sd_bus_get_property_trivial(
2,617✔
437
                        bus,
438
                        "org.freedesktop.systemd1",
439
                        path,
440
                        "org.freedesktop.systemd1.Unit",
441
                        "NeedDaemonReload",
442
                        NULL,
443
                        'b', &b);
444
        if (r < 0)
2,617✔
445
                return r;
446

447
        return b;
2,617✔
448
}
449

450
void warn_unit_file_changed(const char *unit) {
2✔
451
        assert(unit);
2✔
452

453
        if (arg_no_warn)
2✔
454
                return;
455

456
        log_warning("Warning: The unit file, source configuration file or drop-ins of %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2✔
457
                    unit,
458
                    arg_runtime_scope == RUNTIME_SCOPE_SYSTEM ? "" : " --user");
459
}
460

461
int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **ret_unit_path) {
×
462
        assert(lp);
×
UNCOV
463
        assert(unit_name);
×
464

465
        STRV_FOREACH(p, lp->search_path) {
×
466
                _cleanup_free_ char *path = NULL, *lpath = NULL;
×
UNCOV
467
                int r;
×
468

469
                path = path_join(*p, unit_name);
×
470
                if (!path)
×
UNCOV
471
                        return log_oom();
×
472

473
                r = chase(path, arg_root, 0, &lpath, NULL);
×
474
                if (r == -ENOENT)
×
475
                        continue;
×
476
                if (r == -ENOMEM)
×
477
                        return log_oom();
×
478
                if (r < 0)
×
UNCOV
479
                        return log_error_errno(r, "Failed to access path \"%s\": %m", path);
×
480

481
                if (ret_unit_path)
×
UNCOV
482
                        *ret_unit_path = TAKE_PTR(lpath);
×
483

484
                return 1;
485
        }
486

487
        if (ret_unit_path)
×
UNCOV
488
                *ret_unit_path = NULL;
×
489

490
        return 0;
491
}
492

493
int unit_find_paths(
142✔
494
                sd_bus *bus,
495
                const char *unit_name,
496
                LookupPaths *lp,
497
                bool force_client_side,
498
                Hashmap **cached_id_map,
499
                Hashmap **cached_name_map,
500
                char **ret_fragment_path,
501
                char ***ret_dropin_paths) {
502

UNCOV
503
        _cleanup_strv_free_ char **dropins = NULL;
×
504
        _cleanup_free_ char *path = NULL;
142✔
505
        int r;
142✔
506

507
        /**
508
         * Finds where the unit is defined on disk. Returns 0 if the unit is not found. Returns 1 if it is
509
         * found, and sets:
510
         *
511
         * - the path to the unit in *ret_frament_path, if it exists on disk,
512
         *
513
         * - and a strv of existing drop-ins in *ret_dropin_paths, if the arg is not NULL and any dropins
514
         *   were found.
515
         *
516
         * Returns -ERFKILL if the unit is masked, and -EKEYREJECTED if the unit file could not be loaded for
517
         * some reason (the latter only applies if we are going through the service manager). As special
518
         * exception it won't log for these two error cases.
519
         */
520

521
        assert(unit_name);
142✔
522
        assert(ret_fragment_path);
142✔
523
        assert(lp);
142✔
524

525
        /* Go via the bus to acquire the path, unless we are explicitly told not to, or when the unit name is a template */
526
        if (!force_client_side &&
278✔
527
            install_client_side() == INSTALL_CLIENT_SIDE_NO &&
272✔
528
            !unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
261✔
UNCOV
529
                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
530
                _cleanup_free_ char *load_state = NULL, *dbus_path = NULL;
131✔
531

532
                dbus_path = unit_dbus_path_from_name(unit_name);
131✔
533
                if (!dbus_path)
131✔
UNCOV
534
                        return log_oom();
×
535

536
                r = sd_bus_get_property_string(
131✔
537
                                bus,
538
                                "org.freedesktop.systemd1",
539
                                dbus_path,
540
                                "org.freedesktop.systemd1.Unit",
541
                                "LoadState",
542
                                &error,
543
                                &load_state);
544
                if (r < 0)
131✔
UNCOV
545
                        return log_error_errno(r, "Failed to get LoadState: %s", bus_error_message(&error, r));
×
546

547
                if (streq(load_state, "masked"))
131✔
548
                        return -ERFKILL; /* special case: no logging */
549
                if (streq(load_state, "not-found")) {
131✔
550
                        r = 0;
6✔
551
                        goto finish;
6✔
552
                }
553
                if (!STR_IN_SET(load_state, "loaded", "bad-setting"))
125✔
UNCOV
554
                        return -EKEYREJECTED; /* special case: no logging */
×
555

556
                r = sd_bus_get_property_string(
125✔
557
                                bus,
558
                                "org.freedesktop.systemd1",
559
                                dbus_path,
560
                                "org.freedesktop.systemd1.Unit",
561
                                "FragmentPath",
562
                                &error,
563
                                &path);
564
                if (r < 0)
125✔
UNCOV
565
                        return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
×
566

567
                if (ret_dropin_paths) {
125✔
568
                        r = sd_bus_get_property_strv(
125✔
569
                                        bus,
570
                                        "org.freedesktop.systemd1",
571
                                        dbus_path,
572
                                        "org.freedesktop.systemd1.Unit",
573
                                        "DropInPaths",
574
                                        &error,
575
                                        &dropins);
576
                        if (r < 0)
125✔
UNCOV
577
                                return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
×
578
                }
579
        } else {
580
                if (!*cached_name_map) {
11✔
581
                        r = unit_file_build_name_map(lp, NULL, cached_id_map, cached_name_map, NULL);
11✔
582
                        if (r < 0)
11✔
583
                                return r;
2✔
584
                }
585

586
                const char *_path;
11✔
587
                _cleanup_set_free_ Set *names = NULL;
11✔
588
                r = unit_file_find_fragment(*cached_id_map, *cached_name_map, unit_name, &_path, &names);
11✔
589
                if (r < 0)
11✔
UNCOV
590
                        return log_error_errno(r, "Failed to find fragment for '%s': %m", unit_name);
×
591

592
                if (_path) {
11✔
593
                        /* Check if unit is masked (symlinked to /dev/null or empty) */
594
                        r = null_or_empty_path(_path);
7✔
595
                        if (r < 0)
7✔
UNCOV
596
                                return log_error_errno(r, "Failed to check if '%s' is masked: %m", unit_name);
×
597
                        if (r > 0)
7✔
598
                                return -ERFKILL; /* special case: no logging */
599

600
                        path = strdup(_path);
5✔
601
                        if (!path)
5✔
UNCOV
602
                                return log_oom();
×
603
                }
604

605
                if (ret_dropin_paths) {
9✔
606
                        r = unit_file_find_dropin_paths(arg_root, lp->search_path, NULL,
9✔
607
                                                        ".d", ".conf",
608
                                                        NULL, names, &dropins);
609
                        if (r < 0)
9✔
610
                                return r;
611
                }
612
        }
613

614
 finish:
140✔
615
        if (isempty(path)) {
140✔
616
                *ret_fragment_path = NULL;
11✔
617
                r = 0;
11✔
618
        } else {
619
                *ret_fragment_path = TAKE_PTR(path);
129✔
620
                r = 1;
129✔
621
        }
622

623
        if (ret_dropin_paths) {
140✔
624
                if (!strv_isempty(dropins)) {
140✔
625
                        *ret_dropin_paths = TAKE_PTR(dropins);
121✔
626
                        r = 1;
121✔
627
                } else
628
                        *ret_dropin_paths = NULL;
19✔
629
        }
630

631
        if (r == 0 && !arg_force)
140✔
632
                log_error("No files found for %s.", unit_name);
5✔
633

634
        return r;
635
}
636

UNCOV
637
static int unit_find_template_path(
×
638
                const char *unit_name,
639
                LookupPaths *lp,
640
                char **ret_fragment_path,
641
                char **ret_template) {
642

643
        _cleanup_free_ char *t = NULL, *f = NULL;
×
644
        int r;
×
645

646
        /* Returns 1 if a fragment was found, 0 if not found, negative on error. */
647

648
        r = unit_file_find_path(lp, unit_name, &f);
×
UNCOV
649
        if (r < 0)
×
650
                return r;
651
        if (r > 0) {
×
652
                if (ret_fragment_path)
×
653
                        *ret_fragment_path = TAKE_PTR(f);
×
654
                if (ret_template)
×
655
                        *ret_template = NULL;
×
656
                return r; /* found a real unit */
×
657
        }
658

UNCOV
659
        r = unit_name_template(unit_name, &t);
×
660
        if (r == -EINVAL) {
×
661
                if (ret_fragment_path)
×
UNCOV
662
                        *ret_fragment_path = NULL;
×
663
                if (ret_template)
×
664
                        *ret_template = NULL;
×
665

UNCOV
666
                return 0; /* not a template, does not exist */
×
667
        }
668
        if (r < 0)
×
UNCOV
669
                return log_error_errno(r, "Failed to determine template name: %m");
×
670

UNCOV
671
        r = unit_file_find_path(lp, t, ret_fragment_path);
×
UNCOV
672
        if (r < 0)
×
673
                return r;
674

UNCOV
675
        if (ret_template)
×
UNCOV
676
                *ret_template = r > 0 ? TAKE_PTR(t) : NULL;
×
677

678
        return r;
679
}
680

681
int unit_is_masked(sd_bus *bus, const char *unit) {
1,547✔
682
        _cleanup_free_ char *load_state = NULL;
1,547✔
683
        int r;
1,547✔
684

685
        assert(bus);
1,547✔
686
        assert(unit);
1,547✔
687

688
        if (unit_name_is_valid(unit, UNIT_NAME_TEMPLATE)) {
1,547✔
UNCOV
689
                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
UNCOV
690
                _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
×
UNCOV
691
                const char *state;
×
692

UNCOV
693
                r = bus_call_method(bus, bus_systemd_mgr, "GetUnitFileState", &error, &reply, "s", unit);
×
UNCOV
694
                if (r < 0)
×
UNCOV
695
                        return log_debug_errno(r, "Failed to get UnitFileState for '%s': %s",
×
696
                                               unit, bus_error_message(&error, r));
697

UNCOV
698
                r = sd_bus_message_read(reply, "s", &state);
×
UNCOV
699
                if (r < 0)
×
UNCOV
700
                        return bus_log_parse_error_debug(r);
×
701

UNCOV
702
                return STR_IN_SET(state, "masked", "masked-runtime");
×
703
        }
704

705
        r = unit_load_state(bus, unit, &load_state);
1,547✔
706
        if (r < 0)
1,547✔
707
                return r;
708

709
        return streq(load_state, "masked");
1,547✔
710
}
711

712
int unit_exists(LookupPaths *lp, const char *unit) {
26✔
713
        typedef struct UnitStateInfo {
26✔
714
                const char *load_state;
715
                const char *active_state;
716
        } UnitStateInfo;
717

718
        static const struct bus_properties_map property_map[] = {
26✔
719
                { "LoadState",   "s", NULL, offsetof(UnitStateInfo, load_state)   },
720
                { "ActiveState", "s", NULL, offsetof(UnitStateInfo, active_state) },
721
                {},
722
        };
723

724
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
725
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
26✔
726
        _cleanup_free_ char *path = NULL;
26✔
727
        UnitStateInfo info = {};
26✔
728
        sd_bus *bus;
26✔
729
        int r;
26✔
730

731
        if (unit_name_is_valid(unit, UNIT_NAME_TEMPLATE))
26✔
UNCOV
732
                return unit_find_template_path(unit, lp, NULL, NULL);
×
733

734
        path = unit_dbus_path_from_name(unit);
26✔
735
        if (!path)
26✔
736
                return log_oom();
×
737

738
        r = acquire_bus(BUS_MANAGER, &bus);
26✔
739
        if (r < 0)
26✔
740
                return r;
741

742
        r = bus_map_all_properties(bus, "org.freedesktop.systemd1", path, property_map, 0, &error, &m, &info);
26✔
743
        if (r < 0)
26✔
UNCOV
744
                return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
×
745

746
        return !streq_ptr(info.load_state, "not-found") || !streq_ptr(info.active_state, "inactive");
26✔
747
}
748

749
int append_unit_dependencies(sd_bus *bus, char **names, char ***ret) {
3✔
750
        _cleanup_strv_free_ char **with_deps = NULL;
3✔
751

752
        assert(bus);
3✔
753
        assert(ret);
3✔
754

755
        STRV_FOREACH(name, names) {
6✔
756
                char **deps;
3✔
757

758
                if (strv_extend(&with_deps, *name) < 0)
3✔
UNCOV
759
                        return log_oom();
×
760

761
                (void) unit_get_dependencies(bus, *name, &deps);
3✔
762

763
                if (strv_extend_strv_consume(&with_deps, deps, /* filter_duplicates = */ true) < 0)
3✔
UNCOV
764
                        return log_oom();
×
765
        }
766

767
        *ret = TAKE_PTR(with_deps);
3✔
768

769
        return 0;
3✔
770
}
771

772
int maybe_extend_with_unit_dependencies(sd_bus *bus, char ***list) {
1,652✔
773
        _cleanup_strv_free_ char **list_with_deps = NULL;
1,652✔
774
        int r;
1,652✔
775

776
        assert(bus);
1,652✔
777
        assert(list);
1,652✔
778

779
        if (!arg_with_dependencies)
1,652✔
780
                return 0;
781

UNCOV
782
        r = append_unit_dependencies(bus, *list, &list_with_deps);
×
UNCOV
783
        if (r < 0)
×
UNCOV
784
                return log_error_errno(r, "Failed to append unit dependencies: %m");
×
785

UNCOV
786
        return strv_free_and_replace(*list, list_with_deps);
×
787
}
788

789
int unit_get_dependencies(sd_bus *bus, const char *name, char ***ret) {
70✔
790
        _cleanup_strv_free_ char **deps = NULL;
70✔
791

792
        static const struct bus_properties_map map[_DEPENDENCY_MAX][7] = {
70✔
793
                [DEPENDENCY_FORWARD] = {
794
                        { "Requires",    "as", NULL, 0 },
795
                        { "Requisite",   "as", NULL, 0 },
796
                        { "Wants",       "as", NULL, 0 },
797
                        { "ConsistsOf",  "as", NULL, 0 },
798
                        { "BindsTo",     "as", NULL, 0 },
799
                        { "Upholds",     "as", NULL, 0 },
800
                        {}
801
                },
802
                [DEPENDENCY_REVERSE] = {
803
                        { "RequiredBy",  "as", NULL, 0 },
804
                        { "RequisiteOf", "as", NULL, 0 },
805
                        { "WantedBy",    "as", NULL, 0 },
806
                        { "PartOf",      "as", NULL, 0 },
807
                        { "BoundBy",     "as", NULL, 0 },
808
                        { "UpheldBy",    "as", NULL, 0 },
809
                        {}
810
                },
811
                [DEPENDENCY_AFTER] = {
812
                        { "After",       "as", NULL, 0 },
813
                        {}
814
                },
815
                [DEPENDENCY_BEFORE] = {
816
                        { "Before",      "as", NULL, 0 },
817
                        {}
818
                },
819
        };
820

UNCOV
821
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
822
        _cleanup_free_ char *dbus_path = NULL;
70✔
823
        int r;
70✔
824

825
        assert(bus);
70✔
826
        assert(name);
70✔
827
        assert(ret);
70✔
828

829
        dbus_path = unit_dbus_path_from_name(name);
70✔
830
        if (!dbus_path)
70✔
UNCOV
831
                return log_oom();
×
832

833
        r = bus_map_all_properties(bus,
140✔
834
                                   "org.freedesktop.systemd1",
835
                                   dbus_path,
836
                                   map[arg_dependency],
70✔
837
                                   BUS_MAP_STRDUP,
838
                                   &error,
839
                                   NULL,
840
                                   &deps);
841
        if (r < 0)
70✔
UNCOV
842
                return log_error_errno(r, "Failed to get properties of %s: %s", name, bus_error_message(&error, r));
×
843

844
        strv_uniq(deps); /* Sometimes a unit might have multiple deps on the other unit,
70✔
845
                          * but we still want to show it just once. */
846
        *ret = TAKE_PTR(deps);
70✔
847

848
        return 0;
70✔
849
}
850

851
const char* unit_type_suffix(const char *unit) {
28,183✔
852
        const char *dot;
28,183✔
853

854
        dot = strrchr(unit, '.');
28,183✔
855
        if (!dot)
28,183✔
856
                return "";
857

858
        return dot + 1;
28,183✔
859
}
860

861
bool output_show_unit(const UnitInfo *u, char **patterns) {
11,449✔
862
        assert(u);
11,449✔
863

864
        if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
11,449✔
865
                return false;
866

867
        if (arg_types && !strv_contains(arg_types, unit_type_suffix(u->id)))
11,449✔
868
                return false;
869

870
        if (arg_all)
10,586✔
871
                return true;
872

873
        /* Note that '--all' is not purely a state filter, but also a filter that hides units that "follow"
874
         * other units (which is used for device units that appear under different names). */
875
        if (!isempty(u->following))
1,910✔
876
                return false;
877

878
        if (!strv_isempty(arg_states))
1,910✔
879
                return true;
880

881
        /* By default show all units except the ones in inactive state and with no pending job */
882
        if (u->job_id > 0)
1,496✔
883
                return true;
884

885
        if (streq(u->active_state, "inactive"))
1,484✔
886
                return false;
706✔
887

888
        return true;
889
}
890

891
InstallClientSide install_client_side(void) {
861✔
892
        /* Decides whether to execute enable/disable/… client-side offline operation rather than
893
         * server-side. */
894

895
        /* Unsupported environment variable, mostly for debugging purposes */
896
        if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
861✔
897
                return INSTALL_CLIENT_SIDE_OVERRIDE;
898

899
        if (!isempty(arg_root))
861✔
900
                return INSTALL_CLIENT_SIDE_ARG_ROOT;
901

902
        if (running_in_chroot_or_offline())
818✔
903
                return INSTALL_CLIENT_SIDE_OFFLINE;
904

905
        if (sd_booted() <= 0)
818✔
906
                return INSTALL_CLIENT_SIDE_NOT_BOOTED;
907

908
        if (arg_runtime_scope == RUNTIME_SCOPE_GLOBAL)
818✔
909
                return INSTALL_CLIENT_SIDE_GLOBAL_SCOPE;
8✔
910

911
        return INSTALL_CLIENT_SIDE_NO;
912
}
913

914
int output_table(Table *table) {
106✔
915
        int r;
106✔
916

917
        assert(table);
106✔
918

919
        if (OUTPUT_MODE_IS_JSON(arg_output))
106✔
UNCOV
920
                r = table_print_json(table, NULL, output_mode_to_json_format_flags(arg_output) | SD_JSON_FORMAT_COLOR_AUTO);
×
921
        else
922
                r = table_print(table, NULL);
106✔
923
        if (r < 0)
106✔
924
                return table_log_print_error(r);
2✔
925

926
        return 0;
927
}
928

929
bool show_preset_for_state(UnitFileState state) {
1,457✔
930
        /* Don't show preset state in those unit file states, it'll only confuse users. */
931
        return !IN_SET(state,
1,457✔
932
                       UNIT_FILE_ALIAS,
933
                       UNIT_FILE_STATIC,
934
                       UNIT_FILE_GENERATED,
935
                       UNIT_FILE_TRANSIENT);
936
}
937

938
UnitFileFlags unit_file_flags_from_args(void) {
17✔
939
        return (arg_runtime ? UNIT_FILE_RUNTIME : 0) |
34✔
940
               (arg_force   ? UNIT_FILE_FORCE   : 0);
17✔
941
}
942

943
int mangle_names(const char *operation, char * const *original_names, char ***ret) {
525✔
944
        _cleanup_strv_free_ char **l = NULL;
525✔
945
        int r;
525✔
946

947
        assert(operation);
525✔
948
        assert(ret);
525✔
949

950
        STRV_FOREACH(name, original_names) {
1,057✔
951
                char *mangled;
532✔
952

953
                if (is_path(*name))
532✔
954
                        /* When enabling units qualified path names are OK, too, hence allow them explicitly. */
UNCOV
955
                        r = path_make_absolute_cwd(*name, &mangled);
×
956
                else
957
                        r = unit_name_mangle_with_suffix(*name, operation,
532✔
958
                                                         arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
532✔
959
                                                         ".service", &mangled);
960
                if (r < 0)
532✔
UNCOV
961
                        return log_error_errno(r, "Failed to mangle unit name or path '%s': %m", *name);
×
962

963
                if (strv_consume(&l, mangled) < 0)
532✔
UNCOV
964
                        return log_oom();
×
965
        }
966

967
        *ret = TAKE_PTR(l);
525✔
968

969
        return 0;
525✔
970
}
971

972
int halt_now(enum action a) {
3✔
973
        /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need
974
         * to be synced explicitly in advance. */
975
        if (!arg_no_sync && !arg_dry_run)
3✔
UNCOV
976
                sync();
×
977

978
        /* Make sure C-A-D is handled by the kernel from this point on... */
979
        if (!arg_dry_run)
3✔
UNCOV
980
                (void) reboot(RB_ENABLE_CAD);
×
981

982
        switch (a) {
3✔
983

984
        case ACTION_HALT:
1✔
985
                if (!arg_quiet)
1✔
986
                        log_info("Halting.");
1✔
987
                if (arg_dry_run)
1✔
988
                        return 0;
989
                (void) reboot(RB_HALT_SYSTEM);
×
990
                return -errno;
×
991

992
        case ACTION_POWEROFF:
1✔
993
                if (!arg_quiet)
1✔
994
                        log_info("Powering off.");
1✔
995
                if (arg_dry_run)
1✔
996
                        return 0;
UNCOV
997
                (void) reboot(RB_POWER_OFF);
×
998
                return -errno;
×
999

1000
        case ACTION_KEXEC:
1✔
1001
        case ACTION_REBOOT:
1002
                return reboot_with_parameter(REBOOT_FALLBACK |
1✔
1003
                                             (arg_quiet ? 0 : REBOOT_LOG) |
1✔
1004
                                             (arg_dry_run ? REBOOT_DRY_RUN : 0));
1✔
1005

UNCOV
1006
        default:
×
UNCOV
1007
                assert_not_reached();
×
1008
        }
1009
}
1010

1011
int get_unit_by_pid(sd_bus *bus, pid_t pid, char **ret_unit, char **ret_path) {
1✔
UNCOV
1012
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
1013
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1✔
1014
        int r;
1✔
1015

1016
        assert(bus);
1✔
1017
        assert(pid >= 0); /* 0 is accepted by GetUnitByPID for querying our own process. */
1✔
1018

1019
        r = bus_call_method(bus, bus_systemd_mgr, "GetUnitByPID", &error, &reply, "u", (uint32_t) pid);
1✔
1020
        if (r < 0) {
1✔
UNCOV
1021
                if (sd_bus_error_has_name(&error, BUS_ERROR_NO_UNIT_FOR_PID))
×
UNCOV
1022
                        return log_error_errno(r, "%s", bus_error_message(&error, r));
×
1023

UNCOV
1024
                return log_error_errno(r,
×
1025
                                       "Failed to get unit that PID " PID_FMT " belongs to: %s",
1026
                                       pid > 0 ? pid : getpid_cached(),
1027
                                       bus_error_message(&error, r));
1028
        }
1029

1030
        _cleanup_free_ char *u = NULL, *p = NULL;
1✔
1031
        const char *path;
1✔
1032

1033
        r = sd_bus_message_read_basic(reply, 'o', &path);
1✔
1034
        if (r < 0)
1✔
UNCOV
1035
                return bus_log_parse_error(r);
×
1036

1037
        if (ret_unit) {
1✔
1038
                r = unit_name_from_dbus_path(path, &u);
1✔
1039
                if (r < 0)
1✔
1040
                        return log_error_errno(r,
×
1041
                                               "Failed to extract unit name from D-Bus object path '%s': %m",
1042
                                               path);
1043
        }
1044

1045
        if (ret_path) {
1✔
1046
                p = strdup(path);
×
UNCOV
1047
                if (!p)
×
UNCOV
1048
                        return log_oom();
×
1049
        }
1050

1051
        if (ret_unit)
1✔
1052
                *ret_unit = TAKE_PTR(u);
1✔
1053
        if (ret_path)
1✔
UNCOV
1054
                *ret_path = TAKE_PTR(p);
×
1055

1056
        return 0;
1057
}
1058

1059
static int get_unit_by_pidfd(sd_bus *bus, const PidRef *pid, char **ret_unit, char **ret_path) {
5✔
UNCOV
1060
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
×
1061
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
5✔
1062
        int r;
5✔
1063

1064
        assert(bus);
5✔
1065
        assert(pidref_is_set(pid));
5✔
1066

1067
        if (pid->fd < 0)
5✔
1068
                return -EOPNOTSUPP;
1069

1070
        r = bus_call_method(bus, bus_systemd_mgr, "GetUnitByPIDFD", &error, &reply, "h", pid->fd);
5✔
1071
        if (r < 0) {
5✔
UNCOV
1072
                if (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
×
1073
                        return -EOPNOTSUPP;
1074

UNCOV
1075
                if (sd_bus_error_has_names(&error, BUS_ERROR_NO_UNIT_FOR_PID, BUS_ERROR_NO_SUCH_PROCESS))
×
UNCOV
1076
                        return log_error_errno(r, "%s", bus_error_message(&error, r));
×
1077

UNCOV
1078
                return log_error_errno(r,
×
1079
                                       "Failed to get unit that PID " PID_FMT " belongs to: %s",
1080
                                       pid->pid, bus_error_message(&error, r));
1081
        }
1082

1083
        _cleanup_free_ char *u = NULL, *p = NULL;
5✔
1084
        const char *path, *unit;
5✔
1085

1086
        r = sd_bus_message_read(reply, "os", &path, &unit);
5✔
1087
        if (r < 0)
5✔
UNCOV
1088
                return bus_log_parse_error(r);
×
1089

1090
        if (ret_unit) {
5✔
1091
                u = strdup(unit);
5✔
1092
                if (!u)
5✔
UNCOV
1093
                        return log_oom();
×
1094
        }
1095

1096
        if (ret_path) {
5✔
1097
                p = strdup(path);
1✔
1098
                if (!p)
1✔
UNCOV
1099
                        return log_oom();
×
1100
        }
1101

1102
        if (ret_unit)
5✔
1103
                *ret_unit = TAKE_PTR(u);
5✔
1104
        if (ret_path)
5✔
1105
                *ret_path = TAKE_PTR(p);
1✔
1106

1107
        return 0;
1108
}
1109

1110
int lookup_unit_by_pidref(sd_bus *bus, pid_t pid, char **ret_unit, char **ret_path) {
5✔
1111
        int r;
5✔
1112

1113
        assert(bus);
5✔
1114
        assert(pid >= 0); /* 0 means our own process */
5✔
1115

1116
        if (arg_transport != BUS_TRANSPORT_LOCAL)
5✔
1117
                return get_unit_by_pid(bus, pid, ret_unit, ret_path);
5✔
1118

1119
        static bool use_pidfd = true;
5✔
1120
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
5✔
1121

1122
        r = pidref_set_pid(&pidref, pid);
5✔
1123
        if (r < 0)
5✔
UNCOV
1124
                return log_error_errno(r,
×
1125
                                       r == -ESRCH ?
1126
                                       "PID " PID_FMT " doesn't exist or is already gone." :
1127
                                       "Failed to create reference to PID " PID_FMT ": %m",
1128
                                       pid);
1129

1130
        if (use_pidfd) {
5✔
1131
                r = get_unit_by_pidfd(bus, &pidref, ret_unit, ret_path);
5✔
1132
                if (r != -EOPNOTSUPP)
5✔
1133
                        return r;
1134

UNCOV
1135
                use_pidfd = false;
×
UNCOV
1136
                log_debug_errno(r, "Unable to look up process using pidfd, falling back to pid.");
×
1137
        }
1138

1139
        _cleanup_free_ char *u = NULL, *p = NULL;
×
1140

1141
        r = get_unit_by_pid(bus, pidref.pid, ret_unit ? &u : NULL, ret_path ? &p : NULL);
×
1142
        if (r < 0)
×
1143
                return r;
1144

UNCOV
1145
        r = pidref_verify(&pidref);
×
UNCOV
1146
        if (r < 0)
×
UNCOV
1147
                return log_error_errno(r, "Failed to verify our reference to PID " PID_FMT ": %m", pidref.pid);
×
1148

UNCOV
1149
        if (ret_unit)
×
UNCOV
1150
                *ret_unit = TAKE_PTR(u);
×
UNCOV
1151
        if (ret_path)
×
UNCOV
1152
                *ret_path = TAKE_PTR(p);
×
1153

1154
        return 0;
1155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc