aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2020-08-02 20:21:19 +0200
committerKenny Levinsen <kl@kl.wtf>2020-08-02 21:46:10 +0200
commitb751481e5c0bed1b81b7c769923e772e9fd84e9d (patch)
treea08c88eb9b3755afb9b9ba70535ef98944de9301 /common
parentb731b18e0a086e65aa25ed2a5e53488076f5ad37 (diff)
seat: Open/close tty on activation/deactivation
The VT and KD ioctl's are picky about the tty fd used. In order to satisfy these, and to improve state cleanup, we now only and store the current tty when opening a client, and use this fd to perform teardown later. The presence of the fd is also used to signal that teardown is needed.
Diffstat (limited to 'common')
-rw-r--r--common/terminal.c191
1 files changed, 41 insertions, 150 deletions
diff --git a/common/terminal.c b/common/terminal.c
index bcd843d..da66143 100644
--- a/common/terminal.c
+++ b/common/terminal.c
@@ -1,27 +1,26 @@
-#include "string.h"
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#if defined(__linux__)
#include <linux/kd.h>
#include <linux/vt.h>
-#define TTY0 "/dev/tty0"
-#define TTYF "/dev/tty%d"
-#define K_ON K_UNICODE
-#define FRSIG 0
+#define TTYF "/dev/tty%d"
+#define K_ENABLE K_UNICODE
+#define K_DISABLE K_OFF
+#define FRSIG 0
#elif defined(__FreeBSD__)
#include <sys/consio.h>
#include <sys/kbio.h>
-#define TTY0 "/dev/ttyv0"
-#define TTYF "/dev/ttyv%d"
-#define K_ON K_XLATE
-#define K_OFF K_CODE
-#define FRSIG SIGIO
+#define TTYF "/dev/ttyv%d"
+#define K_ENABLE K_XLATE
+#define K_DISABLE K_CODE
+#define FRSIG SIGIO
#else
#error Unsupported platform
#endif
@@ -31,13 +30,21 @@
#define TTYPATHLEN 64
-int terminal_current_vt(void) {
- int fd = open(TTY0, O_RDWR | O_NOCTTY);
+int terminal_open(int vt) {
+ char path[TTYPATHLEN];
+ if (snprintf(path, TTYPATHLEN, TTYF, vt) == -1) {
+ log_errorf("could not generate tty path: %s", strerror(errno));
+ return -1;
+ }
+ int fd = open(path, O_RDWR | O_NOCTTY);
if (fd == -1) {
- log_errorf("could not open tty0: %s", strerror(errno));
+ log_errorf("could not open target tty: %s", strerror(errno));
return -1;
}
+ return fd;
+}
+int terminal_current_vt(int fd) {
#if defined(__linux__)
struct vt_stat st;
int res = ioctl(fd, VT_GETSTATE, &st);
@@ -61,173 +68,57 @@ int terminal_current_vt(void) {
#endif
}
-int terminal_setup(int vt) {
- log_debugf("setting up vt %d", vt);
- if (vt == -1) {
- vt = 0;
- }
- char path[TTYPATHLEN];
- if (snprintf(path, TTYPATHLEN, TTYF, vt) == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int fd = open(path, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not open target tty: %s", strerror(errno));
- return -1;
- }
-
- static struct vt_mode mode = {
- .mode = VT_PROCESS,
+int terminal_set_process_switching(int fd, bool enable) {
+ log_debug("setting process switching");
+ struct vt_mode mode = {
+ .mode = enable ? VT_PROCESS : VT_AUTO,
.waitv = 0,
- .relsig = SIGUSR1,
- .acqsig = SIGUSR2,
+ .relsig = enable ? SIGUSR1 : 0,
+ .acqsig = enable ? SIGUSR2 : 0,
.frsig = FRSIG,
};
- int res = ioctl(fd, VT_SETMODE, &mode);
- close(fd);
- if (res == -1) {
- log_errorf("could not set VT mode: %s", strerror(errno));
- }
-
- return res;
-}
-
-int terminal_teardown(int vt) {
- log_debugf("tearing down vt %d", vt);
- if (vt == -1) {
- vt = 0;
- }
- char path[TTYPATHLEN];
- if (snprintf(path, TTYPATHLEN, TTYF, vt) == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int fd = open(path, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not open target tty: %s", strerror(errno));
- return -1;
- }
- if (ioctl(fd, KDSETMODE, KD_TEXT) == -1) {
- log_errorf("could not set KD graphics mode: %s", strerror(errno));
- close(fd);
- return -1;
- }
- if (ioctl(fd, KDSKBMODE, K_ON) == -1) {
- log_errorf("could not set KD keyboard mode: %s", strerror(errno));
- close(fd);
- return -1;
- }
-
- static struct vt_mode mode = {
- .mode = VT_PROCESS,
- .waitv = 0,
- .relsig = SIGUSR1,
- .acqsig = SIGUSR2,
- .frsig = FRSIG,
- };
if (ioctl(fd, VT_SETMODE, &mode) == -1) {
log_errorf("could not set VT mode: %s", strerror(errno));
- close(fd);
return -1;
}
-
- close(fd);
return 0;
}
-int terminal_switch_vt(int vt) {
+int terminal_switch_vt(int fd, int vt) {
log_debugf("switching to vt %d", vt);
- int fd = open(TTY0, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not open tty0: %s", strerror(errno));
- return -1;
- }
-
- static struct vt_mode mode = {
- .mode = VT_PROCESS,
- .waitv = 0,
- .relsig = SIGUSR1,
- .acqsig = SIGUSR2,
- .frsig = FRSIG,
- };
-
- if (ioctl(fd, VT_SETMODE, &mode) == -1) {
- log_errorf("could not set VT mode: %s", strerror(errno));
- close(fd);
- return -1;
- }
-
if (ioctl(fd, VT_ACTIVATE, vt) == -1) {
log_errorf("could not activate VT: %s", strerror(errno));
- close(fd);
return -1;
}
- close(fd);
return 0;
}
-int terminal_ack_switch(void) {
+int terminal_ack_switch(int fd) {
log_debug("acking vt switch");
- int fd = open(TTY0, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not open tty0: %s", strerror(errno));
- return -1;
- }
-
- int res = ioctl(fd, VT_RELDISP, VT_ACKACQ);
- close(fd);
- if (res == -1) {
+ if (ioctl(fd, VT_RELDISP, VT_ACKACQ) == -1) {
log_errorf("could not ack VT switch: %s", strerror(errno));
+ return -1;
}
- return res;
+ return 0;
}
-int terminal_set_keyboard(int vt, bool enable) {
- log_debugf("setting KD keyboard state to %d on vt %d", enable, vt);
- if (vt == -1) {
- vt = 0;
- }
- char path[TTYPATHLEN];
- if (snprintf(path, TTYPATHLEN, TTYF, vt) == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int fd = open(path, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int res = ioctl(fd, KDSKBMODE, enable ? K_ON : K_OFF);
- close(fd);
- if (res == -1) {
+int terminal_set_keyboard(int fd, bool enable) {
+ log_debugf("setting KD keyboard state to %d", enable);
+ if (ioctl(fd, KDSKBMODE, enable ? K_ENABLE : K_DISABLE) == -1) {
log_errorf("could not set KD keyboard mode: %s", strerror(errno));
+ return -1;
}
- return res;
+ return 0;
}
-int terminal_set_graphics(int vt, bool enable) {
- log_debugf("setting KD graphics state to %d on vt %d", enable, vt);
- if (vt == -1) {
- vt = 0;
- }
- char path[TTYPATHLEN];
- if (snprintf(path, TTYPATHLEN, TTYF, vt) == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int fd = open(path, O_RDWR | O_NOCTTY);
- if (fd == -1) {
- log_errorf("could not generate tty path: %s", strerror(errno));
- return -1;
- }
- int res = ioctl(fd, KDSETMODE, enable ? KD_GRAPHICS : KD_TEXT);
- close(fd);
- if (res == -1) {
+int terminal_set_graphics(int fd, bool enable) {
+ log_debugf("setting KD graphics state to %d", enable);
+ if (ioctl(fd, KDSETMODE, enable ? KD_GRAPHICS : KD_TEXT) == -1) {
log_errorf("could not set KD graphics mode: %s", strerror(errno));
+ return -1;
}
- return res;
+ return 0;
}