summaryrefslogtreecommitdiffstats
path: root/02_exercise/process.c
diff options
context:
space:
mode:
Diffstat (limited to '02_exercise/process.c')
-rw-r--r--02_exercise/process.c68
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)