Browse Source

py3port: fix single-keypress terminal input

MMGen 6 years ago
parent
commit
cc3678619c
3 changed files with 20 additions and 18 deletions
  1. 2 5
      mmgen/crypto.py
  2. 1 1
      mmgen/seed.py
  3. 17 12
      mmgen/term.py

+ 2 - 5
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')

+ 1 - 1
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 ':

+ 17 - 12
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)