Skip to content

Commit a684142

Browse files
committed
Soumendra Ganguly: new additions to the tty library. Functions added: cfmakeecho(), cfmakeraw(), and cfmakecbreak().
The functions setcbreak() and setraw() now return original termios to save an extra tcgetattr() call. Signed-off-by: Soumendra Ganguly <[email protected]>
1 parent bc662c0 commit a684142

File tree

3 files changed

+89
-18
lines changed

3 files changed

+89
-18
lines changed

Doc/library/tty.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,39 @@ 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:: cfmakeecho(mode, echo=True)
24+
25+
Set ECHO in the tty attribute list *mode*, which is a list like the one
26+
returned by :func:`termios.tcgetattr`, if *echo* is :const:`True` or is
27+
omitted. Unset ECHO if *echo* is :const:`False`.
28+
29+
30+
.. function:: cfmakeraw(mode)
31+
32+
Convert the tty attribute list *mode*, which is a list like the one returned
33+
by :func:`termios.tcgetattr`, to that of a tty in raw mode.
34+
35+
36+
.. function:: cfmakecbreak(mode)
37+
38+
Convert the tty attribute list *mode*, which is a list like the one returned
39+
by :func:`termios.tcgetattr`, to that of a tty in cbreak mode.
40+
41+
2342
.. function:: setraw(fd, when=termios.TCSAFLUSH)
2443

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

2949

3050
.. function:: setcbreak(fd, when=termios.TCSAFLUSH)
3151

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

3657

3758
.. seealso::

Lib/tty.py

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
from termios import *
66

7-
__all__ = ["setraw", "setcbreak"]
7+
__all__ = ["cfmakeecho", "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,70 @@
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 cfmakeecho(mode, echo=True):
19+
"""Set/unset ECHO."""
20+
if echo:
21+
mode[LFLAG] |= ECHO
22+
else:
23+
mode[LFLAG] &= ~ECHO
24+
25+
def cfmakeraw(mode):
26+
"""raw mode termios"""
27+
# Clear all POSIX.1-2017 input mode flags.
28+
mode[IFLAG] &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP |
29+
INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)
30+
31+
# Do not post-process output.
32+
mode[OFLAG] &= ~(OPOST)
33+
34+
# Disable parity generation and detection; clear character size mask;
35+
# let character size be 8 bits.
36+
mode[CFLAG] &= ~(PARENB | CSIZE)
37+
mode[CFLAG] |= CS8
38+
39+
# Do not echo characters (including NL); disable canonical input; disable
40+
# the checking of characters against the special control characters INTR,
41+
# QUIT, and SUSP (disable sending of signals using control characters);
42+
# disable any implementation-defined special control characters not
43+
# currently controlled by ICANON, ISIG, IXON, or IXOFF.
44+
mode[LFLAG] &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN)
45+
46+
# POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
47+
# Case B: MIN>0, TIME=0
48+
# A pending read shall block until MIN (here 1) bytes are received,
49+
# or a signal is received.
2650
mode[CC][VMIN] = 1
2751
mode[CC][VTIME] = 0
28-
tcsetattr(fd, when, mode)
2952

30-
def setcbreak(fd, when=TCSAFLUSH):
31-
"""Put terminal into a cbreak mode."""
32-
mode = tcgetattr(fd)
33-
mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
53+
def cfmakecbreak(mode):
54+
"""cbreak mode termios"""
55+
# Do not map CR to NL on input.
56+
mode[IFLAG] &= ~(ICRNL)
57+
58+
# Do not echo characters; disable canonical input.
59+
mode[LFLAG] &= ~(ECHO | ICANON)
60+
61+
# POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing,
62+
# Case B: MIN>0, TIME=0
63+
# A pending read shall block until MIN (here 1) bytes are received,
64+
# or a signal is received.
3465
mode[CC][VMIN] = 1
3566
mode[CC][VTIME] = 0
36-
tcsetattr(fd, when, mode)
67+
68+
def setraw(fd, when=TCSAFLUSH):
69+
"""Put terminal into raw mode.
70+
Returns original termios."""
71+
mode = tcgetattr(fd)
72+
new = list(mode)
73+
cfmakeraw(new)
74+
tcsetattr(fd, when, new)
75+
return mode
76+
77+
def setcbreak(fd, when=TCSAFLUSH):
78+
"""Put terminal into cbreak mode.
79+
Returns original termios."""
80+
mode = tcgetattr(fd)
81+
new = list(mode)
82+
cfmakecbreak(new)
83+
tcsetattr(fd, when, new)
84+
return mode
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Soumendra Ganguly: new additions to the tty library. Functions added: cfmakeecho(), cfmakeraw(), and cfmakecbreak().
2+
The functions setcbreak() and setraw() now return original termios to save an extra tcgetattr() call.

0 commit comments

Comments
 (0)