ldlinux: Accept commands from the serial console
authorMatt Fleming <matt.fleming@intel.com>
Fri, 25 Nov 2011 16:22:44 +0000 (16:22 +0000)
committerMatt Fleming <matt.fleming@intel.com>
Fri, 2 Dec 2011 12:13:31 +0000 (12:13 +0000)
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 <matt.fleming@intel.com>
com32/elflink/ldlinux/cli.c
com32/elflink/ldlinux/get_key.c
com32/libutil/include/getkey.h

index 1ed3ea6..7b2da88 100644 (file)
@@ -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)
index f277b43..42ff5c1 100644 (file)
@@ -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 */
index a46de81..0733723 100644 (file)
 
 #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 */