summaryrefslogtreecommitdiffstats
path: root/02_exercise/process.c
diff options
context:
space:
mode:
authorStefan Zabka <zabkaste@hu-berlin.de>2020-05-24 12:09:46 +0200
committerStefan Zabka <zabkaste@hu-berlin.de>2020-05-24 12:09:46 +0200
commit65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a (patch)
tree60af69be16926ef0f24ad2a954d9205ce9277450 /02_exercise/process.c
parent3b7e61eab8ce5d230bc1b172942c1ab9459ed161 (diff)
downloadbetriebssysteme-65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a.tar.gz
betriebssysteme-65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a.zip
Big remodelling
Diffstat (limited to '02_exercise/process.c')
-rw-r--r--02_exercise/process.c173
1 files changed, 0 insertions, 173 deletions
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 <wait.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.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) {
- 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