diff options
Diffstat (limited to '02_exercise/shell.c')
-rw-r--r-- | 02_exercise/shell.c | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/02_exercise/shell.c b/02_exercise/shell.c index ea1b13f..35de455 100644 --- a/02_exercise/shell.c +++ b/02_exercise/shell.c @@ -3,14 +3,14 @@ #include <string.h> #include <unistd.h> #include <stdbool.h> +#include <wait.h> #include "array.h" #include "process.h" #include "prompt_utils.h" - int main(void) { - chdir("."); + setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); char const *const original_wd = get_current_dir_name(); @@ -24,6 +24,7 @@ int main(void) { printf("%s > ", prompt); if ((length = getline(&line, &cap, stdin)) < 0) { fprintf(stderr, "Failed to read from STDIN"); + fflush(stderr); exit(-1); } @@ -41,12 +42,20 @@ int main(void) { perror("Can't chain cd with other processes"); } - if (arrayLen(processes[0].argv) != 3) { - fprintf(stderr, "usage: cd <path>"); - goto clean; + int ret; + switch(arrayLen(processes[0].argv)) { + case 3: + ret = chdir(processes[0].argv[1]); + break; + case 2: + ret = chdir(original_wd); + break; + default: + fprintf(stderr, "usage: cd <path>\n"); + fflush(stderr); + ret = -1; } - int ret = chdir(processes[0].argv[1]); if (ret) printf("[%i] ", ret); @@ -56,6 +65,40 @@ int main(void) { free((void *)current_wd); } else if (strcmp(processes[0].argv[0], "exit") == 0) { done = true; + } else if (strcmp(processes[0].argv[0], "wait") == 0) { + bool error = false; + pid_t *pids; + arrayInit(pids); + size_t i = 1; + while (!error && processes[0].argv[i] != NULL) { + char *end; + pid_t tmp = strtol(processes[0].argv[i], &end, 10); + if (*end != '\0') { + fprintf(stderr, "Not a valid pid: %s", processes[0].argv[i]); + error = true; + break; + } + arrayPush(pids) = tmp; + ++i; + } + + if (!error) { + while (!arrayIsEmpty(pids)) { + int status; + pid_t current_pid = arrayPop(pids); + printf("Waiting for %ld...\n", (long) current_pid); + if (waitpid(current_pid, &status, WUNTRACED) < 0) { + perror("Could not wait on process"); + } else { + printf("[%i] TERMINATED\n", current_pid); + printf("[%i] EXIT STATUS: %i\n", current_pid, status); // TODO: exit status is wrong + } + // TODO: catch ctrl-c + } + } + + arrayRelease(pids); + } else { for (size_t i = 0; i < arrayLen(processes); ++i) { int ret = exec_command(processes[i]); @@ -65,7 +108,6 @@ int main(void) { } - clean: free((void *)line); line = NULL; cap = 0; |