From 1e4789d4bd9db075929b03015826e4996cb0a37a Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 25 Nov 2011 16:22:44 +0000 Subject: [PATCH] ldlinux: Accept commands from the serial console To mimic the old (pre-elflink) command-line interface behaviour let's use getchar() instead of reading from stdin. This way, if the user types a command on the serial console it will actually be executed. Signed-off-by: Matt Fleming --- com32/elflink/ldlinux/cli.c | 29 ++++++++++++++++++++++++-- com32/elflink/ldlinux/get_key.c | 46 ++++++++++++++++++++++++++++++++--------- com32/libutil/include/getkey.h | 3 +++ 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index 1ed3ea6..7b2da88 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -29,6 +29,31 @@ void clear_screen(void) fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout); } +static int __get_key(void) +{ + unsigned char buffer[KEY_MAXLEN]; + int another; + int nc, rv; + int code; + + nc = 0; + do { + buffer[nc++] = getchar(); + + another = 0; + rv = get_key_decode(buffer, nc, &code); + if (!rv) + return code; + else if (rv == 1) + another = 1; + + } while (another); + + /* We got an unrecognized sequence; return the first character */ + /* We really should remember this and return subsequent characters later */ + return buffer[0]; +} + int mygetkey(clock_t timeout) { clock_t t0, t; @@ -37,14 +62,14 @@ int mygetkey(clock_t timeout) //dprintf("enter"); if (!totaltimeout) - return get_key(stdin, timeout); + return __get_key(); for (;;) { tto = min(totaltimeout, INT_MAX); to = timeout ? min(tto, timeout) : tto; t0 = 0; - key = get_key(stdin, to); + key = __get_key(); t = 0 - t0; if (totaltimeout <= t) diff --git a/com32/elflink/ldlinux/get_key.c b/com32/elflink/ldlinux/get_key.c index f277b43..42ff5c1 100644 --- a/com32/elflink/ldlinux/get_key.c +++ b/com32/elflink/ldlinux/get_key.c @@ -48,7 +48,6 @@ struct keycode { const unsigned char *seq; }; -#define MAXLEN 8 #define CODE(x,y) { x, (sizeof y)-1, (const unsigned char *)(y) } static const struct keycode keycodes[] = { @@ -118,14 +117,43 @@ static const struct keycode keycodes[] = { #define KEY_TIMEOUT ((CLK_TCK+9)/10) +/* + * Attempt to decode the key sequence in 'buffer'. + * + * On success (the data in 'buffer' matches a key code) put the + * corresponding key code in 'code' and return 0. Return 1 if 'buffer' + * partially matches a key code, i.e. we need more data before we can + * make an unambiguous match. Return -1 if the buffer does not contain + * a key code. + */ +int get_key_decode(char *buffer, int nc, int *code) +{ + const struct keycode *kc; + int i, rv; + + rv = -1; + for (i = 0, kc = keycodes; i < NCODES; i++, kc++) { + if (nc == kc->seqlen && !memcmp(buffer, kc->seq, nc)) { + *code = kc->code; + rv = 0; + break; + } else if (nc < kc->seqlen && !memcmp(buffer, kc->seq, nc)) { + rv = 1; + break; + } + } + + return rv; +} + int get_key(FILE * f, clock_t timeout) { - unsigned char buffer[MAXLEN]; + unsigned char buffer[KEY_MAXLEN]; int nc, i, rv; - const struct keycode *kc; int another; unsigned char ch; clock_t start; + int code; /* We typically start in the middle of a clock tick */ if (timeout) @@ -156,14 +184,12 @@ int get_key(FILE * f, clock_t timeout) buffer[nc++] = ch; another = 0; - for (i = 0, kc = keycodes; i < NCODES; i++, kc++) { - if (nc == kc->seqlen && !memcmp(buffer, kc->seq, nc)) - return kc->code; - else if (nc < kc->seqlen && !memcmp(buffer, kc->seq, nc)) { + rv = get_key_decode(buffer, nc, &code); + if (!rv) + return code; + else if (rv == 1) another = 1; - break; - } - } + } while (another); /* We got an unrecognized sequence; return the first character */ diff --git a/com32/libutil/include/getkey.h b/com32/libutil/include/getkey.h index a46de81..0733723 100644 --- a/com32/libutil/include/getkey.h +++ b/com32/libutil/include/getkey.h @@ -77,8 +77,11 @@ #define KEY_MAX 0x012a +#define KEY_MAXLEN 8 + int get_key(FILE *, clock_t); int key_name_to_code(const char *); const char *key_code_to_name(int); +int get_key_decode(char *, int, int *); #endif /* LIBUTIL_GETKEY_H */ -- 2.7.4