How python tty.cfmakeraw() works

ยท 363 words ยท 2 minute read

tty.cfmakeraw() is a function in Python’s tty module that is used to configure a terminal to raw mode. Raw mode is a way of setting the terminal so that the input and output are not processed in the usual way. Instead, input is made available character by character without any processing like line buffering, and output is not transformed in any way.

What does tty.cfmakeraw() do? ๐Ÿ”—

  1. Disabling Canonical Mode: In canonical mode, input is processed in lines. Raw mode disables this, meaning input is available immediately to the program without waiting for a newline character.

  2. Disabling Echo: Normally, when you type characters in a terminal, they are echoed back to you. Raw mode disables this, so characters are not printed to the terminal as they are typed.

  3. Disabling Signal Generation: Special characters like Ctrl+C and Ctrl+Z generate signals (interrupt and suspend, respectively). In raw mode, these signals are disabled, so the program receives the characters instead of the signals.

  4. Disabling Special Handling of Characters: Characters like backspace, delete, and others are not given any special treatment and are passed directly to the program.

How does tty.cfmakeraw() work? ๐Ÿ”—

The function tty.cfmakeraw() takes a termios attribute structure and modifies it to set the terminal to raw mode. Here’s a step-by-step breakdown of what happens:

  1. Importing Modules:

    import termios
    import tty
    
  2. Getting Terminal Attributes: The terminal attributes are typically fetched using termios.tcgetattr(fd), where fd is the file descriptor of the terminal (usually 0 for stdin).

  3. Modifying Attributes: tty.cfmakeraw(attributes) modifies the attributes:

    • Disables canonical mode and echo.
    • Configures the terminal to handle characters one at a time.
    • Disables signals and special character handling.
  4. Applying Attributes: The modified attributes are applied using termios.tcsetattr(fd, termios.TCSANOW, attributes).

tty.cfmakeraw() Example Code ๐Ÿ”—

Here is a simple example to demonstrate:

import termios
import tty
import sys

# Get the current terminal attributes
fd = sys.stdin.fileno()
old_attributes = termios.tcgetattr(fd)

try:
    # Make a copy of the attributes and set them to raw mode
    new_attributes = termios.tcgetattr(fd)
    tty.cfmakeraw(new_attributes)
    termios.tcsetattr(fd, termios.TCSANOW, new_attributes)

    # Now the terminal is in raw mode
    # Example: read a single character without waiting for Enter
    char = sys.stdin.read(1)
    print(f'You pressed: {char}')

finally:
    # Restore the old attributes
    termios.tcsetattr(fd, termios.TCSANOW, old_attributes)