From a5a39b5b9134742ddc7b6bd6e9a363bcbbe3c9a4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 6 Apr 2005 21:13:00 +0000 Subject: [PATCH] Enhance shell. --- src/tests/userprog/shell.c | 107 +++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/src/tests/userprog/shell.c b/src/tests/userprog/shell.c index cfff4e3..d31eb3a 100644 --- a/src/tests/userprog/shell.c +++ b/src/tests/userprog/shell.c @@ -1,59 +1,27 @@ +#include #include #include #include +static void read_line (char line[], size_t); +static bool backspace (char **pos, char line[]); + int main (void) { printf ("Shell starting...\n"); for (;;) { - char command[80], *cp; + char command[80]; - /* Prompt. */ + /* Read command. */ printf ("--"); - - /* Read and echo command. */ - cp = command; - for (;;) - { - char c; - read (STDIN_FILENO, &c, 1); - - switch (c) - { - case '\n': - /* Done. */ - goto got_cmd; - - case '\b': - /* Back up cursor, overwrite character, back up again. */ - printf ("\b \b"); - break; - - case 27: /* Escape. */ - case ('U' - 'A') + 1: /* Ctrl+U. */ - /* Clear entire line. */ - printf ("\n--"); - cp = command; - break; - - default: - /* Add character to line. */ - *cp++ = c; - if (cp >= command + sizeof command - 1) - goto got_cmd; - break; - } - } - got_cmd: - *cp = '\0'; - putchar ('\n'); + read_line (command, sizeof command); /* Execute command. */ if (!strcmp (command, "exit")) break; - else if (cp == command) + else if (command[0] == '\0') { /* Empty command. */ } @@ -70,3 +38,62 @@ main (void) printf ("Shell exiting."); return 0; } + +/* Reads a line of input from the user into LINE, which has room + for SIZE bytes. Handles backspace and Ctrl+U in the ways + expected by Unix users. On return, LINE will always be + null-terminated and will not end in a new-line character. */ +static void +read_line (char line[], size_t size) +{ + char *pos = line; + for (;;) + { + char c; + read (STDIN_FILENO, &c, 1); + + switch (c) + { + case '\n': + *pos = '\0'; + putchar ('\n'); + return; + + case '\b': + backspace (&pos, line); + break; + + case ('U' - 'A') + 1: /* Ctrl+U. */ + while (backspace (&pos, line)) + continue; + break; + + default: + /* Add character to line. */ + if (pos < line + size - 1) + { + putchar (c); + *pos++ = c; + } + break; + } + } +} + +/* If *POS is past the beginning of LINE, backs up one character + position. Returns true if successful, false if nothing was + done. */ +static bool +backspace (char **pos, char line[]) +{ + if (*pos > line) + { + /* Back up cursor, overwrite character, back up + again. */ + printf ("\b \b"); + (*pos)--; + return true; + } + else + return false; +} -- 2.30.2