X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ftests%2Fuserprog%2Fshell.c;h=d31eb3a9a67c534199f0731165295e0a117b1b7e;hb=5780c9f434cca090f88463b7f0199d49b4ded288;hp=7b9570ac9d564df88b3aef8c71d14600b1a481e6;hpb=8a0c402207a9c4b0dc58f417ae3bc169c6f62f0f;p=pintos-anon diff --git a/src/tests/userprog/shell.c b/src/tests/userprog/shell.c index 7b9570a..d31eb3a 100644 --- a/src/tests/userprog/shell.c +++ b/src/tests/userprog/shell.c @@ -1,34 +1,99 @@ +#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. */ - for (cp = command; cp < command + sizeof command - 1; cp++) - { - read (STDIN_FILENO, cp, 1); - putchar (*cp); - if (*cp == '\n') - break; - } - *cp = '\0'; + read_line (command, sizeof command); /* Execute command. */ - if (cp > command) + if (!strcmp (command, "exit")) + break; + else if (command[0] == '\0') + { + /* Empty command. */ + } + else { pid_t pid = exec (command); if (pid != PID_ERROR) - join (pid); + printf ("\"%s\": exit code %d\n", command, wait (pid)); else printf ("exec failed\n"); } } + + 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; }