[syslinux:elflink] ldlinux: Accept commands from the serial console

syslinux-bot for Matt Fleming matt.fleming at intel.com
Sat Dec 17 21:19:39 PST 2011


Commit-ID:  1e4789d4bd9db075929b03015826e4996cb0a37a
Gitweb:     http://www.syslinux.org/commit/1e4789d4bd9db075929b03015826e4996cb0a37a
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Fri, 25 Nov 2011 16:22:44 +0000
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Fri, 2 Dec 2011 12:13:31 +0000

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 <matt.fleming at intel.com>

---
 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 */


More information about the Syslinux-commits mailing list