PKUOS - Pintos
Pintos source browser for PKU Operating System 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
6static void read_line (char line[], size_t);
7static bool backspace (char **pos, char line[]);
8
9int
10main (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. */
51static void
52read_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. */
91static bool
92backspace (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}
static void wait(struct intq *q, struct thread **waiter)
int putchar(int c)
Writes C to the vga display and serial port.
Definition: console.c:163
int printf(const char *format,...)
Writes formatted output to the console.
Definition: stdio.c:79
bool chdir(const char *dir)
Project 4 only.
Definition: syscall.c:157
pid_t exec(const char *file)
Definition: syscall.c:79
int read(int fd, void *buffer, unsigned size)
Definition: syscall.c:115
int pid_t
Process identifier.
Definition: syscall.h:8
#define EXIT_SUCCESS
Typical return values from main() and arguments to exit().
Definition: syscall.h:19
#define PID_ERROR
Definition: syscall.h:9
static bool backspace(char **pos, char line[])
If *POS is past the beginning of LINE, backs up one character position.
Definition: shell.c:92
int main(void)
Definition: shell.c:10
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
#define STDIN_FILENO
Include lib/user/stdio.h or lib/kernel/stdio.h, as appropriate.
Definition: stdio.h:15
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
int strcmp(const char *a_, const char *b_)
Finds the first differing characters in strings A and B.
Definition: string.c:73