Search code examples
pythonsubprocesssignalsinterceptsigint

How to stop SIGINT being passed to subprocess in python?


My python script intercepts the SIGINT signal with the signal process module to prevent premature exit, but this signal is passed to a subprocess that I open with Popen. is there some way to prevent passing this signal to the subprocess so that it also is not exited prematurely when the user presses ctrl-c?


Solution

  • You are able to re-assign the role of ctrl-c using the tty module, which allows you to manipulate the assignment of signals. Be warned, however, that unless you put them back the way they were before you modified them, they will persist for the shell's entire session, even after the program exits.

    Here is a simple code snippet to get you started that stores your old tty settings, re-assigns ctrl-c to ctrl-x, and then restores your previous tty settings upon exit.

    import sys
    import tty
    
    # Back up previous tty settings
    stdin_fileno = sys.stdin.fileno()
    old_ttyattr = tty.tcgetattr(stdin_fileno)
    
    try:
        print 'Reassigning ctrl-c to ctrl-x'
    
        # Enter raw mode on local tty
        tty.setraw(stdin_fileno)
        raw_ta = tty.tcgetattr(stdin_fileno)
        raw_ta[tty.LFLAG] |= tty.ISIG
        raw_ta[tty.OFLAG] |= tty.OPOST | tty.ONLCR
    
        # ^X is the new ^C, set this to 0 to disable it entirely
        raw_ta[tty.CC][tty.VINTR] = '\x18'  
    
        # Set raw tty as active tty
        tty.tcsetattr(stdin_fileno, tty.TCSANOW, raw_ta)
    
        # Dummy program loop
        import time
        for _ in range(5):
            print 'doing stuff'
            time.sleep(1)
    
    finally:
        print 'Resetting ctrl-c'
        # Restore previous tty no matter what
        tty.tcsetattr(stdin_fileno, tty.TCSANOW, old_ttyattr)