From 4fdb1b227cf6853f31fb655bc3e327ae16e7f09b Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Sun, 2 Aug 2020 20:18:37 +0000 Subject: [PATCH] vt(4): CONS_HISTORY/CONS_CLRHIST should operate on issuing terminal Currently the CONS_HISTORY and CONS_CLRHIST ioctls modify the state of the active terminal instead of the terminal against which the ioctl was issued. Because of the way vidcontrol(1) works, these are the same in most cases. But a poorly-timed window switch can make them differ. This is reproducible by issuing e.g. 'vidcontrol -s 2 && vidcontrol -C' to switch from vty 1 to vty 2; teken will reset the cursor position on vty 1 but vt(4) will clear the history buffer of vty 2, producing an interesting state of affairs. Differential Revision: https://reviews.freebsd.org/D25564 --- sys/dev/vt/vt_core.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 5311a8bd6788..952dcbbbb6b9 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -454,7 +454,7 @@ vt_window_postswitch(struct vt_window *vw) return (0); } -/* vt_late_window_switch will done VT switching for regular case. */ +/* vt_late_window_switch will do VT switching for regular case. */ static int vt_late_window_switch(struct vt_window *vw) { @@ -2326,12 +2326,11 @@ vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data, case CONS_HISTORY: if (*(int *)data < 0) return EINVAL; - if (*(int *)data != vd->vd_curwindow->vw_buf.vb_history_size) - vtbuf_sethistory_size(&vd->vd_curwindow->vw_buf, - *(int *)data); + if (*(int *)data != vw->vw_buf.vb_history_size) + vtbuf_sethistory_size(&vw->vw_buf, *(int *)data); return (0); case CONS_CLRHIST: - vtbuf_clearhistory(&vd->vd_curwindow->vw_buf); + vtbuf_clearhistory(&vw->vw_buf); /* * Invalidate the entire visible window; it is not guaranteed * that this operation will be immediately followed by a scroll @@ -2339,9 +2338,11 @@ vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data, * to remain visible. */ VT_LOCK(vd); - vd->vd_flags |= VDF_INVALID; + if (vw == vd->vd_curwindow) { + vd->vd_flags |= VDF_INVALID; + vt_resume_flush_timer(vw, 0); + } VT_UNLOCK(vd); - vt_resume_flush_timer(vd->vd_curwindow, 0); return (0); case CONS_GET: /* XXX */