From cc3678619c6d221ad6c1622f0e03deae58c842f3 Mon Sep 17 00:00:00 2001 From: MMGen Date: Wed, 31 Oct 2018 16:00:13 +0000 Subject: [PATCH] py3port: fix single-keypress terminal input --- mmgen/crypto.py | 7 ++----- mmgen/seed.py | 2 +- mmgen/term.py | 29 +++++++++++++++++------------ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/mmgen/crypto.py b/mmgen/crypto.py index 5a89193a..7e62b67f 100755 --- a/mmgen/crypto.py +++ b/mmgen/crypto.py @@ -127,16 +127,13 @@ def _get_random_data_from_user(uchars): m = 'Enter {} random symbols' if opt.quiet else crmsg['usr_rand_notice'] msg(m.format(uchars)) prompt = 'You may begin typing. {} symbols left: ' - msg_r(prompt.format(uchars)) import time from mmgen.term import get_char_raw,kb_hold_protect - key_data,time_data = '',[] + key_data,time_data = bytes(),[] for i in range(uchars): - kb_hold_protect() - key_data += get_char_raw() - msg_r('\r'+prompt.format(uchars-i-1)) + key_data += get_char_raw('\r'+prompt.format(uchars-i)) time_data.append(time.time()) if opt.quiet: msg_r('\r') diff --git a/mmgen/seed.py b/mmgen/seed.py index e1b03891..25c3be31 100755 --- a/mmgen/seed.py +++ b/mmgen/seed.py @@ -396,7 +396,7 @@ class Mnemonic (SeedSourceUnenc): def get_word(): s,pad = '',0 while True: - ch = get_char_raw('').decode() + ch = get_char_raw('',num_chars=1).decode() if ch in '\b\x7f': if s: s = s[:-1] elif ch in '\n ': diff --git a/mmgen/term.py b/mmgen/term.py index 97f79810..7a7392d7 100755 --- a/mmgen/term.py +++ b/mmgen/term.py @@ -38,6 +38,8 @@ except: def _kb_hold_protect_unix(): + if os.getenv('MMGEN_TEST_SUITE'): return + fd = sys.stdin.fileno() old = termios.tcgetattr(fd) tty.setcbreak(fd) @@ -54,36 +56,39 @@ def _kb_hold_protect_unix(): # Use os.read(), not file.read(), to get a variable number of bytes without blocking. # Request 5 bytes to cover escape sequences generated by F1, F2, .. Fn keys (5 bytes) # as well as UTF8 chars (4 bytes max). -def _get_keypress_unix(prompt='',immed_chars='',prehold_protect=True): - msg_r(prompt) +def _get_keypress_unix(prompt='',immed_chars='',prehold_protect=True,num_chars=5): + fd_err = sys.stderr.fileno() + os.write(fd_err,prompt.encode()) timeout = float(0.3) fd = sys.stdin.fileno() old = termios.tcgetattr(fd) tty.setcbreak(fd) + immed_chars = immed_chars.encode() + if os.getenv('MMGEN_TEST_SUITE'): prehold_protect = False while True: # Protect against held-down key before read() key = select([sys.stdin], [], [], timeout)[0] - ch = os.read(fd,5) + s = os.read(fd,num_chars) if prehold_protect: if key: continue - if immed_chars == 'ALL' or ch in immed_chars: break - if immed_chars == 'ALL_EXCEPT_ENTER' and not ch in '\n\r': break + if immed_chars == 'ALL' or s in immed_chars: break + if immed_chars == 'ALL_EXCEPT_ENTER' and not s in '\n\r': break # Protect against long keypress key = select([sys.stdin], [], [], timeout)[0] if not key: break termios.tcsetattr(fd, termios.TCSADRAIN, old) - return ch + return s -def _get_keypress_unix_raw(prompt='',immed_chars='',prehold_protect=None): +def _get_keypress_unix_raw(prompt='',immed_chars='',prehold_protect=None,num_chars=5): msg_r(prompt) fd = sys.stdin.fileno() old = termios.tcgetattr(fd) tty.setcbreak(fd) - ch = os.read(fd,5) + ch = os.read(fd,num_chars) termios.tcsetattr(fd, termios.TCSADRAIN, old) return ch -def _get_keypress_unix_stub(prompt='',immed_chars='',prehold_protect=None): +def _get_keypress_unix_stub(prompt='',immed_chars='',prehold_protect=None,num_chars=None): msg_r(prompt) return sys.stdin.read(1).encode() @@ -102,7 +107,7 @@ def _kb_hold_protect_mswin(): if float(time.time() - hit_time) > timeout: return -def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True): +def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True,num_chars=None): msg_r(prompt) timeout = float(0.5) @@ -125,14 +130,14 @@ def _get_keypress_mswin(prompt='',immed_chars='',prehold_protect=True): if float(time.time() - hit_time) > timeout: return ch -def _get_keypress_mswin_raw(prompt='',immed_chars='',prehold_protect=None): +def _get_keypress_mswin_raw(prompt='',immed_chars='',prehold_protect=None,num_chars=None): msg_r(prompt) ch = msvcrt.getch() if ord(ch) == 3: raise KeyboardInterrupt return ch -def _get_keypress_mswin_stub(prompt='',immed_chars='',prehold_protect=None): +def _get_keypress_mswin_stub(prompt='',immed_chars='',prehold_protect=None,num_chars=None): msg_r(prompt) return sys.stdin.read(1)