Compare commits

..

15 commits
0.7.0 ... obsd

Author SHA1 Message Date
b4462cb033 attempt to support VT switches on OpenBSD 2024-07-10 15:19:41 +02:00
cc09e26976 Merge remote-tracking branch 'origin/master' into obsd 2023-11-08 12:00:16 +01:00
Adrien Demarez
0746edbeae seatd: fix small bug in assert 2023-10-24 11:59:51 +02:00
Kenny Levinsen
3e9ef69f14 Bump version to 0.8.0 2023-07-19 11:18:33 +02:00
a8aee6fa70 Add basic OpenBSD support
XXX more work needed to manage VT switches and proper
XXX fbtab(4) support to allow for non-root users
2023-07-05 16:57:27 +02:00
4b2ecdf936 Add basic OpenBSD support
XXX more work needed to manage VT switches and proper
XXX fbtab(4) support to allow for non-root users
2023-07-05 10:49:24 +02:00
f2ff233c26 No -lrt on OpenBSD
XXX This is crude, should add meson tests
2023-07-05 10:48:14 +02:00
dbaa859f28 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
2023-07-05 10:47:06 +02:00
Jessica Clarke
1bd042e5b0 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.
2023-05-24 16:43:21 +02:00
Anna (navi) Figueiredo Gomes
56720a6275 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 <navi@vlhl.dev>
2023-04-01 15:34:53 +02:00
Anna (navi) Figueiredo Gomes
e5b018def8 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 <navi@vlhl.dev>
2023-04-01 15:34:53 +02:00
Alyssa Ross
3e0d510b2c 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.
2023-03-13 17:06:31 +01:00
Simon Ser
207e2a5936 man: add missing arg in -n syntax 2023-01-28 23:10:29 +01:00
Chia-I Wu
9b8b6e0bf8 noop: initialize initial_setup
Otherwise the enable_seat callback is never called.
2023-01-16 13:13:52 +01:00
Simon Ser
14355639f8 man: document SEATD_VTBOUND 2022-11-30 18:38:50 +01:00
10 changed files with 95 additions and 24 deletions

View file

