diff options
Diffstat (limited to 'libseat')
| -rw-r--r-- | libseat/backend/noop.c | 135 | ||||
| -rw-r--r-- | libseat/libseat.c | 5 | 
2 files changed, 140 insertions, 0 deletions
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);  | 
