From 65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Sun, 24 May 2020 12:09:46 +0200 Subject: Big remodelling --- 02_exercise/process.c | 173 -------------------------------------------------- 1 file changed, 173 deletions(-) delete mode 100644 02_exercise/process.c (limited to '02_exercise/process.c') diff --git a/02_exercise/process.c b/02_exercise/process.c deleted file mode 100644 index 093b712..0000000 --- a/02_exercise/process.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include -#include -#include - -#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) { - char *part; - char **local_parts; - if (arrayInit(part) != 0 || arrayInit(local_parts) != 0) { - fprintf(stderr, "Failed to prepare new part / parts array whilst parsing line"); - return -1; - } - - for (size_t i = 0; line + i < end; ++i) { - char c = line[i]; - if (c == ' ' || c == '\0') { - if (arrayLen(part) == 0) - continue; - - arrayPush(part) = '\0'; - arrayPush(local_parts) = part; - - if (c == '\0') { - arrayPush(local_parts) = NULL; - break; - } else { - arrayInit(part); - } - } else { - arrayPush(part) = c; - } - } - - if (arrayLen(part) == 0) { - arrayRelease(part); - } else { - arrayPush(local_parts) = part; - } - - arrayPush(local_parts) = NULL; - p->argc = arrayLen(local_parts) - 1; - p->argv = local_parts; - - return 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}; - 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; - } - - 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 - for (size_t i = 0; i < p_len - 1; ++i) { - int fds[2]; - if (pipe(fds) != 0) { - perror("Failed to create pipe"); - return -1; - } - (*processes)[i].out_fd = fds[1]; - (*processes)[i + 1].in_fd = fds[0]; - } - - // setting all processes to non blocking when - if (strcmp(last->argv[last->argc - 1], "&") == 0) { - arrayPop(last->argv) = NULL; - last->argc = last->argc - 1; - last->argv[last->argc] = NULL; - - for (size_t i = 0; i < p_len; ++i) { - (*processes)[i].blocking = false; - } - } - return ret_code; -} - -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); - close(p.in_fd); - } - if (p.out_fd != 0) { - dup2(p.out_fd, 1); - close(p.out_fd); - } - execvp(p.argv[0], p.argv); - fprintf(stderr, "could not execute \"%s\"\n", p.argv[0]); - fflush(stderr); - exit(-1); - } - - if (p.pid < 0) { - fprintf(stderr, "no fork\n"); - exit(-2); - } - - if (p.in_fd != 0) { - close(p.in_fd); - } - - if (p.out_fd != 0) { - close(p.out_fd); - } - - 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); -} - -void free_processes(Process **pr) { - Process *processes = *pr; - while (!arrayIsEmpty(processes)) { - Process p = arrayPop(processes); - while (!arrayIsEmpty(p.argv)) { - char *tmp = arrayPop(p.argv); - if (tmp) - arrayRelease(tmp); - } - arrayRelease(p.argv); - } - arrayRelease(processes); - *pr = NULL; -} \ No newline at end of file -- cgit v1.2.3-54-g00ecf