@ -10,7 +10,8 @@
#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) #define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) #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) { int drm_set_master(int fd) {
return ioctl(fd, DRM_IOCTL_SET_MASTER, 0); return ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
@ -20,17 +21,20 @@ int drm_drop_master(int fd) {
return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); 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) { int path_is_drm(const char *path) {
static const char prefix[] = "/dev/dri/"; if (STR_HAS_PREFIX("/dev/dri/", path))
static const int prefixlen = STRLEN(prefix); return 1;
return strncmp(prefix, path, prefixlen) == 0; return 0;
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
int path_is_drm(const char *path) { int path_is_drm(const char *path) {
static const char prefix[] = "/dev/drm/"; if (STR_HAS_PREFIX("/dev/dri/", path))
static const int prefixlen = STRLEN(prefix); return 1;
return strncmp(prefix, path, prefixlen) == 0; /* Some drivers have /dev/dri/X symlinked to /dev/drm/X */
if (STR_HAS_PREFIX("/dev/drm/", path))
return 1;
return 0;
} }
#else #else
#error Unsupported platform #error Unsupported platform

View file

@ -25,7 +25,7 @@ int path_is_evdev(const char *path) {
int evdev_revoke(int fd) { int evdev_revoke(int fd) {
return ioctl(fd, EVIOCREVOKE, NULL); return ioctl(fd, EVIOCREVOKE, NULL);
} }
#elif defined(__NetBSD__) #elif defined(__NetBSD__) || defined(__OpenBSD__)
int path_is_evdev(const char *path) { int path_is_evdev(const char *path) {
(void)path; (void)path;
return 0; return 0;

View file

@ -26,6 +26,12 @@
#define K_ENABLE K_XLATE #define K_ENABLE K_XLATE
#define K_DISABLE K_RAW #define K_DISABLE K_RAW
#define FRSIG 0 // unimplemented #define FRSIG 0 // unimplemented
#elif defined(__OpenBSD__)
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplay_usl_io.h>
#define K_ENABLE K_XLATE
#define K_DISABLE K_RAW
#define FRSIG SIGIO
#else #else
#error Unsupported platform #error Unsupported platform
#endif #endif
@ -147,16 +153,30 @@ static int get_tty_path(int tty, char path[static TTYPATHLEN]) {
} }
return 0; 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 #else
#error Unsupported platform #error Unsupported platform
#endif #endif
int terminal_open(int vt) { int terminal_open(int vt) {
char path[TTYPATHLEN]; char path[TTYPATHLEN];
log_debugf("terminal_open vt %d", vt);
#ifdef __OpenBSD__
if (vt > 0)
vt--;
#endif
if (get_tty_path(vt, path) == -1) { if (get_tty_path(vt, path) == -1) {
log_errorf("Could not generate tty path: %s", strerror(errno)); log_errorf("Could not generate tty path: %s", strerror(errno));
return -1; return -1;
} }
log_debugf("terminal_open path %s", path);
int fd = open(path, O_RDWR | O_NOCTTY); int fd = open(path, O_RDWR | O_NOCTTY);
if (fd == -1) { if (fd == -1) {
log_errorf("Could not open target tty: %s", strerror(errno)); log_errorf("Could not open target tty: %s", strerror(errno));
@ -166,7 +186,7 @@ int terminal_open(int vt) {
} }
int terminal_current_vt(int fd) { int terminal_current_vt(int fd) {
#if defined(__linux__) || defined(__NetBSD__) #if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__)
struct vt_stat st; struct vt_stat st;
int res = ioctl(fd, VT_GETSTATE, &st); int res = ioctl(fd, VT_GETSTATE, &st);
close(fd); close(fd);
@ -244,11 +264,20 @@ int terminal_ack_acquire(int fd) {
int terminal_set_keyboard(int fd, bool enable) { int terminal_set_keyboard(int fd, bool enable) {
log_debugf("Setting KD keyboard state to %d", enable); log_debugf("Setting KD keyboard state to %d", enable);
#ifndef __OpenBSD1__
if (ioctl(fd, KDSKBMODE, enable ? K_ENABLE : K_DISABLE) == -1) { if (ioctl(fd, KDSKBMODE, enable ? K_ENABLE : K_DISABLE) == -1) {
log_errorf("Could not set KD keyboard mode to %s: %s", log_errorf("Could not set KD keyboard mode to %s: %s",
enable ? "enabled" : "disabled", strerror(errno)); enable ? "enabled" : "disabled", strerror(errno));
return -1; 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__) #if defined(__FreeBSD__)
struct termios tios; struct termios tios;
if (tcgetattr(fd, &tios) == -1) { if (tcgetattr(fd, &tios) == -1) {
@ -271,10 +300,19 @@ int terminal_set_keyboard(int fd, bool enable) {
int terminal_set_graphics(int fd, bool enable) { int terminal_set_graphics(int fd, bool enable) {
log_debugf("Setting KD graphics state to %d", enable); log_debugf("Setting KD graphics state to %d", enable);
#ifndef __OpenBSD1__
if (ioctl(fd, KDSETMODE, enable ? KD_GRAPHICS : KD_TEXT) == -1) { if (ioctl(fd, KDSETMODE, enable ? KD_GRAPHICS : KD_TEXT) == -1) {
log_errorf("Could not set KD graphics mode to %s: %s", enable ? "graphics" : "text", log_errorf("Could not set KD graphics mode to %s: %s", enable ? "graphics" : "text",
strerror(errno)); strerror(errno));
return -1; 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; return 0;
} }

View file

@ -10,7 +10,7 @@
#define STRLEN(s) ((sizeof(s) / sizeof(s[0])) - 1) #define STRLEN(s) ((sizeof(s) / sizeof(s[0])) - 1)
#if defined(__NetBSD__) #if defined(__NetBSD__) || defined(__OpenBSD__)
int path_is_wscons(const char *path) { int path_is_wscons(const char *path) {
static const char wskbd[] = "/dev/wskbd"; static const char wskbd[] = "/dev/wskbd";
static const char wsmouse[] = "/dev/wsmouse"; static const char wsmouse[] = "/dev/wsmouse";

View file

@ -46,13 +46,13 @@ static int disable_seat(struct libseat *base) {
static const char *seat_name(struct libseat *base) { static const char *seat_name(struct libseat *base) {
(void)base; (void)base;
return "noop"; return "seat0";
} }
static int open_device(struct libseat *base, const char *path, int *fd) { static int open_device(struct libseat *base, const char *path, int *fd) {
(void)base; (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) { if (tmpfd < 0) {
log_errorf("Failed to open device: %s", strerror(errno)); log_errorf("Failed to open device: %s", strerror(errno));
return -1; return -1;
@ -115,6 +115,7 @@ static struct libseat *noop_open_seat(const struct libseat_seat_listener *listen
return NULL; return NULL;
} }
backend->initial_setup = true;
backend->seat_listener = listener; backend->seat_listener = listener;
backend->seat_listener_data = data; backend->seat_listener_data = data;
backend->base.impl = &noop_impl; backend->base.impl = &noop_impl;

View file

@ -13,7 +13,7 @@ seatd - A seat management daemon
*-h* *-h*
Show help message and quit. Show help message and quit.
*-n* *-n <fd>*
FD to notify readiness on. A single newline will be written and the fd 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 closed when seatd is ready to serve requests. This is compatible with
s6's notification protocol. s6's notification protocol.
@ -41,6 +41,11 @@ client-side of the protocol.
The location of the socket for seatd is set at compile-time. 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 # SEE ALSO
The libseat library, *<libseat.h>*, *seatd-launch*(1) The libseat library, *<libseat.h>*, *seatd-launch*(1)

View file

@ -1,7 +1,7 @@
project( project(
'seatd', 'seatd',
'c', 'c',
version: '0.7.0', version: '0.8.0',
license: 'MIT', license: 'MIT',
meson_version: '>=0.60.0', meson_version: '>=0.60.0',
default_options: [ default_options: [
@ -22,14 +22,14 @@ if defaultpath == ''
endif endif
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') cc = meson.get_compiler('c')
add_project_arguments( add_project_arguments(
[ [
'-D_XOPEN_SOURCE=700', '-D_XOPEN_SOURCE=700',
'-D__BSD_VISIBLE', '-D_BSD_SOURCE',
'-D_NETBSD_SOURCE', '-D_NETBSD_SOURCE',
'-DSEATD_VERSION="@0@"'.format(meson.project_version()), '-DSEATD_VERSION="@0@"'.format(meson.project_version()),
'-DSEATD_DEFAULTPATH="@0@"'.format(defaultpath), '-DSEATD_DEFAULTPATH="@0@"'.format(defaultpath),
@ -158,8 +158,8 @@ if get_option('libseat-logind') != 'disabled'
endif endif
# needed for cross-compilation # needed for cross-compilation
realtime = meson.get_compiler('c').find_library('rt') # realtime = meson.get_compiler('c').find_library('rt')
private_deps += realtime # private_deps += realtime
if with_builtin if with_builtin
libseat_c_args += '-DBUILTIN_ENABLED=1' libseat_c_args += '-DBUILTIN_ENABLED=1'
@ -220,14 +220,14 @@ if with_server
[ server_files, 'seatd/seatd.c' ], [ server_files, 'seatd/seatd.c' ],
include_directories: [include_directories('.', 'include')], include_directories: [include_directories('.', 'include')],
install: true, install: true,
dependencies: [realtime], # dependencies: [realtime],
) )
executable( executable(
'seatd-launch', 'seatd-launch',
[ 'seatd-launch/seatd-launch.c' ], [ 'seatd-launch/seatd-launch.c' ],
include_directories: [include_directories('.', 'include')], include_directories: [include_directories('.', 'include')],
install: true, install: true,
dependencies: [realtime], # dependencies: [realtime],
) )
endif endif

View file

@ -55,6 +55,23 @@ static int get_peer(int fd, pid_t *pid, uid_t *uid, gid_t *gid) {
*uid = cred.unp_euid; *uid = cred.unp_euid;
*gid = cred.unp_egid; *gid = cred.unp_egid;
return 0; 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__) #elif defined(__FreeBSD__)
struct xucred cred; struct xucred cred;
socklen_t len = sizeof cred; socklen_t len = sizeof cred;
@ -310,7 +327,7 @@ static int handle_switch_session(struct client *client, int session) {
log_error("Protocol error: no seat associated with client"); log_error("Protocol error: no seat associated with client");
return -1; return -1;
} }
log_debugf("handle_switch_session %d", session);
if (seat_set_next_session(client, session) == -1) { if (seat_set_next_session(client, session) == -1) {
goto error; goto error;
} }
@ -353,6 +370,7 @@ static int handle_ping(struct client *client) {
static int client_handle_opcode(struct client *client, uint16_t opcode, size_t size) { static int client_handle_opcode(struct client *client, uint16_t opcode, size_t size) {
int res = 0; int res = 0;
log_debugf("client_handle_opcode: %d\n", opcode);
switch (opcode) { switch (opcode) {
case CLIENT_OPEN_SEAT: { case CLIENT_OPEN_SEAT: {
if (size != 0) { if (size != 0) {

View file

@ -87,8 +87,8 @@ static int vt_close(int vt) {
return -1; return -1;
} }
terminal_set_process_switching(ttyfd, true); terminal_set_process_switching(ttyfd, true);
terminal_set_keyboard(ttyfd, true);
terminal_set_graphics(ttyfd, false); terminal_set_graphics(ttyfd, false);
terminal_set_keyboard(ttyfd, true);
close(ttyfd); close(ttyfd);
return 0; return 0;
} }
@ -107,6 +107,7 @@ static int vt_switch(struct seat *seat, int vt) {
static int vt_ack(struct seat *seat, bool release) { static int vt_ack(struct seat *seat, bool release) {
int tty0fd = terminal_open(seat->cur_vt); int tty0fd = terminal_open(seat->cur_vt);
log_debugf("vt_ack VT %d %d\n", seat->cur_vt, release);
if (tty0fd == -1) { if (tty0fd == -1) {
log_errorf("Could not open tty0 to ack VT signal: %s", strerror(errno)); log_errorf("Could not open tty0 to ack VT signal: %s", strerror(errno));
return -1; return -1;
@ -537,7 +538,7 @@ static int seat_disable_client(struct client *client) {
errno = EBUSY; errno = EBUSY;
return -1; return -1;
} }
assert(seat->active_client = client); assert(seat->active_client == client);
// We *deactivate* all remaining fds. These may later be reactivated. // We *deactivate* all remaining fds. These may later be reactivated.
// The reason we cannot just close them is that certain device fds, such // The reason we cannot just close them is that certain device fds, such

View file

@ -123,6 +123,10 @@ static int test_signal_event(int signal, void *data) {
return 0; return 0;
} }
#ifdef __OpenBSD__
#define SIGRTMIN SIGUSR1
#endif
static void test_poller_single_signal(void) { static void test_poller_single_signal(void) {
struct poller poller; struct poller poller;
test_assert(poller_init(&poller) == 0); test_assert(poller_init(&poller) == 0);