chiark / gitweb /
bus: introduce concept of "const" properties
[elogind.git] / src / libsystemd-bus / bus-objects.c
index 8ffda2f95db0f6ecef8be40e70761d14d2e2aeb6..e468025a8189f293e6db77896968096d161edbc5 100644 (file)
@@ -51,7 +51,7 @@ static int node_vtable_get_userdata(
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
-                        return sd_bus_error_get_errno(error);
+                        return -sd_bus_error_get_errno(error);
                 if (r == 0)
                         return r;
         }
@@ -117,7 +117,7 @@ static int add_enumerated_to_set(
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
-                        return sd_bus_error_get_errno(error);
+                        return -sd_bus_error_get_errno(error);
 
                 STRV_FOREACH(k, children) {
                         if (r < 0) {
@@ -419,7 +419,7 @@ static int invoke_property_get(
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
-                        return sd_bus_error_get_errno(error);
+                        return -sd_bus_error_get_errno(error);
                 return r;
         }
 
@@ -475,7 +475,7 @@ static int invoke_property_set(
                 if (r < 0)
                         return r;
                 if (sd_bus_error_is_set(error))
-                        return sd_bus_error_get_errno(error);
+                        return -sd_bus_error_get_errno(error);
                 return r;
         }
 
@@ -831,7 +831,7 @@ static int process_introspect(
         if (bus->nodes_modified)
                 return 0;
 
-        r = introspect_begin(&intro);
+        r = introspect_begin(&intro, bus->trusted);
         if (r < 0)
                 return r;
 
@@ -1284,6 +1284,10 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
         if (hashmap_isempty(bus->nodes))
                 return 0;
 
+        /* Never respond to broadcast messages */
+        if (bus->bus_client && !m->destination)
+                return 0;
+
         assert(m->path);
         assert(m->member);
 
@@ -1334,7 +1338,8 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
 static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
         struct node *n, *parent;
         const char *e;
-        char *s, *p;
+        _cleanup_free_ char *s = NULL;
+        char *p;
         int r;
 
         assert(bus);
@@ -1362,10 +1367,8 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
                 p = strndupa(path, MAX(1, path - e));
 
                 parent = bus_node_allocate(bus, p);
-                if (!parent) {
-                        free(s);
+                if (!parent)
                         return NULL;
-                }
         }
 
         n = new0(struct node, 1);
@@ -1374,10 +1377,11 @@ static struct node *bus_node_allocate(sd_bus *bus, const char *path) {
 
         n->parent = parent;
         n->path = s;
+        s = NULL; /* do not free */
 
-        r = hashmap_put(bus->nodes, s, n);
+        r = hashmap_put(bus->nodes, n->path, n);
         if (r < 0) {
-                free(s);
+                free(n->path);
                 free(n);
                 return NULL;
         }
@@ -1676,7 +1680,7 @@ static int add_object_vtable_internal(
                             !signature_is_valid(strempty(v->x.method.signature), false) ||
                             !signature_is_valid(strempty(v->x.method.result), false) ||
                             !(v->x.method.handler || (isempty(v->x.method.signature) && isempty(v->x.method.result))) ||
-                            v->flags & (SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY)) {
+                            v->flags & (SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) {
                                 r = -EINVAL;
                                 goto fail;
                         }
@@ -1718,13 +1722,12 @@ static int add_object_vtable_internal(
                             !signature_is_single(v->x.property.signature, false) ||
                             !(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) ||
                             v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY ||
-                            (v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) ||
+                            (!!(v->flags & SD_BUS_VTABLE_PROPERTY_CONST) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) > 1 ||
                             (v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) {
                                 r = -EINVAL;
                                 goto fail;
                         }
 
-
                         m = new0(struct vtable_member, 1);
                         if (!m) {
                                 r = -ENOMEM;
@@ -2009,9 +2012,10 @@ static int emit_properties_changed_on_interface(
                         if (c != v->parent)
                                 continue;
 
-                        assert_return(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE, -EDOM);
+                        assert_return(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE ||
+                                      v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION, -EDOM);
 
-                        if (v->vtable->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY) {
+                        if (v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) {
                                 has_invalidating = true;
                                 continue;
                         }
@@ -2080,7 +2084,7 @@ static int emit_properties_changed_on_interface(
                                 assert_se(v = hashmap_get(bus->vtable_properties, &key));
                                 assert(c == v->parent);
 
-                                if (!(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY))
+                                if (!(v->vtable->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION))
                                         continue;
 
                                 r = sd_bus_message_append(m, "s", *property);