From cbda6f66f480cf647a55da90120c882faa4ed971 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 27 Aug 2020 05:11:15 +0000 Subject: [PATCH] Implement FLUSHO Turn FLUSHO on/off with ^O (or whatever VDISCARD is). Honor that to throw away output quickly. This tries to remain true to 4.4BSD behavior (since that was the origin of this feature), with any corrections NetBSD has done. Since the implemenations are a little different, though, some edge conditions may be handled differently. Reviewed by: kib, kevans Differential Review: https://reviews.freebsd.org/D26148 --- sys/kern/tty.c | 3 +++ sys/kern/tty_ttydisc.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index a6ed98f86297..5cdaa10728d6 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1467,6 +1467,7 @@ tty_signal_sessleader(struct tty *tp, int sig) /* Make signals start output again. */ tp->t_flags &= ~TF_STOPPED; + tp->t_termios.c_lflag &= ~FLUSHO; if (tp->t_session != NULL && tp->t_session->s_leader != NULL) { p = tp->t_session->s_leader; @@ -1486,6 +1487,7 @@ tty_signal_pgrp(struct tty *tp, int sig) /* Make signals start output again. */ tp->t_flags &= ~TF_STOPPED; + tp->t_termios.c_lflag &= ~FLUSHO; if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO)) tty_info(tp); @@ -1930,6 +1932,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag, return (0); case TIOCSTART: tp->t_flags &= ~TF_STOPPED; + tp->t_termios.c_lflag &= ~FLUSHO; ttydevsw_outwakeup(tp); ttydevsw_pktnotify(tp, TIOCPKT_START); return (0); diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c index 0e3c785545a1..546b610010a3 100644 --- a/sys/kern/tty_ttydisc.c +++ b/sys/kern/tty_ttydisc.c @@ -95,6 +95,7 @@ ttydisc_close(struct tty *tp) /* Clean up our flags when leaving the discipline. */ tp->t_flags &= ~(TF_STOPPED|TF_HIWAT|TF_ZOMBIE); + tp->t_termios.c_lflag &= ~FLUSHO; /* * POSIX states that we must drain output and flush input on @@ -474,6 +475,12 @@ ttydisc_write(struct tty *tp, struct uio *uio, int ioflag) MPASS(oblen == 0); + if (CMP_FLAG(l, FLUSHO)) { + uio->uio_offset += uio->uio_resid; + uio->uio_resid = 0; + return (0); + } + /* Step 1: read data. */ obstart = ob; nlen = MIN(uio->uio_resid, sizeof ob); @@ -495,6 +502,12 @@ ttydisc_write(struct tty *tp, struct uio *uio, int ioflag) do { unsigned int plen, wlen; + if (CMP_FLAG(l, FLUSHO)) { + uio->uio_offset += uio->uio_resid; + uio->uio_resid = 0; + return (0); + } + /* Search for special characters for post processing. */ if (CMP_FLAG(o, OPOST)) { plen = ttydisc_findchar(obstart, oblen); @@ -629,6 +642,9 @@ static int ttydisc_echo_force(struct tty *tp, char c, int quote) { + if (CMP_FLAG(l, FLUSHO)) + return 0; + if (CMP_FLAG(o, OPOST) && CTL_ECHO(c, quote)) { /* * Only perform postprocessing when OPOST is turned on @@ -879,8 +895,10 @@ ttydisc_rint(struct tty *tp, char c, int flags) } /* Allow any character to perform a wakeup. */ - if (CMP_FLAG(i, IXANY)) + if (CMP_FLAG(i, IXANY)) { tp->t_flags &= ~TF_STOPPED; + tp->t_termios.c_lflag &= ~FLUSHO; + } /* Remove the top bit. */ if (CMP_FLAG(i, ISTRIP)) @@ -906,6 +924,18 @@ ttydisc_rint(struct tty *tp, char c, int flags) tp->t_flags |= TF_LITERAL; return (0); } + /* Discard processing */ + if (CMP_CC(VDISCARD, c)) { + if (CMP_FLAG(l, FLUSHO)) { + tp->t_termios.c_lflag &= ~FLUSHO; + } else { + tty_flush(tp, FWRITE); + ttydisc_echo(tp, c, 0); + if (tp->t_inq.ti_end > 0) + ttydisc_reprint(tp); + tp->t_termios.c_lflag |= FLUSHO; + } + } } /*