diff options
author | tsoome <tsoome@FreeBSD.org> | 2017-02-06 20:57:17 +0000 |
---|---|---|
committer | tsoome <tsoome@FreeBSD.org> | 2017-02-06 20:57:17 +0000 |
commit | c24e6785098821c4aaf0b543dc091bc2e4e67503 (patch) | |
tree | 7a3948fde10b23bca9890ba089ebe5bb46c21bf5 /sys/boot/i386/common | |
parent | 14e155903dc93ce6bcd38dc26b36593e732b65d5 (diff) | |
download | FreeBSD-src-c24e6785098821c4aaf0b543dc091bc2e4e67503.zip FreeBSD-src-c24e6785098821c4aaf0b543dc091bc2e4e67503.tar.gz |
MFC r310845: boot2 will deadlock if extended keys are used on text input
Approved by: imp (mentor)
Differential Revision: https://reviews.freebsd.org/D8608
Diffstat (limited to 'sys/boot/i386/common')
-rw-r--r-- | sys/boot/i386/common/cons.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/sys/boot/i386/common/cons.c b/sys/boot/i386/common/cons.c index b967d9b..5fb1a93 100644 --- a/sys/boot/i386/common/cons.c +++ b/sys/boot/i386/common/cons.c @@ -65,18 +65,17 @@ int getc(int fn) { - /* - * The extra comparison against zero is an attempt to work around - * what appears to be a bug in QEMU and Bochs. Both emulators - * sometimes report a key-press with scancode one and ascii zero - * when no such key is pressed in reality. As far as I can tell, - * this only happens shortly after a reboot. - */ v86.ctl = V86_FLAGS; v86.addr = 0x16; v86.eax = fn << 8; v86int(); - return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff)); + + if (fn == 0) + return (v86.eax); + + if (V86_ZR(v86.efl)) + return (0); + return (v86.eax); } int @@ -106,14 +105,22 @@ getchar(void) int keyhit(unsigned int secs) { - uint32_t t0, t1; + uint32_t t0, t1, c; if (OPT_CHECK(RBX_NOINTR)) return (0); secs *= SECOND; t0 = 0; for (;;) { - if (xgetc(1)) + /* + * The extra comparison is an attempt to work around + * what appears to be a bug in QEMU and Bochs. Both emulators + * sometimes report a key-press with scancode one and ascii zero + * when no such key is pressed in reality. As far as I can tell, + * this only happens shortly after a reboot. + */ + c = xgetc(1); + if (c != 0 && c != 0x0100) return (1); if (secs > 0) { t1 = *(uint32_t *)PTOV(0x46c); @@ -134,9 +141,19 @@ getstr(char *cmdstr, size_t cmdstrsize) s = cmdstr; for (;;) { - switch (c = xgetc(0)) { - case 0: + c = xgetc(0); + + /* Translate some extended codes. */ + switch (c) { + case 0x5300: /* delete */ + c = '\177'; break; + default: + c &= 0xff; + break; + } + + switch (c) { case '\177': case '\b': if (s > cmdstr) { @@ -149,9 +166,11 @@ getstr(char *cmdstr, size_t cmdstrsize) *s = 0; return; default: - if (s - cmdstr < cmdstrsize - 1) - *s++ = c; - putchar(c); + if (c >= 0x20 && c <= 0x7e) { + if (s - cmdstr < cmdstrsize - 1) + *s++ = c; + putchar(c); + } break; } } |