[U-Boot] [PATCH v2 28/31] sandbox: Allow Ctrl-C to work in sandbox

Simon Glass sjg at chromium.org
Thu Feb 27 21:26:22 CET 2014


It is useful for Cltl-C to be handled by U-Boot as it is on other boards.
But it is also useful to be able to terminate U-Boot with Ctrl-C.

Add an option to enable signals while in raw mode, and make this the
default. Add an option to leave the terminal cooked, which is useful for
redirecting output.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2: None

 arch/sandbox/cpu/os.c            | 13 +++++++------
 arch/sandbox/cpu/start.c         | 28 ++++++++++++++++++++++++++++
 arch/sandbox/include/asm/state.h | 24 ++++++++++++++++++++++++
 drivers/serial/sandbox.c         |  6 +++++-
 include/os.h                     |  6 +++++-
 5 files changed, 69 insertions(+), 8 deletions(-)

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 460ed88..6d5946e 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -99,21 +99,22 @@ void os_exit(int exit_code)
 
 /* Restore tty state when we exit */
 static struct termios orig_term;
+static bool term_setup;
 
 static void os_fd_restore(void)
 {
-	tcsetattr(0, TCSANOW, &orig_term);
+	if (term_setup)
+		tcsetattr(0, TCSANOW, &orig_term);
 }
 
 /* Put tty into raw mode so <tab> and <ctrl+c> work */
-void os_tty_raw(int fd)
+void os_tty_raw(int fd, bool allow_sigs)
 {
-	static int setup = 0;
 	struct termios term;
 
-	if (setup)
+	if (term_setup)
 		return;
-	setup = 1;
+	term_setup = true;
 
 	/* If not a tty, don't complain */
 	if (tcgetattr(fd, &orig_term))
@@ -123,7 +124,7 @@ void os_tty_raw(int fd)
 	term.c_iflag = IGNBRK | IGNPAR;
 	term.c_oflag = OPOST | ONLCR;
 	term.c_cflag = CS8 | CREAD | CLOCAL;
-	term.c_lflag = 0;
+	term.c_lflag = allow_sigs ? ISIG : 0;
 	if (tcsetattr(fd, TCSANOW, &term))
 		return;
 
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 4d5569e..36dfc0a 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -184,6 +184,34 @@ static int sandbox_cmdline_cb_show_lcd(struct sandbox_state *state,
 SANDBOX_CMDLINE_OPT_SHORT(show_lcd, 'l', 0,
 			  "Show the sandbox LCD display");
 
+static const char *term_args[STATE_TERM_COUNT] = {
+	"raw-with-sigs",
+	"raw",
+	"cooked",
+};
+
+static int sandbox_cmdline_cb_terminal(struct sandbox_state *state,
+				       const char *arg)
+{
+	int i;
+
+	for (i = 0; i < STATE_TERM_COUNT; i++) {
+		if (!strcmp(arg, term_args[i])) {
+			state->term_raw = i;
+			return 0;
+		}
+	}
+
+	printf("Unknown terminal setting '%s' (", arg);
+	for (i = 0; i < STATE_TERM_COUNT; i++)
+		printf("%s%s", i ? ", " : "", term_args[i]);
+	puts(")\n");
+
+	return 1;
+}
+SANDBOX_CMDLINE_OPT_SHORT(terminal, 't', 1,
+			  "Set terminal to raw/cooked mode");
+
 int main(int argc, char *argv[])
 {
 	struct sandbox_state *state;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 895b3a4..56bd9a0 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -17,6 +17,29 @@ enum exit_type_id {
 	STATE_EXIT_POWER_OFF,
 };
 
+/**
+ * Selects the behavior of the serial terminal.
+ *
+ * If Ctrl-C is processed by U-Boot, then the only way to quit sandbox is with
+ * the 'reset' command, or equivalent.
+ *
+ * If the terminal is cooked, then Ctrl-C will terminate U-Boot, and the
+ * command line will not be quite such a faithful emulation.
+ *
+ * Options are:
+ *
+ *	raw-with-sigs		- Raw, but allow signals (Ctrl-C will quit)
+ *	raw			- Terminal is always raw
+ *	cooked			- Terminal is always cooked
+ */
+enum state_terminal_raw {
+	STATE_TERM_RAW_WITH_SIGS,	/* Default */
+	STATE_TERM_RAW,
+	STATE_TERM_COOKED,
+
+	STATE_TERM_COUNT,
+};
+
 struct sandbox_spi_info {
 	const char *spec;
 	const struct sandbox_spi_emu_ops *ops;
@@ -42,6 +65,7 @@ struct sandbox_state {
 	bool write_state;		/* Write sandbox state on exit */
 	bool ignore_missing_state_on_read;	/* No error if state missing */
 	bool show_lcd;			/* Show LCD on start-up */
+	enum state_terminal_raw term_raw;	/* Terminal raw/cooked */
 
 	/* Pointer to information for each SPI bus/cs */
 	struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index c27b5b8..51fd871 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -15,6 +15,7 @@
 #include <os.h>
 #include <serial.h>
 #include <linux/compiler.h>
+#include <asm/state.h>
 
 /*
  *
@@ -31,7 +32,10 @@ static unsigned int serial_buf_read;
 
 static int sandbox_serial_init(void)
 {
-	os_tty_raw(0);
+	struct sandbox_state *state = state_get_current();
+
+	if (state->term_raw != STATE_TERM_COOKED)
+		os_tty_raw(0, state->term_raw == STATE_TERM_RAW_WITH_SIGS);
 	return 0;
 }
 
diff --git a/include/os.h b/include/os.h
index ac8c8bb..f647bb7 100644
--- a/include/os.h
+++ b/include/os.h
@@ -95,8 +95,12 @@ void os_exit(int exit_code) __attribute__((noreturn));
 
 /**
  * Put tty into raw mode to mimic serial console better
+ *
+ * @param fd		File descriptor of stdin (normally 0)
+ * @param allow_sigs	Allow Ctrl-C, Ctrl-Z to generate signals rather than
+ *			be handled by U-Boot
  */
-void os_tty_raw(int fd);
+void os_tty_raw(int fd, bool allow_sigs);
 
 /**
  * Acquires some memory from the underlying os.
-- 
1.9.0.279.gdc9e3eb



More information about the U-Boot mailing list