aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2020-09-22 00:54:51 +0200
committerKenny Levinsen <kl@kl.wtf>2020-09-22 01:14:24 +0200
commit521d95349f6aced729192054e24cd04757f4f2ad (patch)
treedf051295700c07adc0eedccf86d83d9b7b76b1bc
parent0132841987f4a847e91d3592162340af425f3c55 (diff)
terminal: Fix VT numbering on FreeBSD
FreeBSD adds one to the VT number returned by the GET_ACTIVE ioctl, so to match things up, the wrapper here subtracted by one. This lead to ttyv0 being named VT 0. This had the side-effect of VT numbering not matching expectations, and switching not behaving as intended. Align numbers with expectations, and move the required subtraction to terminal_open, so that VT 1 matches ttyv0.
-rw-r--r--common/terminal.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/common/terminal.c b/common/terminal.c
index e397357..ad54624 100644
--- a/common/terminal.c
+++ b/common/terminal.c
@@ -38,6 +38,38 @@ static int get_tty_path(int tty, char path[static TTYPATHLEN]) {
const size_t prefix_len = sizeof(prefix) - 1;
strcpy(path, prefix);
+ // The FreeBSD VT_GETACTIVE is implemented in the kernel as follows:
+ //
+ // static int
+ // vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data,
+ // struct thread *td)
+ // {
+ // struct vt_window *vw = tm->tm_softc;
+ // struct vt_device *vd = vw->vw_device;
+ // ...
+ // switch (cmd) {
+ // ...
+ // case VT_GETACTIVE:
+ // *(int *)data = vd->vd_curwindow->vw_number + 1;
+ // return (0);
+ // ...
+ // }
+ // ...
+ // }
+ //
+ // The side-effect here being that the returned VT number is one
+ // greater than the internal VT number. The internal number is what is
+ // used to number the TTY device, while the external number is what we
+ // use in e.g. VT switching.
+ //
+ // We subtract one from the requested TTY number to compensate. If the
+ // user asked for TTY 0 (which is special on Linux), we just give them
+ // the first tty.
+
+ if (tty > 0) {
+ tty--;
+ }
+
// The FreeBSD tty name is constructed in the kernel as follows:
//
// static void
@@ -139,35 +171,11 @@ int terminal_current_vt(int fd) {
return -1;
}
- // The FreeBSD VT_GETACTIVE is implemented in the kernel as follows:
- //
- // static int
- // vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data,
- // struct thread *td)
- // {
- // struct vt_window *vw = tm->tm_softc;
- // struct vt_device *vd = vw->vw_device;
- // ...
- // switch (cmd) {
- // ...
- // case VT_GETACTIVE:
- // *(int *)data = vd->vd_curwindow->vw_number + 1;
- // return (0);
- // ...
- // }
- // ...
- // }
- //
- // The side-effect here being that the returned VT number is one
- // greater than the internal VT number, which is what is used for e.g.
- // numbering the associated VT. To simplify things, we subtract one
- // from the returned VT number before returning it.
-
- if (vt < 1) {
+ if (vt == -1) {
log_errorf("invalid vt: %d", vt);
return -1;
}
- return vt - 1;
+ return vt;
#else
#error Unsupported platform
#endif