diff options
| author | manuel <manuel@mausz.at> | 2012-03-27 11:51:08 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2012-03-27 11:51:08 +0200 |
| commit | 4f670845ff9ab6c48bcb5f7bf4d4ef6dc3c3064b (patch) | |
| tree | 868c52e06f207b5ec8a3cc141f4b8b2bdfcc165c /examples/shell.c | |
| parent | eae0bd57f0a26314a94785061888d193d186944a (diff) | |
| download | progos-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.c | 104 |
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 | |||
| 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 | } | ||
