35 lines
1012 B
Python
35 lines
1012 B
Python
import fcntl
|
|
import os
|
|
import select
|
|
import sys
|
|
import termios
|
|
from contextlib import contextmanager
|
|
|
|
|
|
@contextmanager
|
|
def setup_term(*args, **kwargs):
|
|
fd = sys.stdin.fileno()
|
|
oldterm = termios.tcgetattr(fd)
|
|
newattr = termios.tcgetattr(fd)
|
|
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
|
|
termios.tcsetattr(fd, termios.TCSANOW, newattr)
|
|
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
|
|
try:
|
|
yield
|
|
finally:
|
|
# restore terminal settings
|
|
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
|
|
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
|
|
|
|
|
|
def getch(timeout):
|
|
# sys.stdin.read is blocking, use select instead
|
|
# NOTE: this will not work on windows as select only accepts sockets, not all file descriptors
|
|
# TODO: use python selectors module?
|
|
o, _, _ = select.select([sys.stdin], [], [], timeout)
|
|
if o != []:
|
|
assert len(o) == 1
|
|
return o[0].read(1)
|
|
return None
|