chiark / gitweb /
gpt-auto-generator: skip nonexistent devices
[elogind.git] / src / libsystemd-bus / bus-objects.c
index 68437f1e37f86ac6de035b30262948fdd079c4cd..b116a5dd10146ddc729abade07fd4bf7d11b3c05 100644 (file)
@@ -1593,15 +1593,25 @@ static void free_node_vtable(sd_bus *bus, struct node_vtable *w) {
         free(w);
 }
 
-static unsigned vtable_member_hash_func(const void *a) {
+static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) {
         const struct vtable_member *m = a;
+        uint8_t hash_key2[HASH_KEY_SIZE];
+        unsigned long ret;
 
         assert(m);
 
-        return
-                string_hash_func(m->path) ^
-                string_hash_func(m->interface) ^
-                string_hash_func(m->member);
+        ret = string_hash_func(m->path, hash_key);
+
+        /* Use a slightly different hash key for the interface */
+        memcpy(hash_key2, hash_key, HASH_KEY_SIZE);
+        hash_key2[0]++;
+        ret ^= string_hash_func(m->interface, hash_key2);
+
+        /* And an even different one for the  member */
+        hash_key2[0]++;
+        ret ^= string_hash_func(m->member, hash_key2);
+
+        return ret;
 }
 
 static int vtable_member_compare_func(const void *a, const void *b) {
@@ -1971,6 +1981,7 @@ static int emit_properties_changed_on_interface(
                 const char *path,
                 const char *interface,
                 bool require_fallback,
+                bool *found_interface,
                 char **names) {
 
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -1987,6 +1998,7 @@ static int emit_properties_changed_on_interface(
         assert(prefix);
         assert(path);
         assert(interface);
+        assert(found_interface);
 
         n = hashmap_get(bus->nodes, prefix);
         if (!n)
@@ -2022,6 +2034,8 @@ static int emit_properties_changed_on_interface(
                 if (r == 0)
                         continue;
 
+                *found_interface = true;
+
                 if (names) {
                         /* If the caller specified a list of
                          * properties we include exactly those in the
@@ -2175,6 +2189,7 @@ _public_ int sd_bus_emit_properties_changed_strv(
                 char **names) {
 
         BUS_DONT_DESTROY(bus);
+        bool found_interface = false;
         char *prefix;
         int r;
 
@@ -2195,7 +2210,7 @@ _public_ int sd_bus_emit_properties_changed_strv(
         do {
                 bus->nodes_modified = false;
 
-                r = emit_properties_changed_on_interface(bus, path, path, interface, false, names);
+                r = emit_properties_changed_on_interface(bus, path, path, interface, false, &found_interface, names);
                 if (r != 0)
                         return r;
                 if (bus->nodes_modified)
@@ -2203,7 +2218,7 @@ _public_ int sd_bus_emit_properties_changed_strv(
 
                 prefix = alloca(strlen(path) + 1);
                 OBJECT_PATH_FOREACH_PREFIX(prefix, path) {
-                        r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, names);
+                        r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names);
                         if (r != 0)
                                 return r;
                         if (bus->nodes_modified)
@@ -2212,7 +2227,7 @@ _public_ int sd_bus_emit_properties_changed_strv(
 
         } while (bus->nodes_modified);
 
-        return -ENOENT;
+        return found_interface ? 0 : -ENOENT;
 }
 
 _public_ int sd_bus_emit_properties_changed(