aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libseat.h2
-rw-r--r--libseat/backend/noop.c135
-rw-r--r--libseat/libseat.c5
-rw-r--r--meson.build2
4 files changed, 143 insertions, 1 deletions
diff --git a/include/libseat.h b/include/libseat.h
index 5375cd6..82098ea 100644
--- a/include/libseat.h
+++ b/include/libseat.h
@@ -1,6 +1,8 @@
#ifndef _LIBSEAT_H
#define _LIBSEAT_H
+#include <stdarg.h>
+
/*
* An opaque struct containing an opened seat, created by libseat_open_seat and
* destroyed by libseat_close_seat.
diff --git a/libseat/backend/noop.c b/libseat/backend/noop.c
new file mode 100644
index 0000000..71d0224
--- /dev/null
+++ b/libseat/backend/noop.c
@@ -0,0 +1,135 @@
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include "backend.h"
+#include "log.h"
+
+struct backend_noop {
+ struct libseat base;
+ struct libseat_seat_listener *seat_listener;
+ void *seat_listener_data;
+
+ bool initial_setup;
+ int sockets[2];
+};
+
+extern const struct seat_impl noop_impl;
+
+static struct backend_noop *backend_noop_from_libseat_backend(struct libseat *base) {
+ assert(base->impl == &noop_impl);
+ return (struct backend_noop *)base;
+}
+
+static void destroy(struct backend_noop *backend) {
+ close(backend->sockets[0]);
+ close(backend->sockets[1]);
+ free(backend);
+}
+
+static int close_seat(struct libseat *base) {
+ struct backend_noop *backend = backend_noop_from_libseat_backend(base);
+ destroy(backend);
+ return 0;
+}
+
+static int disable_seat(struct libseat *base) {
+ (void)base;
+ return 0;
+}
+
+static const char *seat_name(struct libseat *base) {
+ (void)base;
+ return "noop";
+}
+
+static int open_device(struct libseat *base, const char *path, int *fd) {
+ (void)base;
+
+ int tmpfd = open(path, O_RDWR | O_CLOEXEC);
+ if (tmpfd < 0) {
+ log_errorf("Failed to open device: %s", strerror(errno));
+ return -1;
+ }
+
+ *fd = tmpfd;
+ return tmpfd;
+}
+
+static int close_device(struct libseat *base, int device_id) {
+ (void)base;
+ (void)device_id;
+ return 0;
+}
+
+static int switch_session(struct libseat *base, int s) {
+ (void)base;
+ (void)s;
+ log_errorf("No-op backend cannot switch to session %d", s);
+ return -1;
+}
+
+static int get_fd(struct libseat *base) {
+ struct backend_noop *backend = backend_noop_from_libseat_backend(base);
+ return backend->sockets[0];
+}
+
+static int dispatch_background(struct libseat *base, int timeout) {
+ struct backend_noop *backend = backend_noop_from_libseat_backend(base);
+
+ if (backend->initial_setup) {
+ backend->initial_setup = false;
+ backend->seat_listener->enable_seat(&backend->base, backend->seat_listener_data);
+ }
+
+ struct pollfd fd = {
+ .fd = backend->sockets[0],
+ .events = POLLIN,
+ };
+ if (poll(&fd, 1, timeout) < 0) {
+ if (errno == EAGAIN || errno == EINTR) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static struct libseat *noop_open_seat(struct libseat_seat_listener *listener, void *data) {
+ struct backend_noop *backend = calloc(1, sizeof(struct backend_noop));
+ if (backend == NULL) {
+ return NULL;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, backend->sockets) != 0) {
+ log_errorf("socketpair() failed: %s", strerror(errno));
+ free(backend);
+ return NULL;
+ }
+
+ backend->seat_listener = listener;
+ backend->seat_listener_data = data;
+ backend->base.impl = &noop_impl;
+
+ return &backend->base;
+}
+
+const struct seat_impl noop_impl = {
+ .open_seat = noop_open_seat,
+ .disable_seat = disable_seat,
+ .close_seat = close_seat,
+ .seat_name = seat_name,
+ .open_device = open_device,
+ .close_device = close_device,
+ .switch_session = switch_session,
+ .get_fd = get_fd,
+ .dispatch = dispatch_background,
+};
diff --git a/libseat/libseat.c b/libseat/libseat.c
index b1e8bb2..a7e079c 100644
--- a/libseat/libseat.c
+++ b/libseat/libseat.c
@@ -13,6 +13,7 @@
extern const struct seat_impl seatd_impl;
extern const struct seat_impl logind_impl;
extern const struct seat_impl builtin_impl;
+extern const struct seat_impl noop_impl;
static const struct named_backend impls[] = {
#ifdef SEATD_ENABLED
@@ -24,6 +25,7 @@ static const struct named_backend impls[] = {
#ifdef BUILTIN_ENABLED
{"builtin", &builtin_impl},
#endif
+ {"noop", &noop_impl},
{NULL, NULL},
};
@@ -62,6 +64,9 @@ struct libseat *libseat_open_seat(struct libseat_seat_listener *listener, void *
struct libseat *backend = NULL;
for (const struct named_backend *iter = impls; iter->backend != NULL; iter++) {
+ if (iter->backend == &noop_impl) {
+ continue;
+ }
backend = iter->backend->open_seat(listener, data);
if (backend != NULL) {
log_infof("Seat opened with backend '%s'", iter->name);
diff --git a/meson.build b/meson.build
index f41b621..c3800ae 100644
--- a/meson.build
+++ b/meson.build
@@ -145,7 +145,7 @@ symbols_file = 'libseat/libseat.syms'
symbols_flag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), symbols_file)
lib = library(
'seat', # This results in the library being called 'libseat'
- [ 'libseat/libseat.c' ],
+ [ 'libseat/libseat.c', 'libseat/backend/noop.c' ],
soversion: libseat_soversion,
link_with: private_lib,
include_directories: [include_directories('.', 'include')],