diff options
-rw-r--r-- | 02_exercise/process.c | 68 | ||||
-rw-r--r-- | 02_exercise/process.h | 25 | ||||
-rw-r--r-- | 02_exercise/process_test.c | 31 | ||||
-rw-r--r-- | 02_exercise/prog.c | 2 | ||||
-rw-r--r-- | 02_exercise/prompt_utils.c | 32 | ||||
-rw-r--r-- | 02_exercise/prompt_utils.h | 9 | ||||
-rw-r--r-- | 02_exercise/prompt_utils_test.c | 12 | ||||
-rw-r--r-- | 02_exercise/prompt_utils_test.h | 5 | ||||
-rw-r--r-- | 02_exercise/shell.c | 12 |
9 files changed, 106 insertions, 90 deletions
diff --git a/02_exercise/process.c b/02_exercise/process.c index 08be0fd..093b712 100644 --- a/02_exercise/process.c +++ b/02_exercise/process.c @@ -1,19 +1,14 @@ -// -// Created by stefan on 21.05.20. -// - +#include <wait.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <wait.h> #include "array.h" #include "process.h" -// Given a substring of a line tries to parse out as much information as possible -int parse_command(char const *line, char const *end, process *p) { - +// given a substring of a line tries to parse out as much information as possible +int parse_command(char const *line, char const *end, Process *p) { char *part; char **local_parts; if (arrayInit(part) != 0 || arrayInit(local_parts) != 0) { @@ -26,8 +21,10 @@ int parse_command(char const *line, char const *end, process *p) { if (c == ' ' || c == '\0') { if (arrayLen(part) == 0) continue; + arrayPush(part) = '\0'; arrayPush(local_parts) = part; + if (c == '\0') { arrayPush(local_parts) = NULL; break; @@ -38,6 +35,7 @@ int parse_command(char const *line, char const *end, process *p) { arrayPush(part) = c; } } + if (arrayLen(part) == 0) { arrayRelease(part); } else { @@ -51,23 +49,26 @@ int parse_command(char const *line, char const *end, process *p) { return 0; } -int parse_line(char const *const line, process **processes) { - // Splits the line at | and then parses the commands - int ret_code = 0; +int parse_line(char const *const line, Process **processes) { + // splits the line at | and then parses the commands + int ret_code; if (arrayInit(*processes) != 0) { perror("Failed to initialize processes array"); return -1; } + bool done = false; char const *cursor = line; while (!done) { - process p = {.in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true}; + Process p = {.in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true}; char const *end = strchr(cursor, '|'); + if (end == NULL) { done = true; end = line + strlen(line); } + if ((ret_code = parse_command(cursor, end, &p)) != 0) { return ret_code; } @@ -75,11 +76,11 @@ int parse_line(char const *const line, process **processes) { arrayPush(*processes) = p; cursor = end + 1; } - size_t p_len = arrayLen(*processes); - process *last = *processes + (p_len - 1); - // Linking up all processes as we currently only have pipes for multiple commands + size_t p_len = arrayLen(*processes); + Process *last = *processes + (p_len - 1); + // linking up all processes as we currently only have pipes for multiple commands for (size_t i = 0; i < p_len - 1; ++i) { int fds[2]; if (pipe(fds) != 0) { @@ -89,9 +90,10 @@ int parse_line(char const *const line, process **processes) { (*processes)[i].out_fd = fds[1]; (*processes)[i + 1].in_fd = fds[0]; } - // Setting all processes to non blocking when + + // setting all processes to non blocking when if (strcmp(last->argv[last->argc - 1], "&") == 0) { - arrayPop(last->argv); + arrayPop(last->argv) = NULL; last->argc = last->argc - 1; last->argv[last->argc] = NULL; @@ -102,10 +104,15 @@ int parse_line(char const *const line, process **processes) { return ret_code; } -int exec_command(process p, unsigned timeout) { - timeout = timeout ^ timeout; +int exec_command(Process p) { int status; + if (!p.blocking) { + // if the process is to be put in the background let a fork handle it + if (fork() != 0) + return 0; + } + if ((p.pid = fork()) == 0) { if (p.in_fd != 0) { dup2(p.in_fd, 0); @@ -125,22 +132,35 @@ int exec_command(process p, unsigned timeout) { fprintf(stderr, "no fork\n"); exit(-2); } + if (p.in_fd != 0) { close(p.in_fd); } - if(p.out_fd != 0) { + + if (p.out_fd != 0) { close(p.out_fd); } - waitpid(p.pid, &status, 0); + if (!p.blocking) + printf("[%i]\n", p.pid); + + if (waitpid(p.pid, &status, 0) < 0) { + fprintf(stderr, "wait error'ed out\n"); + } + + if (!p.blocking) { + printf("[%i] TERMINATED\n", p.pid); + printf("[%i] EXIT STATUS: %i\n", p.pid, status); // TODO: exit status is wrong + exit(0); + } return WEXITSTATUS(status); } -int free_processes(process **pr) { - process *processes = *pr; +void free_processes(Process **pr) { + Process *processes = *pr; while (!arrayIsEmpty(processes)) { - process p = arrayPop(processes); + Process p = arrayPop(processes); while (!arrayIsEmpty(p.argv)) { char *tmp = arrayPop(p.argv); if (tmp) diff --git a/02_exercise/process.h b/02_exercise/process.h index f1cdfa0..3b7e833 100644 --- a/02_exercise/process.h +++ b/02_exercise/process.h @@ -1,7 +1,3 @@ -// -// Created by stefan on 21.05.20. -// - #ifndef SHELL_PROCESS_H #define SHELL_PROCESS_H #include <stdbool.h> @@ -14,17 +10,20 @@ typedef struct { int out_fd; int pid; bool blocking; -} process; - -//Parses the given line and creates an array of processes at *processes -// Expects tail -F file | grep panic & to mean that both processes should -// run in the background -int parse_line(char const *line, process ** processes); -// returns the return code of the executed program -int exec_command(process p, unsigned timeout); +} Process; -int free_processes(process ** processes); +/* + * Parses the given line and creates an array of processes at *processes + * Expects tail -F file | grep panic & to mean that both processes should + * run in the background + */ +int parse_line(char const *line, Process ** processes); +/* + * returns the return code of the executed program + */ +int exec_command(Process p); +void free_processes(Process ** processes); #endif // SHELL_PROCESS_H diff --git a/02_exercise/process_test.c b/02_exercise/process_test.c index dc3a291..a7b0b9c 100644 --- a/02_exercise/process_test.c +++ b/02_exercise/process_test.c @@ -1,15 +1,12 @@ -// -// Created by stefan on 21.05.20. -// -#include "process.h" -#include "array.h" #include <assert.h> #include <string.h> +#include "array.h" +#include "process.h" void test_simple_case() { - process * processes= NULL; - parse_line("cat my_txt ",&processes); + Process *processes = NULL; + parse_line("cat my_txt ", &processes); assert(arrayLen(processes) == 1); assert(arrayLen(processes[0].argv) == 3); assert(strcmp(processes[0].argv[0], "cat") == 0); @@ -17,9 +14,9 @@ void test_simple_case() { free_processes(&processes); } -void test_detatched() { - process * processes= NULL; - parse_line("cat my_txt &",&processes); +void test_detached() { + Process *processes = NULL; + parse_line("cat my_txt &", &processes); assert(arrayLen(processes) == 1); assert(arrayLen(processes[0].argv) == 3); assert(strcmp(processes[0].argv[0], "cat") == 0); @@ -30,8 +27,8 @@ void test_detatched() { void test_pipe() { - process * processes= NULL; - parse_line("echo my_txt | grep txt",&processes); + Process *processes = NULL; + parse_line("echo my_txt | grep txt", &processes); assert(arrayLen(processes) == 2); assert(arrayLen(processes[0].argv) == 3); assert(strcmp(processes[0].argv[0], "echo") == 0); @@ -45,20 +42,22 @@ void test_pipe() { } void test_ls(){ - process * processes= NULL; + Process *processes = NULL; parse_line("ls", &processes); assert(arrayLen(processes) == 1); - process p = processes[0]; + Process p = processes[0]; assert(arrayLen(p.argv)==2); assert(p.argc == 1); assert(strcmp(p.argv[0], "ls") == 0); assert(p.argc[p.argv] == NULL); free_processes(&processes); } + +/* int main() { test_ls(); test_simple_case(); - test_detatched(); + test_detached(); test_pipe(); return 0; -}
\ No newline at end of file +}*/ diff --git a/02_exercise/prog.c b/02_exercise/prog.c index 41c0545..efd2527 100644 --- a/02_exercise/prog.c +++ b/02_exercise/prog.c @@ -1,6 +1,6 @@ +#include <time.h> #include <stdio.h> #include <stdlib.h> -#include <time.h> #include <unistd.h> static unsigned int hash(const void* key, size_t size) { diff --git a/02_exercise/prompt_utils.c b/02_exercise/prompt_utils.c index 238f47c..168c088 100644 --- a/02_exercise/prompt_utils.c +++ b/02_exercise/prompt_utils.c @@ -1,13 +1,10 @@ -#include "prompt_utils.h" - -#include "array.h" -#include <errno.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -char const *relative_path(char const *const from_dir, char const *const to_dir) { +#include "array.h" +#include "prompt_utils.h" +char const *relative_path(char const *const from_dir, char const *const to_dir) { // easiest cases first { if (strcmp(from_dir, to_dir) == 0) { @@ -24,9 +21,10 @@ char const *relative_path(char const *const from_dir, char const *const to_dir) return return_value; } } - // Splitting path into pieces so we can do strcmp on each of them - size_t const *const from_dir_indeces = get_seperator_indeces(from_dir, '/'); - size_t const *const to_dir_indeces = get_seperator_indeces(to_dir, '/'); + + // splitting path into pieces so we can do strcmp on each of them + size_t const *const from_dir_indeces = get_separator_indices(from_dir, '/'); + size_t const *const to_dir_indeces = get_separator_indices(to_dir, '/'); size_t from_dir_len = arrayLen(from_dir_indeces); size_t to_dir_len = arrayLen(to_dir_indeces); @@ -50,7 +48,7 @@ char const *relative_path(char const *const from_dir, char const *const to_dir) size_t levels_up = from_dir_len - i - 1; char *return_value; if (levels_up == 0) { - // Equal dirs for whole length of path and not equal => subdir + // equal dirs for whole length of path and not equal => subdir size_t length = strlen(to_dir + common_position) + strlen("./") + 1; return_value = malloc(length * sizeof(char)); strcpy(return_value, "."); @@ -75,18 +73,18 @@ char const *relative_path(char const *const from_dir, char const *const to_dir) return return_value; } -size_t *get_seperator_indeces(char const *const text, char seperator) { - size_t *indeces; - arrayInit(indeces); +size_t *get_separator_indices(char const *const text, char seperator) { + size_t *indices; + arrayInit(indices); char const *current = text; if (strchr(current, seperator) == NULL) { - arrayRelease(indeces); + arrayRelease(indices); return NULL; } while ((current = strchr(current, seperator)) != NULL) { - arrayPush(indeces) = (size_t) (current - text); + arrayPush(indices) = (size_t) (current - text); ++current; } - arrayPush(indeces) = strlen(text); - return indeces; + arrayPush(indices) = strlen(text); + return indices; } diff --git a/02_exercise/prompt_utils.h b/02_exercise/prompt_utils.h index a3a9d9e..36d065d 100644 --- a/02_exercise/prompt_utils.h +++ b/02_exercise/prompt_utils.h @@ -1,11 +1,10 @@ #ifndef PROMPT_UTILS_H_INCLUDED #define PROMPT_UTILS_H_INCLUDED -#include <stddef.h> - -// Returns the relative path to get from the `from_dir` to the `to_dir` +// returns the relative path to get from the `from_dir` to the `to_dir` char const *relative_path(char const *from_dir, char const *to_dir); -// Returns the position of each occurence of the seperator -size_t *get_seperator_indeces(char const *text, char seperator); +// returns the position of each occurrence of the separator +size_t *get_separator_indices(char const *text, char separator); + #endif // PROMPT_UTILS_H_INCLUDED diff --git a/02_exercise/prompt_utils_test.c b/02_exercise/prompt_utils_test.c index 3819021..8bc29de 100644 --- a/02_exercise/prompt_utils_test.c +++ b/02_exercise/prompt_utils_test.c @@ -4,20 +4,20 @@ #include <stdio.h> #include <string.h> -void test_get_seperator_indeces() { +void test_get_separator_indices() { char const *const test_str = "/This/is/a/test"; - size_t const *const result = get_seperator_indeces(test_str, '/'); + size_t const *const result = get_separator_indices(test_str, '/'); for (size_t i = 0; i < arrayLen(result); i++) { printf("%ld : %s \n", result[i], test_str + result[i]); } } void test_paths(char const *const from, char const *const to, char const *const expected) { - size_t const *const result = get_seperator_indeces(from, '/'); + size_t const *const result = get_separator_indices(from, '/'); for (size_t i = 0; i < arrayLen(result); i++) { printf("%ld : %s \n", result[i], from + result[i]); } - size_t const *const result2 = get_seperator_indeces(to, '/'); + size_t const *const result2 = get_separator_indices(to, '/'); for (size_t i = 0; i < arrayLen(result2); i++) { printf("%ld : %s \n", result2[i], to + result2[i]); } @@ -36,8 +36,10 @@ void test_relative_path() { test_paths("/B/C", "/", "../.."); } +/* int main(void) { test_relative_path(); - test_get_seperator_indeces(); + test_get_separator_indices(); return 0; } +*/ diff --git a/02_exercise/prompt_utils_test.h b/02_exercise/prompt_utils_test.h index fbaabde..59717d0 100644 --- a/02_exercise/prompt_utils_test.h +++ b/02_exercise/prompt_utils_test.h @@ -1,6 +1,7 @@ #ifndef PROMPT_UTILS_TEST_H_INCLUDED #define PROMPT_UTILS_TEST_H_INCLUDED -void test_get_seperator_indeces(); + +void test_get_separator_indices(); void test_relative_path(); -#endif
\ No newline at end of file +#endif diff --git a/02_exercise/shell.c b/02_exercise/shell.c index eed8e64..f456465 100644 --- a/02_exercise/shell.c +++ b/02_exercise/shell.c @@ -1,17 +1,14 @@ -#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdbool.h> -#include <sys/wait.h> #include "array.h" #include "process.h" #include "prompt_utils.h" - int main(void) { chdir("."); setvbuf(stdout, NULL, _IONBF, 0); @@ -36,7 +33,7 @@ int main(void) { line[length - 1] = '\0'; // cut the line feed - process * processes = NULL; + Process * processes = NULL; parse_line(line, &processes); if (strcmp(processes[0].argv[0], "cd") == 0) { @@ -62,10 +59,11 @@ int main(void) { } else { int ret; for (size_t i = 0; i < arrayLen(processes); ++i) { - ret = exec_command(processes[i], 0); + ret = exec_command(processes[i]); + if (ret) + printf("[%i] ", ret); } - if (ret) - printf("[%i] ", ret); + } clean: |