]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/login/logind-session.c
terminal reset should honour default_utf8 kernel setting (#6606)
[thirdparty/systemd.git] / src / login / logind-session.c
index ae05877a68681a8a22724d7b641d9f3200ee00fc..c345b1ca44bc2d8630ecc435aea25fb863e79986 100644 (file)
@@ -45,6 +45,7 @@
 #include "terminal-util.h"
 #include "user-util.h"
 #include "util.h"
+#include "process-util.h"
 
 #define RELEASE_USEC (20*USEC_PER_SEC)
 
@@ -82,6 +83,7 @@ Session* session_new(Manager *m, const char *id) {
         s->manager = m;
         s->fifo_fd = -1;
         s->vtfd = -1;
+        s->audit_id = AUDIT_SESSION_INVALID;
 
         return s;
 }
@@ -152,6 +154,18 @@ void session_set_user(Session *s, User *u) {
         LIST_PREPEND(sessions_by_user, u->sessions, s);
 }
 
+static void session_save_devices(Session *s, FILE *f) {
+        SessionDevice *sd;
+        Iterator i;
+
+        if (!hashmap_isempty(s->devices)) {
+                fprintf(f, "DEVICES=");
+                HASHMAP_FOREACH(sd, s->devices, i)
+                        fprintf(f, "%u:%u ", major(sd->dev), minor(sd->dev));
+                fprintf(f, "\n");
+        }
+}
+
 int session_save(Session *s) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -268,10 +282,10 @@ int session_save(Session *s) {
         if (!s->vtnr)
                 fprintf(f, "POSITION=%u\n", s->position);
 
-        if (s->leader > 0)
+        if (pid_is_valid(s->leader))
                 fprintf(f, "LEADER="PID_FMT"\n", s->leader);
 
-        if (s->audit_id > 0)
+        if (audit_session_is_valid(s->audit_id))
                 fprintf(f, "AUDIT=%"PRIu32"\n", s->audit_id);
 
         if (dual_timestamp_is_set(&s->timestamp))
@@ -281,8 +295,10 @@ int session_save(Session *s) {
                         s->timestamp.realtime,
                         s->timestamp.monotonic);
 
-        if (s->controller)
+        if (s->controller) {
                 fprintf(f, "CONTROLLER=%s\n", s->controller);
+                session_save_devices(s, f);
+        }
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -304,6 +320,43 @@ fail:
         return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
 }
 
+static int session_load_devices(Session *s, const char *devices) {
+        const char *p;
+        int r = 0;
+
+        assert(s);
+
+        for (p = devices;;) {
+                _cleanup_free_ char *word = NULL;
+                SessionDevice *sd;
+                dev_t dev;
+                int k;
+
+                k = extract_first_word(&p, &word, NULL, 0);
+                if (k == 0)
+                        break;
+                if (k < 0) {
+                        r = k;
+                        break;
+                }
+
+                k = parse_dev(word, &dev);
+                if (k < 0) {
+                        r = k;
+                        continue;
+                }
+
+                /* The file descriptors for loaded devices will be reattached later. */
+                k = session_device_new(s, dev, false, &sd);
+                if (k < 0)
+                        r = k;
+        }
+
+        if (r < 0)
+                log_error_errno(r, "Loading session devices for session %s failed: %m", s->id);
+
+        return r;
+}
 
 int session_load(Session *s) {
         _cleanup_free_ char *remote = NULL,
@@ -317,7 +370,9 @@ int session_load(Session *s) {
                 *uid = NULL,
                 *realtime = NULL,
                 *monotonic = NULL,
-                *controller = NULL;
+                *controller = NULL,
+                *active = NULL,
+                *devices = NULL;
 
         int k, r;
 
@@ -345,6 +400,8 @@ int session_load(Session *s) {
                            "REALTIME",       &realtime,
                            "MONOTONIC",      &monotonic,
                            "CONTROLLER",     &controller,
+                           "ACTIVE",         &active,
+                           "DEVICES",        &devices,
                            NULL);
 
         if (r < 0)
@@ -404,9 +461,8 @@ int session_load(Session *s) {
         }
 
         if (leader) {
-                k = parse_pid(leader, &s->leader);
-                if (k >= 0)
-                        audit_session_from_pid(s->leader, &s->audit_id);
+                if (parse_pid(leader, &s->leader) >= 0)
+                        (void) audit_session_from_pid(s->leader, &s->audit_id);
         }
 
         if (type) {
@@ -447,10 +503,17 @@ int session_load(Session *s) {
         if (monotonic)
                 timestamp_deserialize(monotonic, &s->timestamp.monotonic);
 
+        if (active) {
+                k = parse_boolean(active);
+                if (k >= 0)
+                        s->was_active = k;
+        }
+
         if (controller) {
-                if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0)
+                if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
                         session_set_controller(s, controller, false, false);
-                else
+                        session_load_devices(s, devices);
+                } else
                         session_restore_vt(s);
         }
 
@@ -1093,10 +1156,10 @@ void session_restore_vt(Session *s) {
 
         (void) ioctl(vt, KDSETMODE, KD_TEXT);
 
-        if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
-                kb = K_UNICODE;
-        else
+        if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && parse_boolean(utf8) == 0)
                 kb = K_XLATE;
+        else
+                kb = K_UNICODE;
 
         (void) ioctl(vt, KDSKBMODE, kb);