From 33f1871b8b8b567f3d2bfb7f216a63491426eade Mon Sep 17 00:00:00 2001 From: Soumendra Ganguly Date: Sat, 11 Feb 2023 15:10:53 -0600 Subject: [PATCH 1/4] New additions to the tty library. Functions added: cfmakeraw(), and cfmakecbreak(). The functions setcbreak() and setraw() now return original termios to save an extra tcgetattr() call. Signed-off-by: Soumendra Ganguly --- Doc/library/tty.rst | 18 ++++++++++-- Lib/tty.py | 70 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index b30bc3c7ac42e9..37776c7d5acee4 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -20,18 +20,32 @@ Because it requires the :mod:`termios` module, it will work only on Unix. The :mod:`tty` module defines the following functions: +.. function:: cfmakeraw(mode) + + Convert the tty attribute list *mode*, which is a list like the one returned + by :func:`termios.tcgetattr`, to that of a tty in raw mode. + + +.. function:: cfmakecbreak(mode) + + Convert the tty attribute list *mode*, which is a list like the one returned + by :func:`termios.tcgetattr`, to that of a tty in cbreak mode. + + .. function:: setraw(fd, when=termios.TCSAFLUSH) Change the mode of the file descriptor *fd* to raw. If *when* is omitted, it defaults to :const:`termios.TCSAFLUSH`, and is passed to - :func:`termios.tcsetattr`. + :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` + is saved before setting *fd* to raw mode; this value is returned. .. function:: setcbreak(fd, when=termios.TCSAFLUSH) Change the mode of file descriptor *fd* to cbreak. If *when* is omitted, it defaults to :const:`termios.TCSAFLUSH`, and is passed to - :func:`termios.tcsetattr`. + :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` + is saved before setting *fd* to cbreak mode; this value is returned. .. seealso:: diff --git a/Lib/tty.py b/Lib/tty.py index a72eb6755450bb..7d916029ff2ce9 100644 --- a/Lib/tty.py +++ b/Lib/tty.py @@ -4,9 +4,9 @@ from termios import * -__all__ = ["setraw", "setcbreak"] +__all__ = ["cfmakeraw", "cfmakecbreak", "setraw", "setcbreak"] -# Indexes for termios list. +# Indices for termios list. IFLAG = 0 OFLAG = 1 CFLAG = 2 @@ -15,22 +15,60 @@ OSPEED = 5 CC = 6 -def setraw(fd, when=TCSAFLUSH): - """Put terminal into a raw mode.""" - mode = tcgetattr(fd) - mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) - mode[OFLAG] = mode[OFLAG] & ~(OPOST) - mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB) - mode[CFLAG] = mode[CFLAG] | CS8 - mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG) +def cfmakeraw(mode): + """Make termios mode raw.""" + # Clear all POSIX.1-2017 input mode flags. + # See chapter 11 "General Terminal Interface" + # of POSIX.1-2017 Base Definitions. + mode[IFLAG] &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | + INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF) + + # Do not post-process output. + mode[OFLAG] &= ~OPOST + + # Disable parity generation and detection; clear character size mask; + # let character size be 8 bits. + mode[CFLAG] &= ~(PARENB | CSIZE) + mode[CFLAG] |= CS8 + + # Clear all POSIX.1-2017 local mode flags. + mode[LFLAG] &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | + IEXTEN | ISIG | NOFLSH | TOSTOP) + + # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing, + # Case B: MIN>0, TIME=0 + # A pending read shall block until MIN (here 1) bytes are received, + # or a signal is received. mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 - tcsetattr(fd, when, mode) -def setcbreak(fd, when=TCSAFLUSH): - """Put terminal into a cbreak mode.""" - mode = tcgetattr(fd) - mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON) +def cfmakecbreak(mode): + """Make termios mode cbreak.""" + # Do not map CR to NL on input. + mode[IFLAG] &= ~(ICRNL) + + # Do not echo characters; disable canonical input. + mode[LFLAG] &= ~(ECHO | ICANON) + + # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing, + # Case B: MIN>0, TIME=0 + # A pending read shall block until MIN (here 1) bytes are received, + # or a signal is received. mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 - tcsetattr(fd, when, mode) + +def setraw(fd, when=TCSAFLUSH): + """Put terminal into raw mode.""" + mode = tcgetattr(fd) + new = list(mode) + cfmakeraw(new) + tcsetattr(fd, when, new) + return mode + +def setcbreak(fd, when=TCSAFLUSH): + """Put terminal into cbreak mode.""" + mode = tcgetattr(fd) + new = list(mode) + cfmakecbreak(new) + tcsetattr(fd, when, new) + return mode From 0bb5bafe8cc0a8b676d3c36870fab666742ac153 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 11 Feb 2023 21:18:12 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst diff --git a/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst new file mode 100644 index 00000000000000..f28b7f45667326 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst @@ -0,0 +1 @@ +New additions and improvements to the tty library. From 286e30c052814bd77894287286676a3c00acf184 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Fri, 19 May 2023 17:41:30 +0000 Subject: [PATCH 3/4] Add versionadded tags and improve NEWS. --- Doc/library/tty.rst | 4 ++++ .../Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index 37776c7d5acee4..702ac294eb14ec 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -25,12 +25,16 @@ The :mod:`tty` module defines the following functions: Convert the tty attribute list *mode*, which is a list like the one returned by :func:`termios.tcgetattr`, to that of a tty in raw mode. +.. versionadded:: 3.12 + .. function:: cfmakecbreak(mode) Convert the tty attribute list *mode*, which is a list like the one returned by :func:`termios.tcgetattr`, to that of a tty in cbreak mode. +.. versionadded:: 3.12 + .. function:: setraw(fd, when=termios.TCSAFLUSH) diff --git a/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst index f28b7f45667326..246530472165f7 100644 --- a/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst +++ b/Misc/NEWS.d/next/Library/2023-02-11-21-18-10.gh-issue-85984.nvzOD0.rst @@ -1 +1,3 @@ -New additions and improvements to the tty library. +Add :func:`tty.cfmakeraw` and :func:`tty.cfmakecbreak` to :mod:`tty` and +modernize, the behavior of :func:`tty.setraw` and :func:`tty.setcbreak` to use +POSIX.1-2017 Chapter 11 "General Terminal Interface" flag masks by default. From 96c03d5c378c41f5bf4e2341d4443fb8d5ebe978 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google LLC]" Date: Fri, 19 May 2023 17:44:48 +0000 Subject: [PATCH 4/4] versionadded indentation --- Doc/library/tty.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index 702ac294eb14ec..fc7f98c7931fa5 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -25,7 +25,7 @@ The :mod:`tty` module defines the following functions: Convert the tty attribute list *mode*, which is a list like the one returned by :func:`termios.tcgetattr`, to that of a tty in raw mode. -.. versionadded:: 3.12 + .. versionadded:: 3.12 .. function:: cfmakecbreak(mode) @@ -33,7 +33,7 @@ The :mod:`tty` module defines the following functions: Convert the tty attribute list *mode*, which is a list like the one returned by :func:`termios.tcgetattr`, to that of a tty in cbreak mode. -.. versionadded:: 3.12 + .. versionadded:: 3.12 .. function:: setraw(fd, when=termios.TCSAFLUSH)