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

systemd / systemd / 15232239991

24 May 2025 08:01PM UTC coverage: 72.053% (-0.02%) from 72.07%
15232239991

push

github

web-flow
docs: add man pages for sd_device_enumerator_[new,ref,unref,unrefp] (#37586)

For #20929.

299160 of 415197 relevant lines covered (72.05%)

703671.29 hits per line

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

28.24
/src/shared/bus-object.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "sd-bus.h"
4

5
#include "alloc-util.h"
6
#include "bus-introspect.h"
7
#include "bus-object.h"
8
#include "log.h"
9
#include "ordered-set.h"
10
#include "string-util.h"
11
#include "strv.h"
12

13
int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) {
17,011✔
14
        int r;
17,011✔
15

16
        log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface);
17,011✔
17

18
        for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
20,633✔
19
                r = sd_bus_add_object_vtable(bus, NULL,
7,244✔
20
                                             impl->path,
3,622✔
21
                                             impl->interface,
3,622✔
22
                                             *p,
23
                                             userdata);
24
                if (r < 0)
3,622✔
25
                        return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
×
26
                                               impl->path,
27
                                               impl->interface);
28
        }
29

30
        for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
47,032✔
31
                r = sd_bus_add_fallback_vtable(bus, NULL,
60,042✔
32
                                               impl->path,
30,021✔
33
                                               impl->interface,
30,021✔
34
                                               p->vtable,
35
                                               p->object_find,
30,021✔
36
                                               userdata);
37
                if (r < 0)
30,021✔
38
                        return log_error_errno(r, "Failed to register bus path %s with interface %s: %m",
×
39
                                               impl->path,
40
                                               impl->interface);
41
        }
42

43
        if (impl->node_enumerator) {
17,011✔
44
                r = sd_bus_add_node_enumerator(bus, NULL,
9,354✔
45
                                               impl->path,
4,677✔
46
                                               impl->node_enumerator,
47
                                               userdata);
48
                if (r < 0)
4,677✔
49
                        return log_error_errno(r, "Failed to add node enumerator for %s: %m",
×
50
                                               impl->path);
51
        }
52

53
        if (impl->manager) {
17,011✔
54
                r = sd_bus_add_object_manager(bus, NULL, impl->path);
102✔
55
                if (r < 0)
102✔
56
                        return log_error_errno(r, "Failed to add object manager for %s: %m", impl->path);
×
57
        }
58

59
        for (size_t i = 0; impl->children && impl->children[i]; i++) {
30,400✔
60
                r = bus_add_implementation(bus, impl->children[i], userdata);
13,389✔
61
                if (r < 0)
13,389✔
62
                        return r;
63
        }
64

65
        return 0;
66
}
67

68
static const BusObjectImplementation* find_implementation(
×
69
                const char *pattern,
70
                const BusObjectImplementation* const* bus_objects) {
71

72
        for (size_t i = 0; bus_objects && bus_objects[i]; i++) {
×
73
                const BusObjectImplementation *impl = bus_objects[i];
×
74

75
                if (STR_IN_SET(pattern, impl->path, impl->interface))
×
76
                        return impl;
×
77

78
                impl = find_implementation(pattern, impl->children);
×
79
                if (impl)
×
80
                        return impl;
81
        }
82

83
        return NULL;
84
}
85

86
static int bus_introspect_implementation(
×
87
                struct introspect *intro,
88
                const BusObjectImplementation *impl) {
89
        int r;
×
90

91
        for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) {
×
92
                r = introspect_write_interface(intro, impl->interface, *p);
×
93
                if (r < 0)
×
94
                        return log_error_errno(r, "Failed to write introspection data: %m");
×
95
        }
96

97
        for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) {
×
98
                r = introspect_write_interface(intro, impl->interface, p->vtable);
×
99
                if (r < 0)
×
100
                        return log_error_errno(r, "Failed to write introspection data: %m");
×
101
        }
102

103
        return 0;
104
}
105

106
static void list_paths(
×
107
                FILE *out,
108
                const BusObjectImplementation* const* bus_objects) {
109

110
        for (size_t i = 0; bus_objects[i]; i++) {
×
111
                fprintf(out, "%s\t%s\n", bus_objects[i]->path, bus_objects[i]->interface);
×
112
                if (bus_objects[i]->children)
×
113
                        list_paths(out, bus_objects[i]->children);
×
114
        }
115
}
×
116

117
int bus_introspect_implementations(
×
118
                FILE *out,
119
                const char *pattern,
120
                const BusObjectImplementation* const* bus_objects) {
121

122
        const BusObjectImplementation *impl, *main_impl = NULL;
×
123
        _cleanup_free_ char *s = NULL;
×
124
        int r;
×
125

126
        if (streq(pattern, "list")) {
×
127
                list_paths(out, bus_objects);
×
128
                return 0;
129
        }
130

131
        struct introspect intro = {};
×
132
        bool is_interface = sd_bus_interface_name_is_valid(pattern);
×
133

134
        impl = find_implementation(pattern, bus_objects);
×
135
        if (!impl)
×
136
                return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
×
137
                                       "%s %s not found",
138
                                       is_interface ? "Interface" : "Object path",
139
                                       pattern);
140

141
        /* We use trusted=false here to get all the @org.freedesktop.systemd1.Privileged annotations. */
142
        r = introspect_begin(&intro, false);
×
143
        if (r < 0)
×
144
                return log_error_errno(r, "Failed to write introspection data: %m");
×
145

146
        r = introspect_write_default_interfaces(&intro, impl->manager);
×
147
        if (r < 0)
×
148
                return log_error_errno(r, "Failed to write introspection data: %m");
×
149

150
        /* Check if there is a non-fallback path that applies to the given interface, also
151
         * print it. This is useful in the case of units: o.fd.systemd1.Service is declared
152
         * as a fallback vtable for o/fd/systemd1/unit, and we also want to print
153
         * o.fd.systemd1.Unit, which is the non-fallback implementation. */
154
        if (impl->fallback_vtables && is_interface)
×
155
                main_impl = find_implementation(impl->path, bus_objects);
×
156

157
        if (main_impl)
×
158
                bus_introspect_implementation(&intro, main_impl);
×
159

160
        if (impl != main_impl)
×
161
                bus_introspect_implementation(&intro, impl);
×
162

163
        _cleanup_ordered_set_free_ OrderedSet *nodes = NULL;
×
164

165
        for (size_t i = 0; impl->children && impl->children[i]; i++) {
×
166
                r = ordered_set_put_strdup(&nodes, impl->children[i]->path);
×
167
                if (r < 0)
×
168
                        return log_oom();
×
169
        }
170

171
        r = introspect_write_child_nodes(&intro, nodes, impl->path);
×
172
        if (r < 0)
×
173
                return r;
174

175
        r = introspect_finish(&intro, &s);
×
176
        if (r < 0)
×
177
                return log_error_errno(r, "Failed to write introspection data: %m");
×
178

179
        fputs(s, out);
×
180
        return 0;
181
}
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