History

kdb: Improve handling of characters from different input sources

Currently if an escape timer is interrupted by a character from a different input source then the new character is discarded and the function returns '\e' (which will be discarded by the level above). It is hard to see why this would ever be the desired behaviour. Fix this to return the new character rather than the '\e'. This is a bigger refactor than might be expected because the new character needs to go through escape sequence detection.

Daniel Thompson committed 7 years ago

Commit cdca8d81 parent 4f27e821 file · +19 −19Browse files

Showing the changes to kernel/debug (1 of 1 file). Show all

Unified · Split

kernel/debug/kdb/kdb_io.c+19−19
@@ -127,10 +127,10 @@ char kdb_getchar(void) · 126 unmodified lines
127127 {
128128 #define ESCAPE_UDELAY 1000
129129 #define ESCAPE_DELAY (2*1000000/ESCAPE_UDELAY) /* 2 seconds worth of udelays */
130− char escape_data[5]; /* longest vt100 escape sequence is 4 bytes */
131− char *ped = escape_data;
130+ char buf[4]; /* longest vt100 escape sequence is 4 bytes */
131+ char *pbuf = buf;
132132 int escape_delay = 0;
133− get_char_func *f, *f_escape = NULL;
133+ get_char_func *f, *f_prev = NULL;
134134 int key;
135135
136136 for (f = &kdb_poll_funcs[0]; ; ++f) {
@@ -150,26 +150,26 @@ char kdb_getchar(void) · 13 unmodified lines
150150 continue;
151151 }
152152
153− if (escape_delay == 0 && key == '\e') {
153+ /*
154+ * When the first character is received (or we get a change
155+ * input source) we set ourselves up to handle an escape
156+ * sequences (just in case).
157+ */
158+ if (f_prev != f) {
159+ f_prev = f;
160+ pbuf = buf;
154161 escape_delay = ESCAPE_DELAY;
155− ped = escape_data;
156− f_escape = f;
157− }
158− if (escape_delay) {
159− if (f_escape != f)
160− return '\e';
161−
162− *ped++ = key;
163− key = kdb_handle_escape(escape_data, ped - escape_data);
164− if (key < 0)
165− return '\e';
166− if (key == 0)
167− continue;
168162 }
169163
170− break; /* A key to process */
164+ *pbuf++ = key;
165+ key = kdb_handle_escape(buf, pbuf - buf);
166+ if (key < 0) /* no escape sequence; return first character */
167+ return buf[0];
168+ if (key > 0)
169+ return key;
171170 }
172− return key;
171+
172+ unreachable();
173173 }
174174
175175 /*