]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/login/logind-session.c
logind: split out dbus header files into their own
[thirdparty/systemd.git] / src / login / logind-session.c
index 4b4dd4c060bed5710a58c5f0409ce1cfbca09102..17700c6921901e766d83b0ef3bedce9022635092 100644 (file)
@@ -5,9 +5,9 @@
 #include <linux/kd.h>
 #include <linux/vt.h>
 #include <signal.h>
-#include <stdio_ext.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "sd-messages.h"
 #include "fileio.h"
 #include "format-util.h"
 #include "io-util.h"
+#include "logind-dbus.h"
+#include "logind-seat-dbus.h"
+#include "logind-session-dbus.h"
 #include "logind-session.h"
+#include "logind-user-dbus.h"
 #include "mkdir.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -213,7 +217,6 @@ int session_save(Session *s) {
         if (r < 0)
                 goto fail;
 
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
         (void) fchmod(fileno(f), 0644);
 
         fprintf(f,
@@ -643,20 +646,26 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er
                                 s->leader,
                                 s->user->slice,
                                 description,
-                                STRV_MAKE(s->user->runtime_dir_service, s->user->service), /* These two have StopWhenUnneeded= set, hence add a dep towards them */
-                                STRV_MAKE("systemd-logind.service", "systemd-user-sessions.service", s->user->runtime_dir_service, s->user->service), /* And order us after some more */
+                                /* These two have StopWhenUnneeded= set, hence add a dep towards them */
+                                STRV_MAKE(s->user->runtime_dir_service,
+                                          s->user->service),
+                                /* And order us after some more */
+                                STRV_MAKE("systemd-logind.service",
+                                          "systemd-user-sessions.service",
+                                          s->user->runtime_dir_service,
+                                          s->user->service),
                                 s->user->home,
                                 properties,
                                 error,
                                 &s->scope_job);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(error, r));
+                        return log_error_errno(r, "Failed to start session scope %s: %s",
+                                               scope, bus_error_message(error, r));
 
                 s->scope = TAKE_PTR(scope);
         }
 
-        if (s->scope)
-                (void) hashmap_put(s->manager->session_units, s->scope, s);
+        (void) hashmap_put(s->manager->session_units, s->scope, s);
 
         return 0;
 }
@@ -1227,54 +1236,26 @@ error:
 }
 
 static void session_restore_vt(Session *s) {
-        pid_t pid;
-        int r;
-
-        if (s->vtnr < 1)
-                return;
-
-        if (s->vtfd < 0)
-                return;
+        int r, vt, old_fd;
 
-        /* The virtual terminal can potentially be entering in hung-up state at any time
-         * depending on when the controlling process exits.
-         *
-         * If the controlling process exits while we're restoring the virtual terminal,
-         * the VT will enter in hung-up state and we'll fail at restoring it. To prevent
-         * this case, we kick off the current controlling process (if any) in a child
-         * process so logind doesn't play around with tty ownership.
-         *
-         * If the controlling process already exited, getting a fresh handle to the
-         * virtual terminal reset the hung-up state. */
-        r = safe_fork("(logind)", FORK_REOPEN_LOG|FORK_CLOSE_ALL_FDS|FORK_RESET_SIGNALS|FORK_WAIT|FORK_LOG, &pid);
-        if (r == 0) {
-                char path[sizeof("/dev/tty") + DECIMAL_STR_MAX(s->vtnr)];
-                int vt;
-
-                /* We must be a session leader in order to become the controlling process. */
-                pid = setsid();
-                if (pid < 0) {
-                        log_error_errno(errno, "Failed to become session leader: %m");
-                        _exit(EXIT_FAILURE);
-                }
+        /* We need to get a fresh handle to the virtual terminal,
+         * since the old file-descriptor is potentially in a hung-up
+         * state after the controlling process exited; we do a
+         * little dance to avoid having the terminal be available
+         * for reuse before we've cleaned it up.
+         */
+        old_fd = TAKE_FD(s->vtfd);
 
-                sprintf(path, "/dev/tty%u", s->vtnr);
-                vt = acquire_terminal(path, ACQUIRE_TERMINAL_FORCE, USEC_INFINITY);
-                if (vt < 0) {
-                        log_error_errno(vt, "Cannot acquire VT %s of session %s: %m", path, s->id);
-                        _exit(EXIT_FAILURE);
-                }
+        vt = session_open_vt(s);
+        safe_close(old_fd);
 
-                r = vt_restore(vt);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to restore VT, ignoring: %m");
+        if (vt < 0)
+                return;
 
-                /* Give up and release the controlling terminal. */
-                safe_close(vt);
-                _exit(EXIT_SUCCESS);
-        }
+        r = vt_restore(vt);
+        if (r < 0)
+                log_warning_errno(r, "Failed to restore VT, ignoring: %m");
 
-        /* Close the fd in any cases.  */
         s->vtfd = safe_close(s->vtfd);
 }