Skip to content

Commit 486bc8e

Browse files
8vasublurb-it[bot]gpshead
authored
gh-85984: New additions and improvements to the tty library. (#101832)
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 <soumendraganguly@gmail.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
1 parent 3ac856e commit 486bc8e

File tree

3 files changed

+77
-18
lines changed

3 files changed

+77
-18
lines changed

Doc/library/tty.rst

+20-2
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,36 @@ Because it requires the :mod:`termios` module, it will work only on Unix.
2020
The :mod:`tty` module defines the following functions:
2121

2222

23+
.. function:: cfmakeraw(mode)
24+
25+
Convert the tty attribute list *mode*, which is a list like the one returned
26+
by :func:`termios.tcgetattr`, to that of a tty in raw mode.
27+
28+
.. versionadded:: 3.12
29+
30+
31+
.. function:: cfmakecbreak(mode)
32+
33+
Convert the tty attribute list *mode*, which is a list like the one returned
34+
by :func:`termios.tcgetattr`, to that of a tty in cbreak mode.
35+
36+
.. versionadded:: 3.12
37+
38+
2339
.. function:: setraw(fd, when=termios.TCSAFLUSH)
2440

2541
Change the mode of the file descriptor *fd* to raw. If *when* is omitted, it
2642
defaults to :const:`termios.TCSAFLUSH`, and is passed to
27-
:func:`termios.tcsetattr`.
43+
:func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr`
44+
is saved before setting *fd* to raw mode; this value is returned.
2845

2946

3047
.. function:: setcbreak(fd, when=termios.TCSAFLUSH)
3148

3249
Change the mode of file descriptor *fd* to cbreak. If *when* is omitted, it
3350
defaults to :const:`termios.TCSAFLUSH`, and is passed to
34-
:func:`termios.tcsetattr`.
51+
:func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr`
52+
is saved before setting *fd* to cbreak mode; this value is returned.
3553

3654

3755
.. seealso::

Lib/tty.py

+54-16
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
from termios import *
66

7-
__all__ = ["setraw", "setcbreak"]
7+
__all__ = ["cfmakeraw", "cfmakecbreak", "setraw", "setcbreak"]
88

9-
# Indexes for termios list.
9+
# Indices for termios list.
1010
IFLAG = 0
1111
OFLAG = 1
1212
CFLAG = 2
@@ -15,22 +15,60 @@
1515
OSPEED = 5
1616
CC = 6
1717

18-
def setraw(fd, when=TCSAFLUSH):
19-
"""Put terminal into a raw mode."""
20-
mode = tcgetattr(fd)
21-
mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
22-
mode[OFLAG] = mode[OFLAG] & ~(OPOST)
23-
mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB)
24-
mode[CFLAG] = mode[CFLAG] | CS8
25-
mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
18+
def cfmakeraw(mode):
19+
"""Make termios mode raw."""
20+
# Clear all POSIX.1-2017 input mode flags.
21+
# See chapter 11 "General Terminal Interface"
22+
# of POSIX.1-2017 Base Definitions.
23+
mode[IFLAG] &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP |
24+
INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)
25+
26+
# Do not post-process output.
27+
mode[OFLAG] &= ~OPOST
28+
29+
# Disable parity generation and detection; clear character size mask;
30+
# let character size be 8 bits.
31+
mode[CFLAG] &= ~(PARENB | CSIZE)
32+
mode[CFLAG] |= CS8
33+
34+
# Clear all POSIX.1-2017 local mode flags.
35+
mode[LFLAG] &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON |
36+
IEXTEN | ISIG | NOFLSH | TOSTOP)
37+
38+
# POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
39+
# Case B: MIN>0, TIME=0
40+
# A pending read shall block until MIN (here 1) bytes are received,
41+
# or a signal is received.
2642
mode[CC][VMIN] = 1
2743
mode[CC][VTIME] = 0
28-
tcsetattr(fd, when, mode)
2944

30-
def setcbreak(fd, when=TCSAFLUSH):
31-
"""Put terminal into a cbreak mode."""
32-
mode = tcgetattr(fd)
33-
mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
45+
def cfmakecbreak(mode):
46+
"""Make termios mode cbreak."""
47+
# Do not map CR to NL on input.
48+
mode[IFLAG] &= ~(ICRNL)
49+
50+
# Do not echo characters; disable canonical input.
51+
mode[LFLAG] &= ~(ECHO | ICANON)
52+
53+
# POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
54+
# Case B: MIN>0, TIME=0
55+
# A pending read shall block until MIN (here 1) bytes are received,
56+
# or a signal is received.
3457
mode[CC][VMIN] = 1
3558
mode[CC][VTIME] = 0
36-
tcsetattr(fd, when, mode)
59+
60+
def setraw(fd, when=TCSAFLUSH):
61+
"""Put terminal into raw mode."""
62+
mode = tcgetattr(fd)
63+
new = list(mode)
64+
cfmakeraw(new)
65+
tcsetattr(fd, when, new)
66+
return mode
67+
68+
def setcbreak(fd, when=TCSAFLUSH):
69+
"""Put terminal into cbreak mode."""
70+
mode = tcgetattr(fd)
71+
new = list(mode)
72+
cfmakecbreak(new)
73+
tcsetattr(fd, when, new)
74+
return mode
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add :func:`tty.cfmakeraw` and :func:`tty.cfmakecbreak` to :mod:`tty` and
2+
modernize, the behavior of :func:`tty.setraw` and :func:`tty.setcbreak` to use
3+
POSIX.1-2017 Chapter 11 "General Terminal Interface" flag masks by default.

0 commit comments

Comments
 (0)