chiark / gitweb /
tree-wide: beautify remaining copyright statements
[elogind.git] / src / login / logind-session-device.c
index 65a0690129b76a2b294c828f9b03d35522817ee5..e10b810dc0a55e7e4a83a793c4398633524fa164 100644 (file)
@@ -1,21 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 /***
-  This file is part of systemd.
-
-  Copyright 2013 David Herrmann
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+  Copyright © 2013 David Herrmann
 ***/
 
 #include <fcntl.h>
@@ -110,7 +95,7 @@ static int session_device_notify(SessionDevice *sd, enum SessionDeviceNotificati
         return sd_bus_send(sd->session->manager->bus, m, NULL);
 }
 
-static int sd_eviocrevoke(int fd) {
+static void sd_eviocrevoke(int fd) {
         static bool warned = false;
 
         assert(fd >= 0);
@@ -122,8 +107,6 @@ static int sd_eviocrevoke(int fd) {
                         warned = true;
                 }
         }
-
-        return 0;
 }
 
 static int sd_drmsetmaster(int fd) {
@@ -170,7 +153,7 @@ static int session_device_open(SessionDevice *sd, bool active) {
                 } else
                         /* DRM-Master is granted to the first user who opens a device automatically (ughh,
                          * racy!). Hence, we just drop DRM-Master in case we were the first. */
-                        sd_drmdropmaster(fd);
+                        (void) sd_drmdropmaster(fd);
                 break;
 
         case DEVICE_TYPE_EVDEV:
@@ -199,6 +182,11 @@ static int session_device_start(SessionDevice *sd) {
         switch (sd->type) {
 
         case DEVICE_TYPE_DRM:
+                if (sd->fd < 0) {
+                        log_error("Failed to re-activate DRM fd, as the fd was lost (maybe logind restart went wrong?)");
+                        return -EBADF;
+                }
+
                 /* Device is kept open. Simply call drmSetMaster() and hope there is no-one else. In case it fails, we
                  * keep the device paused. Maybe at some point we have a drmStealMaster(). */
                 r = sd_drmsetmaster(sd->fd);
@@ -220,7 +208,7 @@ static int session_device_start(SessionDevice *sd) {
 
         case DEVICE_TYPE_UNKNOWN:
         default:
-                /* fallback for devices wihout synchronizations */
+                /* fallback for devices without synchronizations */
                 break;
         }
 
@@ -235,13 +223,20 @@ static void session_device_stop(SessionDevice *sd) {
                 return;
 
         switch (sd->type) {
+
         case DEVICE_TYPE_DRM:
+                if (sd->fd < 0) {
+                        log_error("Failed to de-activate DRM fd, as the fd was lost (maybe logind restart went wrong?)");
+                        return;
+                }
+
                 /* On DRM devices we simply drop DRM-Master but keep it open.
                  * This allows the user to keep resources allocated. The
                  * CAP_SYS_ADMIN restriction to DRM-Master prevents users from
                  * circumventing this. */
                 sd_drmdropmaster(sd->fd);
                 break;
+
         case DEVICE_TYPE_EVDEV:
                 /* Revoke access on evdev file-descriptors during deactivation.
                  * This will basically prevent any operations on the fd and
@@ -249,6 +244,7 @@ static void session_device_stop(SessionDevice *sd) {
                  * protection this way. */
                 sd_eviocrevoke(sd->fd);
                 break;
+
         case DEVICE_TYPE_UNKNOWN:
         default:
                 /* fallback for devices without synchronization */
@@ -411,20 +407,26 @@ error:
 void session_device_free(SessionDevice *sd) {
         assert(sd);
 
+        /* Make sure to remove the pushed fd. */
         if (sd->pushed_fd) {
-                const char *m;
-
-                /* Remove the pushed fd again, just in case. */
-
-                m = strjoina("FDSTOREREMOVE=1\n"
-                             "FDNAME=session-", sd->session->id);
-
-                (void) sd_notify(false, m);
+                _cleanup_free_ char *m = NULL;
+                const char *id;
+                int r;
+
+                /* Session ID does not contain separators. */
+                id = sd->session->id;
+                assert(*(id + strcspn(id, "-\n")) == '\0');
+
+                r = asprintf(&m, "FDSTOREREMOVE=1\n"
+                                 "FDNAME=session-%s-device-%u-%u\n",
+                                 id, major(sd->dev), minor(sd->dev));
+                if (r >= 0)
+                        (void) sd_notify(false, m);
         }
 
         session_device_stop(sd);
         session_device_notify(sd, SESSION_DEVICE_RELEASE);
-        close_nointr(sd->fd);
+        safe_close(sd->fd);
 
         LIST_REMOVE(sd_by_device, sd->device->session_devices, sd);
 
@@ -459,13 +461,15 @@ void session_device_resume_all(Session *s) {
         assert(s);
 
         HASHMAP_FOREACH(sd, s->devices, i) {
-                if (!sd->active) {
-                        if (session_device_start(sd) < 0)
-                                continue;
-                        if (session_device_save(sd) < 0)
-                                continue;
-                        session_device_notify(sd, SESSION_DEVICE_RESUME);
-                }
+                if (sd->active)
+                        continue;
+
+                if (session_device_start(sd) < 0)
+                        continue;
+                if (session_device_save(sd) < 0)
+                        continue;
+
+                session_device_notify(sd, SESSION_DEVICE_RESUME);
         }
 }
 
@@ -476,32 +480,35 @@ void session_device_pause_all(Session *s) {
         assert(s);
 
         HASHMAP_FOREACH(sd, s->devices, i) {
-                if (sd->active) {
-                        session_device_stop(sd);
-                        session_device_notify(sd, SESSION_DEVICE_PAUSE);
-                }
+                if (!sd->active)
+                        continue;
+
+                session_device_stop(sd);
+                session_device_notify(sd, SESSION_DEVICE_PAUSE);
         }
 }
 
 unsigned int session_device_try_pause_all(Session *s) {
+        unsigned num_pending = 0;
         SessionDevice *sd;
         Iterator i;
-        unsigned int num_pending = 0;
 
         assert(s);
 
         HASHMAP_FOREACH(sd, s->devices, i) {
-                if (sd->active) {
-                        session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
-                        ++num_pending;
-                }
+                if (!sd->active)
+                        continue;
+
+                session_device_notify(sd, SESSION_DEVICE_TRY_PAUSE);
+                num_pending++;
         }
 
         return num_pending;
 }
 
 int session_device_save(SessionDevice *sd) {
-        const char *m;
+        _cleanup_free_ char *m = NULL;
+        const char *id;
         int r;
 
         assert(sd);
@@ -516,8 +523,15 @@ int session_device_save(SessionDevice *sd) {
         if (sd->pushed_fd)
                 return 0;
 
-        m = strjoina("FDSTORE=1\n"
-                     "FDNAME=session", sd->session->id);
+        /* Session ID does not contain separators. */
+        id = sd->session->id;
+        assert(*(id + strcspn(id, "-\n")) == '\0');
+
+        r = asprintf(&m, "FDSTORE=1\n"
+                         "FDNAME=session-%s-device-%u-%u\n",
+                         id, major(sd->dev), minor(sd->dev));
+        if (r < 0)
+                return r;
 
         r = sd_pid_notify_with_fds(0, false, m, &sd->fd, 1);
         if (r < 0)
@@ -528,11 +542,12 @@ int session_device_save(SessionDevice *sd) {
 }
 
 void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
-        assert(fd > 0);
+        assert(fd >= 0);
         assert(sd);
         assert(sd->fd < 0);
         assert(!sd->active);
 
         sd->fd = fd;
+        sd->pushed_fd = true;
         sd->active = active;
 }