From: Lennart Poettering Date: Fri, 13 Apr 2012 19:32:17 +0000 (+0200) Subject: dbus: automatically send out changed events for properties written to X-Git-Tag: v183~315 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=d4e7373bbbc878b0d8ed1c28e21262a6d908d616 dbus: automatically send out changed events for properties written to --- diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c index 038fdd41a..badd037db 100644 --- a/src/shared/dbus-common.c +++ b/src/shared/dbus-common.c @@ -403,6 +403,7 @@ get_prop: DBusMessageIter sub; char *sig; void *data; + DBusMessage *changed; if (!dbus_message_iter_init(message, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) @@ -454,22 +455,34 @@ set_prop: dbus_free(sig); return bus_send_error_reply(c, message, NULL, -EINVAL); } - dbus_free(sig); - data = (char*)bp->base + p->offset; + data = (uint8_t*) bp->base + p->offset; if (p->indirect) data = *(void**)data; + r = p->set(&sub, property, data); - if (r < 0) { - if (r == -ENOMEM) - goto oom; + if (r == -ENOMEM) + goto oom; + else if (r < 0) return bus_send_error_reply(c, message, NULL, r); - } reply = dbus_message_new_method_return(message); if (!reply) goto oom; + + /* Send out a signal about this, but it doesn't really + * matter if this fails, so eat all errors */ + changed = bus_properties_changed_one_new( + dbus_message_get_path(message), + interface, + property); + if (changed) { + dbus_connection_send(c, changed, NULL); + dbus_message_unref(changed); + } + + } else { const char *interface = dbus_message_get_interface(message); @@ -729,7 +742,8 @@ DBusMessage* bus_properties_changed_new(const char *path, const char *interface, assert(interface); assert(properties); - if (!(m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"))) + m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"); + if (!m) goto oom; dbus_message_iter_init_append(m, &iter); @@ -759,6 +773,43 @@ oom: return NULL; } +DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property) { + DBusMessage *m; + DBusMessageIter iter, sub; + + assert(interface); + assert(property); + + m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"); + if (!m) + goto oom; + + dbus_message_iter_init_append(m, &iter); + + /* We won't send any property values, since they might be + * large and sometimes not cheap to generated */ + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) + goto oom; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &property)) + goto oom; + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + + return NULL; +} + uint32_t bus_flags_to_events(DBusWatch *bus_watch) { unsigned flags; uint32_t events = 0; diff --git a/src/shared/dbus-common.h b/src/shared/dbus-common.h index 38d8e6538..ca398fc3f 100644 --- a/src/shared/dbus-common.h +++ b/src/shared/dbus-common.h @@ -178,6 +178,7 @@ int bus_property_append_long(DBusMessageIter *i, const char *property, void *dat const char *bus_errno_to_dbus(int error); DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties); +DBusMessage* bus_properties_changed_one_new(const char *path, const char *interface, const char *property); uint32_t bus_flags_to_events(DBusWatch *bus_watch); unsigned bus_events_to_flags(uint32_t events);