return NULL;
}
+ s->devices = hashmap_new(trivial_hash_func, trivial_compare_func);
+ if (!s->devices) {
+ free(s->state_file);
+ free(s);
+ return NULL;
+ }
+
s->id = path_get_file_name(s->state_file);
if (hashmap_put(m->sessions, s->id, s) < 0) {
+ hashmap_free(s->devices);
free(s->state_file);
free(s);
return NULL;
}
void session_free(Session *s) {
+ SessionDevice *sd;
+
assert(s);
if (s->in_gc_queue)
session_drop_controller(s);
+ while ((sd = hashmap_first(s->devices)))
+ session_device_free(sd);
+
+ hashmap_free(s->devices);
+
if (s->user) {
LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s);
if (s->service)
fprintf(f, "SERVICE=%s\n", s->service);
- if (s->seat && seat_can_multi_session(s->seat))
+ if (s->seat && seat_has_vts(s->seat))
fprintf(f, "VTNR=%i\n", s->vtnr);
if (s->leader > 0)
seat_attach_session(o, s);
}
- if (vtnr && s->seat && seat_can_multi_session(s->seat)) {
+ if (vtnr && s->seat && seat_has_vts(s->seat)) {
int v;
k = safe_atoi(vtnr, &v);
assert(s);
assert(s->user);
- if (s->vtnr < 0)
+ if (s->vtnr <= 0)
return -ENOTSUP;
if (!s->seat)
if (s->seat->active == s)
return 0;
- assert(seat_is_vtconsole(s->seat));
+ assert(seat_has_vts(s->seat));
return chvt(s->vtnr);
}
int session_finalize(Session *s) {
int r = 0;
+ SessionDevice *sd;
assert(s);
"MESSAGE=Removed session %s.", s->id,
NULL);
+ /* Kill session devices */
+ while ((sd = hashmap_first(s->devices)))
+ session_device_free(sd);
+
/* Remove X11 symlink */
session_unlink_x11_socket(s);
}
void session_drop_controller(Session *s) {
+ SessionDevice *sd;
+
assert(s);
if (!s->controller)
manager_drop_busname(s->manager, s->controller);
free(s->controller);
s->controller = NULL;
+
+ /* 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);
}
static const char* const session_state_table[_SESSION_STATE_MAX] = {