CS318 - Pintos
Pintos source browser for JHU CS318 course
shell.c
Go to the documentation of this file.
1 #include <stdbool.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <syscall.h>
5 
6 static void read_line (char line[], size_t);
7 static bool backspace (char **pos, char line[]);
8 
9 int
10 main (void)
11 {
12  printf ("Shell starting...\n");
13  for (;;)
14  {
15  char command[80];
16 
17  /* Read command. */
18  printf ("--");
19  read_line (command, sizeof command);
20 
21  /* Execute command. */
22  if (!strcmp (command, "exit"))
23  break;
24  else if (!memcmp (command, "cd ", 3))
25  {
26  if (!chdir (command + 3))
27  printf ("\"%s\": chdir failed\n", command + 3);
28  }
29  else if (command[0] == '\0')
30  {
31  /* Empty command. */
32  }
33  else
34  {
35  pid_t pid = exec (command);
36  if (pid != PID_ERROR)
37  printf ("\"%s\": exit code %d\n", command, wait (pid));
38  else
39  printf ("exec failed\n");
40  }
41  }
42 
43  printf ("Shell exiting.");
44  return EXIT_SUCCESS;
45 }
46 
47 /** Reads a line of input from the user into LINE, which has room
48  for SIZE bytes. Handles backspace and Ctrl+U in the ways
49  expected by Unix users. On return, LINE will always be
50  null-terminated and will not end in a new-line character. */
51 static void
52 read_line (char line[], size_t size)
53 {
54  char *pos = line;
55  for (;;)
56  {
57  char c;
58  read (STDIN_FILENO, &c, 1);
59 
60  switch (c)
61  {
62  case '\r':
63  *pos = '\0';
64  putchar ('\n');
65  return;
66 
67  case '\b':
68  backspace (&pos, line);
69  break;
70 
71  case ('U' - 'A') + 1: /**< Ctrl+U. */
72  while (backspace (&pos, line))
73  continue;
74  break;
75 
76  default:
77  /* Add character to line. */
78  if (pos < line + size - 1)
79  {
80  putchar (c);
81  *pos++ = c;
82  }
83  break;
84  }
85  }
86 }
87 
88 /** If *POS is past the beginning of LINE, backs up one character
89  position. Returns true if successful, false if nothing was
90  done. */
91 static bool
92 backspace (char **pos, char line[])
93 {
94  if (*pos > line)
95  {
96  /* Back up cursor, overwrite character, back up
97  again. */
98  printf ("\b \b");
99  (*pos)--;
100  return true;
101  }
102  else
103  return false;
104 }
putchar
int putchar(int c)
Writes C to the vga display and serial port.
Definition: console.c:163
read_line
static void read_line(char line[], size_t)
Reads a line of input from the user into LINE, which has room for SIZE bytes.
Definition: shell.c:52
STDIN_FILENO
#define STDIN_FILENO
Include lib/user/stdio.h or lib/kernel/stdio.h, as appropriate.
Definition: stdio.h:15
string.h
backspace
static bool backspace(char **pos, char line[])
If *POS is past the beginning of LINE, backs up one character position.
Definition: shell.c:92
strcmp
int strcmp(const char *a_, const char *b_)
Finds the first differing characters in strings A and B.
Definition: string.c:73
exec
pid_t exec(const char *file)
Definition: syscall.c:79
stdbool.h
main
int main(void)
Definition: shell.c:10
printf
int printf(const char *format,...)
Writes formatted output to the console.
Definition: stdio.c:79
chdir
bool chdir(const char *dir)
Project 4 only.
Definition: syscall.c:157
memcmp
int memcmp(const void *a_, const void *b_, size_t size)
Find the first differing byte in the two blocks of SIZE bytes at A and B.
Definition: string.c:53
EXIT_SUCCESS
#define EXIT_SUCCESS
Typical return values from main() and arguments to exit().
Definition: syscall.h:19
wait
static void wait(struct intq *q, struct thread **waiter)
pid_t
int pid_t
Process identifier.
Definition: syscall.h:8
PID_ERROR
#define PID_ERROR
Definition: syscall.h:9
read
int read(int fd, void *buffer, unsigned size)
Definition: syscall.c:115