summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--02_exercise/process.c68
-rw-r--r--02_exercise/process.h25
-rw-r--r--02_exercise/process_test.c31
-rw-r--r--02_exercise/prog.c2
-rw-r--r--02_exercise/prompt_utils.c32
-rw-r--r--02_exercise/prompt_utils.h9
-rw-r--r--02_exercise/prompt_utils_test.c12
-rw-r--r--02_exercise/prompt_utils_test.h5
-rw-r--r--02_exercise/shell.c12
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: