From 14355639f8a31e8a8b1d46fddcddfa924aa5f426 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 16 Sep 2022 12:25:37 +0000 Subject: [PATCH 01/14] man: document SEATD_VTBOUND --- man/seatd.1.scd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/man/seatd.1.scd b/man/seatd.1.scd index f599a23..48e3f64 100644 --- a/man/seatd.1.scd +++ b/man/seatd.1.scd @@ -41,6 +41,11 @@ client-side of the protocol. The location of the socket for seatd is set at compile-time. +# ENVIRONMENT + +*SEATD_VTBOUND* + If set to "0", the seat will not be bound to a VT. + # SEE ALSO The libseat library, **, *seatd-launch*(1) From 9b8b6e0bf88f02b77835c977ca97017ac6ed850f Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 13 Jan 2023 11:03:43 -0800 Subject: [PATCH 02/14] noop: initialize initial_setup Otherwise the enable_seat callback is never called. --- libseat/backend/noop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libseat/backend/noop.c b/libseat/backend/noop.c index f69aac6..7db8a55 100644 --- a/libseat/backend/noop.c +++ b/libseat/backend/noop.c @@ -115,6 +115,7 @@ static struct libseat *noop_open_seat(const struct libseat_seat_listener *listen return NULL; } + backend->initial_setup = true; backend->seat_listener = listener; backend->seat_listener_data = data; backend->base.impl = &noop_impl; From 207e2a59363037c192278bc51e3693d88d115514 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 27 Jan 2023 11:43:46 +0000 Subject: [PATCH 03/14] man: add missing arg in -n syntax --- man/seatd.1.scd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/seatd.1.scd b/man/seatd.1.scd index 48e3f64..92f8e4b 100644 --- a/man/seatd.1.scd +++ b/man/seatd.1.scd @@ -13,7 +13,7 @@ seatd - A seat management daemon *-h* Show help message and quit. -*-n* +*-n * FD to notify readiness on. A single newline will be written and the fd closed when seatd is ready to serve requests. This is compatible with s6's notification protocol. From 3e0d510b2c46eb18ab7239b029e01475eb2e3810 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 11 Mar 2023 13:56:57 +0000 Subject: [PATCH 04/14] meson: fix seatdpath with absolute bindir Quoting the Meson documentation: > Note that the value returned for built-in options that end in `dir` > such as `bindir` and `libdir` is usually a path relative to (and > inside) the `prefix` but you should not rely on that, as it can also > be an absolute path [in some cases](Builtin-options.md#universal-options). > [`install_dir` arguments](Installing.md) handle that as expected > but if you need an absolute path, e.g. to use in a define etc., > you should use the path concatenation operator like this: > `get_option('prefix') / get_option('localstatedir')`. > Never manually join paths as if they were strings. The concatenation of two absolute paths caused seatd-launch in Nixpkgs to try to launch e.g. /nix/store/43wyk9s2l2z8cparnshbf24d39vm5272-seatd-0.7.0//nix/store/j9a7k4qqwc3byyfmpqwg46shmh6g82yf-seatd-0.7.0-bin/bin/seatd. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 661b39a..0c6c823 100644 --- a/meson.build +++ b/meson.build @@ -22,7 +22,7 @@ if defaultpath == '' endif endif -seatdpath = '@0@/@1@/seatd'.format(get_option('prefix'), get_option('bindir')) +seatdpath = get_option('prefix') / get_option('bindir') / 'seatd' cc = meson.get_compiler('c') From e5b018def8a672cf099df4270e9f3f224b51c09b Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Thu, 30 Mar 2023 07:58:49 -0300 Subject: [PATCH 05/14] noop: Return seat0 as the seat name wlroots' libinput backend expects the name of the seat to either match ID_SEAT from udev, or in case ID_SEAT returns nothing, match seat0. As noop has no seat switching, always returning seat0 as the session name fixes that. Signed-off-by: Anna (navi) Figueiredo Gomes --- libseat/backend/noop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libseat/backend/noop.c b/libseat/backend/noop.c index 7db8a55..141ffd9 100644 --- a/libseat/backend/noop.c +++ b/libseat/backend/noop.c @@ -46,7 +46,7 @@ static int disable_seat(struct libseat *base) { static const char *seat_name(struct libseat *base) { (void)base; - return "noop"; + return "seat0"; } static int open_device(struct libseat *base, const char *path, int *fd) { From 56720a6275032ebafc4aed53d03612e5cc9d8ff7 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Thu, 30 Mar 2023 07:58:51 -0300 Subject: [PATCH 06/14] noop: Additional open flags for `open(2)` Matching the functionallity by the seatd open call. O_NONBLOCK is specially important for libseat, otherwise it hangs while trying to drain all events from an input device fd. Signed-off-by: Anna (navi) Figueiredo Gomes --- libseat/backend/noop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libseat/backend/noop.c b/libseat/backend/noop.c index 141ffd9..18f26c3 100644 --- a/libseat/backend/noop.c +++ b/libseat/backend/noop.c @@ -52,7 +52,7 @@ static const char *seat_name(struct libseat *base) { static int open_device(struct libseat *base, const char *path, int *fd) { (void)base; - int tmpfd = open(path, O_RDWR | O_CLOEXEC); + int tmpfd = open(path, O_RDWR | O_NOCTTY | O_NOFOLLOW | O_CLOEXEC | O_NONBLOCK); if (tmpfd < 0) { log_errorf("Failed to open device: %s", strerror(errno)); return -1; From 1bd042e5b0a524fb7d30953179474e60974aa6ee Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Tue, 23 May 2023 21:31:21 +0100 Subject: [PATCH 07/14] drm: Support drm-subtree drivers on FreeBSD The drm-kmod drivers use linuxkpi and end up with /dev/drm being the canonical path for the devices, but the drm-subtree drivers use drmkpi which has them appear under /dev/dri like Linux. Thus, adapt path_is_drm to recognise both on FreeBSD. --- common/drm.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/common/drm.c b/common/drm.c index 45ed7e5..06d6720 100644 --- a/common/drm.c +++ b/common/drm.c @@ -10,7 +10,8 @@ #define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) #define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) -#define STRLEN(s) ((sizeof(s) / sizeof(s[0])) - 1) +#define STRLEN(s) ((sizeof(s) / sizeof(s[0])) - 1) +#define STR_HAS_PREFIX(prefix, s) (strncmp(prefix, s, STRLEN(prefix)) == 0) int drm_set_master(int fd) { return ioctl(fd, DRM_IOCTL_SET_MASTER, 0); @@ -22,15 +23,18 @@ int drm_drop_master(int fd) { #if defined(__linux__) || defined(__NetBSD__) int path_is_drm(const char *path) { - static const char prefix[] = "/dev/dri/"; - static const int prefixlen = STRLEN(prefix); - return strncmp(prefix, path, prefixlen) == 0; + if (STR_HAS_PREFIX("/dev/dri/", path)) + return 1; + return 0; } #elif defined(__FreeBSD__) int path_is_drm(const char *path) { - static const char prefix[] = "/dev/drm/"; - static const int prefixlen = STRLEN(prefix); - return strncmp(prefix, path, prefixlen) == 0; + if (STR_HAS_PREFIX("/dev/dri/", path)) + return 1; + /* Some drivers have /dev/dri/X symlinked to /dev/drm/X */ + if (STR_HAS_PREFIX("/dev/drm/", path)) + return 1; + return 0; } #else #error Unsupported platform From dbaa859f2899442909ece685634bb16d37f6a2ce Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 5 Jul 2023 10:47:06 +0200 Subject: [PATCH 08/14] define _BSD_SOURCE rather then __BSD_VISIBLE __BSD_VISIBLE was set to 0, causing issues on OpenBSD The proper way is to set _BSD_SOURCE --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0c6c823..18aca69 100644 --- a/meson.build +++ b/meson.build @@ -29,7 +29,7 @@ cc = meson.get_compiler('c') add_project_arguments( [ '-D_XOPEN_SOURCE=700', - '-D__BSD_VISIBLE', + '-D_BSD_SOURCE', '-D_NETBSD_SOURCE', '-DSEATD_VERSION="@0@"'.format(meson.project_version()), '-DSEATD_DEFAULTPATH="@0@"'.format(defaultpath), From f2ff233c264a6332522c2aa05259b913e2e4af4b Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 5 Jul 2023 10:48:14 +0200 Subject: [PATCH 09/14] No -lrt on OpenBSD XXX This is crude, should add meson tests --- meson.build | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 18aca69..36665de 100644 --- a/meson.build +++ b/meson.build @@ -158,8 +158,8 @@ if get_option('libseat-logind') != 'disabled' endif # needed for cross-compilation -realtime = meson.get_compiler('c').find_library('rt') -private_deps += realtime +# realtime = meson.get_compiler('c').find_library('rt') +# private_deps += realtime if with_builtin libseat_c_args += '-DBUILTIN_ENABLED=1' @@ -220,14 +220,14 @@ if with_server [ server_files, 'seatd/seatd.c' ], include_directories: [include_directories('.', 'include')], install: true, - dependencies: [realtime], +# dependencies: [realtime], ) executable( 'seatd-launch', [ 'seatd-launch/seatd-launch.c' ], include_directories: [include_directories('.', 'include')], install: true, - dependencies: [realtime], +# dependencies: [realtime], ) endif From 4b2ecdf936366c79f3c58ef09dee3d87ccca88a8 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 5 Jul 2023 10:49:24 +0200 Subject: [PATCH 10/14] Add basic OpenBSD support XXX more work needed to manage VT switches and proper XXX fbtab(4) support to allow for non-root users --- common/drm.c | 2 +- common/evdev.c | 2 +- common/terminal.c | 12 ++++++++++-- seatd/client.c | 17 +++++++++++++++++ tests/poller.c | 4 ++++ 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/common/drm.c b/common/drm.c index 06d6720..2fbadd5 100644 --- a/common/drm.c +++ b/common/drm.c @@ -21,7 +21,7 @@ int drm_drop_master(int fd) { return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); } -#if defined(__linux__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) int path_is_drm(const char *path) { if (STR_HAS_PREFIX("/dev/dri/", path)) return 1; diff --git a/common/evdev.c b/common/evdev.c index 7ec0fe2..a77bf36 100644 --- a/common/evdev.c +++ b/common/evdev.c @@ -25,7 +25,7 @@ int path_is_evdev(const char *path) { int evdev_revoke(int fd) { return ioctl(fd, EVIOCREVOKE, NULL); } -#elif defined(__NetBSD__) +#elif defined(__NetBSD__) || defined(__OpenBSD__) int path_is_evdev(const char *path) { (void)path; return 0; diff --git a/common/terminal.c b/common/terminal.c index fa220a2..7c1342e 100644 --- a/common/terminal.c +++ b/common/terminal.c @@ -21,7 +21,7 @@ #define K_ENABLE K_XLATE #define K_DISABLE K_RAW #define FRSIG SIGIO -#elif defined(__NetBSD__) +#elif defined(__NetBSD__) || defined(__OpenBSD__) #include #define K_ENABLE K_XLATE #define K_DISABLE K_RAW @@ -147,6 +147,14 @@ static int get_tty_path(int tty, char path[static TTYPATHLEN]) { } return 0; } +#elif defined(__OpenBSD__) +static int get_tty_path(int tty, char path[static TTYPATHLEN]) { + assert(tty >= 0); + if (snprintf(path, TTYPATHLEN, "/dev/ttyC%d", tty) == -1) { + return -1; + } + return 0; +} #else #error Unsupported platform #endif @@ -175,7 +183,7 @@ int terminal_current_vt(int fd) { return -1; } return st.v_active; -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__OpenBSD__) int vt; int res = ioctl(fd, VT_GETACTIVE, &vt); close(fd); diff --git a/seatd/client.c b/seatd/client.c index a33bfe7..0ab16f8 100644 --- a/seatd/client.c +++ b/seatd/client.c @@ -55,6 +55,23 @@ static int get_peer(int fd, pid_t *pid, uid_t *uid, gid_t *gid) { *uid = cred.unp_euid; *gid = cred.unp_egid; return 0; +#elif defined(__OpenBSD__) + struct sockpeercred peercred; + socklen_t len = sizeof(peercred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &len) == -1) { + // assume builtin backend + if (errno == EINVAL) { + *pid = getpid(); + *uid = getuid(); + *gid = getgid(); + return 0; + } + return -1; + } + *pid = peercred.pid; + *uid = peercred.uid; + *gid = peercred.gid; + return 0; #elif defined(__FreeBSD__) struct xucred cred; socklen_t len = sizeof cred; diff --git a/tests/poller.c b/tests/poller.c index 382d9d2..dd36c7d 100644 --- a/tests/poller.c +++ b/tests/poller.c @@ -123,6 +123,10 @@ static int test_signal_event(int signal, void *data) { return 0; } +#ifdef __OpenBSD__ +#define SIGRTMIN SIGUSR1 +#endif + static void test_poller_single_signal(void) { struct poller poller; test_assert(poller_init(&poller) == 0); From a8aee6fa70f68d54fe5f8a0db935cf85e83f849e Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 5 Jul 2023 10:49:24 +0200 Subject: [PATCH 11/14] Add basic OpenBSD support XXX more work needed to manage VT switches and proper XXX fbtab(4) support to allow for non-root users --- common/wscons.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/wscons.c b/common/wscons.c index 33c757e..121074c 100644 --- a/common/wscons.c +++ b/common/wscons.c @@ -10,7 +10,7 @@ #define STRLEN(s) ((sizeof(s) / sizeof(s[0])) - 1) -#if defined(__NetBSD__) +#if defined(__NetBSD__) || defined(__OpenBSD__) int path_is_wscons(const char *path) { static const char wskbd[] = "/dev/wskbd"; static const char wsmouse[] = "/dev/wsmouse"; From 3e9ef69f14f630a719dd464f3c90a7932f1c8296 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Wed, 19 Jul 2023 11:18:33 +0200 Subject: [PATCH 12/14] Bump version to 0.8.0 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0c6c823..516d7d2 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'seatd', 'c', - version: '0.7.0', + version: '0.8.0', license: 'MIT', meson_version: '>=0.60.0', default_options: [ From 0746edbeaeb1c94a54bf833f6167b4a6b8237cbf Mon Sep 17 00:00:00 2001 From: Adrien Demarez Date: Tue, 24 Oct 2023 00:42:37 +0200 Subject: [PATCH 13/14] seatd: fix small bug in assert --- seatd/seat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seatd/seat.c b/seatd/seat.c index 7a66a20..d09b2eb 100644 --- a/seatd/seat.c +++ b/seatd/seat.c @@ -537,7 +537,7 @@ static int seat_disable_client(struct client *client) { errno = EBUSY; return -1; } - assert(seat->active_client = client); + assert(seat->active_client == client); // We *deactivate* all remaining fds. These may later be reactivated. // The reason we cannot just close them is that certain device fds, such From b4462cb033ad3172e6daa98a4eff2883f88ea524 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Wed, 10 Jul 2024 15:19:41 +0200 Subject: [PATCH 14/14] attempt to support VT switches on OpenBSD --- common/terminal.c | 36 +++++++++++++++++++++++++++++++++--- seatd/client.c | 3 ++- seatd/seat.c | 3 ++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/common/terminal.c b/common/terminal.c index 7c1342e..5aac2dd 100644 --- a/common/terminal.c +++ b/common/terminal.c @@ -21,11 +21,17 @@ #define K_ENABLE K_XLATE #define K_DISABLE K_RAW #define FRSIG SIGIO -#elif defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(__NetBSD__) #include #define K_ENABLE K_XLATE #define K_DISABLE K_RAW #define FRSIG 0 // unimplemented +#elif defined(__OpenBSD__) +#include +#include +#define K_ENABLE K_XLATE +#define K_DISABLE K_RAW +#define FRSIG SIGIO #else #error Unsupported platform #endif @@ -161,10 +167,16 @@ static int get_tty_path(int tty, char path[static TTYPATHLEN]) { int terminal_open(int vt) { char path[TTYPATHLEN]; + log_debugf("terminal_open vt %d", vt); +#ifdef __OpenBSD__ + if (vt > 0) + vt--; +#endif if (get_tty_path(vt, path) == -1) { log_errorf("Could not generate tty path: %s", strerror(errno)); return -1; } + log_debugf("terminal_open path %s", path); int fd = open(path, O_RDWR | O_NOCTTY); if (fd == -1) { log_errorf("Could not open target tty: %s", strerror(errno)); @@ -174,7 +186,7 @@ int terminal_open(int vt) { } int terminal_current_vt(int fd) { -#if defined(__linux__) || defined(__NetBSD__) +#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) struct vt_stat st; int res = ioctl(fd, VT_GETSTATE, &st); close(fd); @@ -183,7 +195,7 @@ int terminal_current_vt(int fd) { return -1; } return st.v_active; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(__FreeBSD__) int vt; int res = ioctl(fd, VT_GETACTIVE, &vt); close(fd); @@ -252,11 +264,20 @@ int terminal_ack_acquire(int fd) { int terminal_set_keyboard(int fd, bool enable) { log_debugf("Setting KD keyboard state to %d", enable); +#ifndef __OpenBSD1__ if (ioctl(fd, KDSKBMODE, enable ? K_ENABLE : K_DISABLE) == -1) { log_errorf("Could not set KD keyboard mode to %s: %s", enable ? "enabled" : "disabled", strerror(errno)); return -1; } +#else + int mode = enable ? WSKBD_RAW : WSKBD_TRANSLATED; + if (ioctl(fd, WSKBDIO_SETMODE, &mode) == -1) { + log_errorf("Could not set keyboard mode to %s: %s", + enable ? "translated" : "raw", strerror(errno)); + return -1; + } +#endif #if defined(__FreeBSD__) struct termios tios; if (tcgetattr(fd, &tios) == -1) { @@ -279,10 +300,19 @@ int terminal_set_keyboard(int fd, bool enable) { int terminal_set_graphics(int fd, bool enable) { log_debugf("Setting KD graphics state to %d", enable); +#ifndef __OpenBSD1__ if (ioctl(fd, KDSETMODE, enable ? KD_GRAPHICS : KD_TEXT) == -1) { log_errorf("Could not set KD graphics mode to %s: %s", enable ? "graphics" : "text", strerror(errno)); return -1; } +#else + int mode = enable ? WSDISPLAYIO_MODE_MAPPED : WSDISPLAYIO_MODE_EMUL; + if (ioctl(fd, WSDISPLAYIO_SMODE, &mode) == -1) { + log_errorf("Could not set graphics mode to %s: %s", + enable ? "mapped" : "emul", strerror(errno)); + return -1; + } +#endif return 0; } diff --git a/seatd/client.c b/seatd/client.c index 0ab16f8..481704e 100644 --- a/seatd/client.c +++ b/seatd/client.c @@ -327,7 +327,7 @@ static int handle_switch_session(struct client *client, int session) { log_error("Protocol error: no seat associated with client"); return -1; } - + log_debugf("handle_switch_session %d", session); if (seat_set_next_session(client, session) == -1) { goto error; } @@ -370,6 +370,7 @@ static int handle_ping(struct client *client) { static int client_handle_opcode(struct client *client, uint16_t opcode, size_t size) { int res = 0; + log_debugf("client_handle_opcode: %d\n", opcode); switch (opcode) { case CLIENT_OPEN_SEAT: { if (size != 0) { diff --git a/seatd/seat.c b/seatd/seat.c index d09b2eb..8820992 100644 --- a/seatd/seat.c +++ b/seatd/seat.c @@ -87,8 +87,8 @@ static int vt_close(int vt) { return -1; } terminal_set_process_switching(ttyfd, true); - terminal_set_keyboard(ttyfd, true); terminal_set_graphics(ttyfd, false); + terminal_set_keyboard(ttyfd, true); close(ttyfd); return 0; } @@ -107,6 +107,7 @@ static int vt_switch(struct seat *seat, int vt) { static int vt_ack(struct seat *seat, bool release) { int tty0fd = terminal_open(seat->cur_vt); + log_debugf("vt_ack VT %d %d\n", seat->cur_vt, release); if (tty0fd == -1) { log_errorf("Could not open tty0 to ack VT signal: %s", strerror(errno)); return -1;