[syslinux] [PATCH 4/9] ldlinux: get_key() requires raw access to user input

Matt Fleming matt at console-pimps.org
Fri Nov 2 07:13:13 PDT 2012


From: Matt Fleming <matt.fleming at intel.com>

commit 4503e6260c0 ("ldlinux: Use stdcon instead of rawcon for the
console") broke get_key() because it was no longer possible to read
raw data from stdin. Provide a new function raw_read() that will
return user input a character at a time.

Signed-off-by: Matt Fleming <matt.fleming at intel.com>
---
 com32/elflink/ldlinux/Makefile  |  2 +-
 com32/elflink/ldlinux/get_key.c | 22 +++++++++++++++++++++-
 com32/libutil/ansiraw.c         | 19 +++++++++++++++++++
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index dc48ca9..0666d9f 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -14,7 +14,7 @@ topdir = ../../..
 MAKEDIR = $(topdir)/mk
 include $(MAKEDIR)/elf.mk
 
-CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include
+CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib
 LIBS = --whole-archive $(com32)/lib/libcom32min.a
 
 all: ldlinux.c32 ldlinux_lnx.a
diff --git a/com32/elflink/ldlinux/get_key.c b/com32/elflink/ldlinux/get_key.c
index 0be06b9..123171a 100644
--- a/com32/elflink/ldlinux/get_key.c
+++ b/com32/elflink/ldlinux/get_key.c
@@ -41,6 +41,7 @@
 #include <sys/times.h>
 #include <getkey.h>
 #include <libutil.h>
+#include <sys/file.h>
 
 struct keycode {
     int code;
@@ -146,6 +147,25 @@ int get_key_decode(char *buffer, int nc, int *code)
     return rv;
 }
 
+#ifdef __COM32__
+extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count);
+
+int raw_read(int fd, void *buf, size_t count)
+{
+	(void)fd;
+
+	/*
+	 * Instead of using the read(2) stdlib function use
+	 * __rawcon_read() directly since we want a single key and
+	 * don't want any processing/batching of the user input to
+	 * occur - we want the raw data.
+	 */
+	return __rawcon_read(NULL, buf, count);
+}
+#else
+extern int raw_read(int fd, void *buf, size_t count);
+#endif
+
 int get_key(FILE * f, clock_t timeout)
 {
     char buffer[KEY_MAXLEN];
@@ -162,7 +182,7 @@ int get_key(FILE * f, clock_t timeout)
     nc = 0;
     start = times(NULL);
     do {
-	rv = read(fileno(f), &ch, 1);
+	rv = raw_read(fileno(f), &ch, 1);
 	if (rv == 0 || (rv == -1 && errno == EAGAIN)) {
 	    clock_t lateness = times(NULL) - start;
 	    if (nc && lateness > 1 + KEY_TIMEOUT) {
diff --git a/com32/libutil/ansiraw.c b/com32/libutil/ansiraw.c
index 2afd48a..b67768c 100644
--- a/com32/libutil/ansiraw.c
+++ b/com32/libutil/ansiraw.c
@@ -47,6 +47,7 @@ void console_ansi_raw(void)
 
 #include <stdio.h>
 #include <termios.h>
+#include <unistd.h>
 
 static struct termios original_termios_settings;
 
@@ -82,4 +83,22 @@ void console_ansi_raw(void)
     tcsetattr(0, TCSAFLUSH, &tio);
 }
 
+int raw_read(int fd, void *buf, size_t count)
+{
+	struct termios tio, rtio;
+	int rv;
+
+	tcgetattr(fd, &tio);
+
+	cfmakeraw(&rtio);
+	tcsetattr(fd, 0, &rtio);
+
+	rv = read(fd, buf, count);
+
+	/* Restore settings */
+	tcsetattr(fd, 0, &tio);
+
+	return rv;
+}
+
 #endif
-- 
1.7.11.7




More information about the Syslinux mailing list