◐ Shell
clean mode source ↗

gh-85984: Add _POSIX_VDISABLE from unistd.h to termios module. by 8vasu · Pull Request #114985 · python/cpython

@8vasu

@8vasu 8vasu commented

Feb 4, 2024

edited by bedevere-app Bot

Loading

This follows #102413.

POSIX General Terminal Interface defines Special Control Characters. An example of this is the INTR character, which is usually set to Control-C, which sends the SIGINT signal to interrupt a process running in the terminal.

POSIX General Terminal Interface allows the programmer to disable these characters by setting them to _POSIX_VDISABLE, which is defined in POSIX <unistd.h>. This is how POSIX stty(1) disables special control characters internally; for example, running the following command will disable the INTR character:

stty intr undef

Now hitting Control-C will not send SIGINT to the running process until it is reset using the following command:

stty intr ^c.

At any given point of time, check all terminal settings by running stty -a.

This PR adds _POSIX_VDISABLE to the termios module.

Signed-off-by: Soumendra Ganguly <soumendraganguly@gmail.com>

@8vasu

@gpshead @encukou

In a previous PR in this series (#101832), I mentioned the idea of writing a Python library that mimics stty(1) to provide a unified, highly convenient, and Pythonic interface to termios and winsize functionalities. While working on this, I noticed the lack _POSIX_VDISABLE in the termios library.

This is not a dependency of the main set of changes of this series in #101833, but since this idea was conceived while working on this issue and since this PR is so small, I did not create a separate issue for this.

I have added a test script as a comment.

8vasu

#ifdef _POSIX_VDISABLE
{"_POSIX_VDISABLE", _POSIX_VDISABLE},
#endif

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following script uses termios._POSIX_VDISABLE to disable INTR. Then it calls stty(1) to check if INTR has successfully been disabled.

#!/usr/bin/python3

# Written and tested on Debian GNU/Linux 12 (bookworm) using stty (GNU coreutils) 9.1.

import subprocess
import termios

def stty_intr_value():
    out = subprocess.run(['stty', '-a'], stdout=subprocess.PIPE, text=True).stdout
    s = out.replace(";", " ")
    sub = "intr = "
    i = s.find(sub) + len(sub)
    return s[i:].split()[0]

t = termios.tcgetattr(0)
t[6][termios.VINTR] = bytes([termios._POSIX_VDISABLE])
termios.tcsetattr(0, termios.TCSANOW, t)

assert stty_intr_value() == "<undef>"
print("PASSED")

Hit Control-C after running running above script to see SIGINT not being sent.

Please run stty intr ^c to restore Control-C functionality.

@8vasu

@8vasu

@gpshead Thank you so much! I will make my stty-like library available soon and send you a link.

fsc-eriker pushed a commit to fsc-eriker/cpython that referenced this pull request

Feb 14, 2024
…ython#114985)

Signed-off-by: Soumendra Ganguly <soumendraganguly@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>