aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2011-11-25 16:22:44 +0000
committerMatt Fleming <matt.fleming@intel.com>2011-12-02 12:13:31 +0000
commit1e4789d4bd9db075929b03015826e4996cb0a37a (patch)
treea283a88884af791d8e294b4d658b503d4732ec07
parent086d698c642f0b8901757a40cef56b04d05bf19c (diff)
downloadsyslinux-1e4789d4bd9db075929b03015826e4996cb0a37a.tar.gz
syslinux-1e4789d4bd9db075929b03015826e4996cb0a37a.tar.xz
syslinux-1e4789d4bd9db075929b03015826e4996cb0a37a.zip
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@intel.com>
-rw-r--r--com32/elflink/ldlinux/cli.c29
-rw-r--r--com32/elflink/ldlinux/get_key.c46
-rw-r--r--com32/libutil/include/getkey.h3
3 files changed, 66 insertions, 12 deletions
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index 1ed3ea63..7b2da880 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 f277b43b..42ff5c12 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 a46de812..0733723b 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 */