summaryrefslogtreecommitdiff
path: root/src/login/logind.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-09-17 17:39:55 +0200
committerLennart Poettering <lennart@poettering.net>2013-09-17 11:30:44 -0500
commite8b212fe56f7f4e1778474777a7a2959244d0047 (patch)
treeb3d30b51e14d95cbda6245ee96b04e7a781f6b21 /src/login/logind.c
parent718d006a63f773c42106494e823250c48942cf08 (diff)
logind: add infrastructure to watch busnames
If we want to track bus-names to allow exclusive resource-access, we need a way to get notified when a bus-name is gone. We make logind watch for NameOwnerChanged dbus events and check whether the name is currently watched. If it is, we remove it from the watch-list (notification for other objects can be added in follow-up patches).
Diffstat (limited to 'src/login/logind.c')
-rw-r--r--src/login/logind.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/login/logind.c b/src/login/logind.c
index 29019c214b..89e4eeea16 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -74,6 +74,7 @@ Manager *manager_new(void) {
m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
m->buttons = hashmap_new(string_hash_func, string_compare_func);
+ m->busnames = hashmap_new(string_hash_func, string_compare_func);
m->user_units = hashmap_new(string_hash_func, string_compare_func);
m->session_units = hashmap_new(string_hash_func, string_compare_func);
@@ -82,7 +83,7 @@ Manager *manager_new(void) {
m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
- if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
+ if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
!m->user_units || !m->session_units ||
!m->session_fds || !m->inhibitor_fds || !m->button_fds) {
manager_free(m);
@@ -111,6 +112,7 @@ void manager_free(Manager *m) {
Seat *s;
Inhibitor *i;
Button *b;
+ char *n;
assert(m);
@@ -132,12 +134,16 @@ void manager_free(Manager *m) {
while ((b = hashmap_first(m->buttons)))
button_free(b);
+ while ((n = hashmap_first(m->busnames)))
+ free(hashmap_remove(m->busnames, n));
+
hashmap_free(m->devices);
hashmap_free(m->seats);
hashmap_free(m->sessions);
hashmap_free(m->users);
hashmap_free(m->inhibitors);
hashmap_free(m->buttons);
+ hashmap_free(m->busnames);
hashmap_free(m->user_units);
hashmap_free(m->session_units);
@@ -361,6 +367,40 @@ int manager_add_button(Manager *m, const char *name, Button **_button) {
return 0;
}
+int manager_watch_busname(Manager *m, const char *name) {
+ char *n;
+ int r;
+
+ assert(m);
+ assert(name);
+
+ if (hashmap_get(m->busnames, name))
+ return 0;
+
+ n = strdup(name);
+ if (!n)
+ return -ENOMEM;
+
+ r = hashmap_put(m->busnames, n, n);
+ if (r < 0) {
+ free(n);
+ return r;
+ }
+
+ return 0;
+}
+
+void manager_drop_busname(Manager *m, const char *name) {
+ char *key;
+
+ assert(m);
+ assert(name);
+
+ key = hashmap_remove(m->busnames, name);
+ if (key)
+ free(key);
+}
+
int manager_process_seat_device(Manager *m, struct udev_device *d) {
Device *device;
int r;
@@ -1045,6 +1085,18 @@ static int manager_connect_bus(Manager *m) {
dbus_bus_add_match(m->bus,
"type='signal',"
+ "sender='"DBUS_SERVICE_DBUS"',"
+ "interface='"DBUS_INTERFACE_DBUS"',"
+ "member='NameOwnerChanged',"
+ "path='"DBUS_PATH_DBUS"'",
+ &error);
+ if (dbus_error_is_set(&error)) {
+ log_error("Failed to add match for NameOwnerChanged: %s", bus_error_message(&error));
+ dbus_error_free(&error);
+ }
+
+ dbus_bus_add_match(m->bus,
+ "type='signal',"
"sender='org.freedesktop.systemd1',"
"interface='org.freedesktop.systemd1.Manager',"
"member='JobRemoved',"