chiark / gitweb /
shared/sparse-endian.h: add missing byteswap.h include
[elogind.git] / src / login / logind-session.c
index feedc30fa6142fa8fefc7b208447ba32ef2aba77..eeb58c9031b71d1bce41805cb778e6d4c7890d30 100644 (file)
 
 static void session_remove_fifo(Session *s);
 
-static unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
-        uint64_t u = *(const dev_t*)p;
-
-        return uint64_hash_func(&u, hash_key);
-}
-
-static int devt_compare_func(const void *_a, const void *_b) {
-        dev_t a, b;
-
-        a = *(const dev_t*) _a;
-        b = *(const dev_t*) _b;
-
-        return a < b ? -1 : (a > b ? 1 : 0);
-}
-
 Session* session_new(Manager *m, const char *id) {
         Session *s;
 
@@ -76,7 +61,7 @@ Session* session_new(Manager *m, const char *id) {
                 return NULL;
         }
 
-        s->devices = hashmap_new(devt_hash_func, devt_compare_func);
+        s->devices = hashmap_new(&devt_hash_ops);
         if (!s->devices) {
                 free(s->state_file);
                 free(s);
@@ -1074,30 +1059,30 @@ bool session_is_controller(Session *s, const char *sender) {
         return streq_ptr(s->controller, sender);
 }
 
-static void session_swap_controller(Session *s, char *name) {
+static void session_release_controller(Session *s, bool notify) {
+        _cleanup_free_ char *name = NULL;
         SessionDevice *sd;
 
-        if (s->controller) {
-                manager_drop_busname(s->manager, s->controller);
-                free(s->controller);
-                s->controller = NULL;
+        if (!s->controller)
+                return;
 
-                /* Drop all devices as they're now unused. Do that after the
-                 * controller is released to avoid sending out useles
-                 * dbus signals. */
-                while ((sd = hashmap_first(s->devices)))
-                        session_device_free(sd);
+        name = s->controller;
 
-                if (!name)
-                        session_restore_vt(s);
-        }
+        /* By resetting the controller before releasing the devices, we won't
+         * send notification signals. This avoids sending useless notifications
+         * if the controller is released on disconnects. */
+        if (!notify)
+                s->controller = NULL;
 
-        s->controller = name;
-        session_save(s);
+        while ((sd = hashmap_first(s->devices)))
+                session_device_free(sd);
+
+        s->controller = NULL;
+        manager_drop_busname(s->manager, name);
 }
 
 int session_set_controller(Session *s, const char *sender, bool force) {
-        char *t;
+        _cleanup_free_ char *name = NULL;
         int r;
 
         assert(s);
@@ -1108,15 +1093,13 @@ int session_set_controller(Session *s, const char *sender, bool force) {
         if (s->controller && !force)
                 return -EBUSY;
 
-        t = strdup(sender);
-        if (!t)
+        name = strdup(sender);
+        if (!name)
                 return -ENOMEM;
 
-        r = manager_watch_busname(s->manager, sender);
-        if (r) {
-                free(t);
+        r = manager_watch_busname(s->manager, name);
+        if (r)
                 return r;
-        }
 
         /* When setting a session controller, we forcibly mute the VT and set
          * it into graphics-mode. Applications can override that by changing
@@ -1127,10 +1110,15 @@ int session_set_controller(Session *s, const char *sender, bool force) {
          * If logind crashes/restarts, we restore the controller during restart
          * or reset the VT in case it crashed/exited, too. */
         r = session_prepare_vt(s);
-        if (r < 0)
+        if (r < 0) {
+                manager_drop_busname(s->manager, name);
                 return r;
+        }
 
-        session_swap_controller(s, t);
+        session_release_controller(s, true);
+        s->controller = name;
+        name = NULL;
+        session_save(s);
 
         return 0;
 }
@@ -1141,7 +1129,9 @@ void session_drop_controller(Session *s) {
         if (!s->controller)
                 return;
 
-        session_swap_controller(s, NULL);
+        session_release_controller(s, false);
+        session_save(s);
+        session_restore_vt(s);
 }
 
 static const char* const session_state_table[_SESSION_STATE_MAX] = {
@@ -1159,6 +1149,7 @@ static const char* const session_type_table[_SESSION_TYPE_MAX] = {
         [SESSION_X11] = "x11",
         [SESSION_WAYLAND] = "wayland",
         [SESSION_MIR] = "mir",
+        [SESSION_WEB] = "web",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);