aboutsummaryrefslogtreecommitdiffstats
path: root/logind.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-03-04 06:39:15 +0100
committerGerd Hoffmann <kraxel@redhat.com>2019-03-04 06:39:15 +0100
commita54addaa25769da1df006562974f699319bf1172 (patch)
treed900524fc5809593c677968e97ba614d93e564d9 /logind.c
parentc7759d655484c105bce6dc86a036585e01347f6c (diff)
downloadfbida-a54addaa25769da1df006562974f699319bf1172.tar.gz
move logind code to separate file
Diffstat (limited to 'logind.c')
-rw-r--r--logind.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/logind.c b/logind.c
new file mode 100644
index 0000000..b426609
--- /dev/null
+++ b/logind.c
@@ -0,0 +1,196 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <inttypes.h>
+#include <time.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <termios.h>
+
+#include <sys/stat.h>
+
+#include "config.h"
+#ifdef HAVE_SYSTEMD
+# include <systemd/sd-bus.h>
+#endif
+
+#include "logind.h"
+#include "kbd.h"
+
+#ifdef HAVE_SYSTEMD
+
+/* ---------------------------------------------------------------------- */
+
+static sd_bus *logind_dbus = NULL;
+
+int logind_init(void)
+{
+ int r;
+
+ r = sd_bus_open_system(&logind_dbus);
+ if (r < 0) {
+ fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
+ return -1;
+ }
+
+ r = logind_take_control();
+ if (r < 0) {
+ sd_bus_unref(logind_dbus);
+ logind_dbus = NULL;
+ return -1;
+ }
+
+ fprintf(stderr, "Opening input devices via logind.\n");
+ return 0;
+}
+
+int logind_take_control(void)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ int r;
+
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "TakeControl",
+ &error,
+ &m,
+ "b",
+ false);
+ if (r < 0) {
+ fprintf(stderr, "TakeControl failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ }
+ sd_bus_message_unref(m);
+
+ return r;
+}
+
+int logind_open(const char *path, int flags, void *user_data)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ struct stat st;
+ unsigned int maj, min;
+ int inactive;
+ int handle, fd, r;
+
+ r = stat(path, &st);
+ if (r < 0) {
+ fprintf(stderr, "stat %s failed: %s\n", path, strerror(errno));
+ libinput_deverror++;
+ return -1;
+ }
+
+ maj = major(st.st_rdev);
+ min = minor(st.st_rdev);
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "TakeDevice",
+ &error,
+ &m,
+ "uu",
+ maj,
+ min);
+ if (r < 0) {
+ fprintf(stderr, "TakeDevice failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ libinput_deverror++;
+ return -1;
+ }
+
+ handle = -1;
+ inactive = -1;
+ r = sd_bus_message_read(m, "hb", &handle, &inactive);
+ if (r < 0) {
+ fd = -1;
+ fprintf(stderr, "Parsing TakeDevice reply failed: %s\n", strerror(-r));
+ libinput_deverror++;
+ } else {
+ fd = fcntl(handle, F_DUPFD_CLOEXEC, 0);
+ fprintf(stderr, "open %s: got fd %d via logind.\n",
+ path, fd);
+ libinput_devcount++;
+ }
+ sd_bus_message_unref(m);
+
+ return fd;
+}
+
+void logind_close(int fd, void *user_data)
+{
+ sd_bus_error error = SD_BUS_ERROR_NULL;
+ sd_bus_message *m = NULL;
+ struct stat st;
+ unsigned int maj, min;
+ int r;
+
+ r = fstat(fd, &st);
+ if (r < 0) {
+ fprintf(stderr, "fstat failed: %s\n", strerror(errno));
+ return;
+ }
+ close(fd);
+
+ maj = major(st.st_rdev);
+ min = minor(st.st_rdev);
+ r = sd_bus_call_method(logind_dbus,
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1/session/self",
+ "org.freedesktop.login1.Session",
+ "ReleaseDevice",
+ &error,
+ &m,
+ "uu",
+ maj,
+ min);
+ if (r < 0) {
+ fprintf(stderr, "ReleaseDevice failed: %s\n", error.message);
+ sd_bus_error_free(&error);
+ }
+ sd_bus_message_unref(m);
+ libinput_devcount--;
+ return;
+}
+
+#else
+
+/* ---------------------------------------------------------------------- */
+
+int logind_init(void)
+{
+ fprintf(stderr, "warning: compiled without logind support.\n");
+ return -1;
+}
+
+int logind_take_control(void)
+{
+ return -1;
+}
+
+int logind_open(const char *path, int flags, void *user_data)
+{
+ fprintf(stderr, "error: compiled without logind support.\n");
+ libinput_deverror++;
+ errno = ENOSYS;
+ return -1;
+}
+
+void logind_close(int fd, void *user_data)
+{
+}
+
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+const struct libinput_interface libinput_if_logind = {
+ .open_restricted = logind_open,
+ .close_restricted = logind_close,
+};