diff options
Diffstat (limited to '02_exercise/process.c')
-rw-r--r-- | 02_exercise/process.c | 68 |
1 files changed, 44 insertions, 24 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) |