Get rid of unnecessary barrier. Improve comment.
[pintos-anon] / src / tests / userprog / shell.c
index 905e18b0275570ce2f678cc9d87b8f72ee84bc03..d31eb3a9a67c534199f0731165295e0a117b1b7e 100644 (file)
@@ -1,28 +1,99 @@
+#include <stdbool.h>
 #include <stdio.h>
+#include <string.h>
 #include <syscall.h>
 
+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_line (command, sizeof command);
+      
+      /* Execute command. */
+      if (!strcmp (command, "exit"))
+        break;
+      else if (command[0] == '\0') 
+        {
+          /* Empty command. */
+        }
+      else
+        {
+          pid_t pid = exec (command);
+          if (pid != PID_ERROR)
+            printf ("\"%s\": exit code %d\n", command, wait (pid));
+          else
+            printf ("exec failed\n");
+        }
+    }
+
+  printf ("Shell exiting.");
+  return 0;
+}
 
-      /* Read and echo command. */
-      for (cp = command; cp < command + sizeof command - 1; cp++)
+/* 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) 
         {
-          read (STDIN_FILENO, cp, 1);
-          putchar (*cp);
-          if (*cp == '\n')
-            break;
+        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;
         }
-      *cp = '\0';
-      
-      /* Execute command. */
-      if (cp > command) 
-        join (exec (command));
     }
 }
+
+/* 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;
+}