summaryrefslogtreecommitdiffstats
path: root/examples/shell.c
diff options
context:
space:
mode:
authormanuel <manuel@mausz.at>2012-03-27 11:51:08 +0200
committermanuel <manuel@mausz.at>2012-03-27 11:51:08 +0200
commit4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b (patch)
tree868c52e06f207b5ec8a3cc141f4b8b2bdfcc165c /examples/shell.c
parenteae0bd57f0a26314a94785061888d193d186944a (diff)
downloadprogos-4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b.tar.gz
progos-4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b.tar.bz2
progos-4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b.zip
reorganize file structure to match the upstream requirements
Diffstat (limited to 'examples/shell.c')
-rw-r--r--examples/shell.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/examples/shell.c b/examples/shell.c
new file mode 100644
index 0000000..93641b4
--- /dev/null
+++ b/examples/shell.c
@@ -0,0 +1,104 @@
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}