summaryrefslogtreecommitdiffstats
path: root/02_exercise
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
parent3b7e61eab8ce5d230bc1b172942c1ab9459ed161 (diff)
downloadbetriebssysteme-65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a.tar.gz
betriebssysteme-65966ded0cc15c5966c6568cf0ff2f2bbe1fc29a.zip
Big remodelling
Diffstat (limited to '02_exercise')
-rw-r--r--02_exercise/.gitignore2
-rw-r--r--02_exercise/CMakeLists.txt57
-rw-r--r--02_exercise/Makefile32
-rw-r--r--02_exercise/array.c59
-rw-r--r--02_exercise/array.h142
-rw-r--r--02_exercise/beispiele/dup/Makefile18
-rw-r--r--02_exercise/beispiele/dup/dup.c51
-rw-r--r--02_exercise/beispiele/fork_example/Makefile18
-rw-r--r--02_exercise/beispiele/fork_example/fork.c36
-rw-r--r--02_exercise/beispiele/fork_signal/Makefile19
-rw-r--r--02_exercise/beispiele/fork_signal/fork.c39
-rw-r--r--02_exercise/beispiele/fork_signal/signal.c21
-rw-r--r--02_exercise/beispiele/pipe_bidirect/Makefile19
-rw-r--r--02_exercise/beispiele/pipe_bidirect/log.txt19
-rw-r--r--02_exercise/beispiele/pipe_bidirect/pingpong.c125
-rw-r--r--02_exercise/beispiele/pipe_example/Makefile18
-rw-r--r--02_exercise/beispiele/pipe_example/pipe.c60
-rw-r--r--02_exercise/process.c173
-rw-r--r--02_exercise/process.h29
-rw-r--r--02_exercise/process_test.c63
-rw-r--r--02_exercise/prog.c52
-rw-r--r--02_exercise/prompt_utils.c90
-rw-r--r--02_exercise/prompt_utils.h10
-rw-r--r--02_exercise/prompt_utils_test.c45
-rw-r--r--02_exercise/prompt_utils_test.h7
-rw-r--r--02_exercise/shell.c76
26 files changed, 0 insertions, 1280 deletions
diff --git a/02_exercise/.gitignore b/02_exercise/.gitignore
deleted file mode 100644
index 5aacf99..0000000
--- a/02_exercise/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-prog
-shell
diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt
deleted file mode 100644
index ca67d1a..0000000
--- a/02_exercise/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-cmake_minimum_required(VERSION 3.5)
-
-project(shell C)
-
-set(CMAKE_C_COMPILER gcc)
-set(CMAKE_C_STANDARD 11)
-set(CMAKE_C_STANDARD_REQUIRED True)
-
-add_executable(prog prog.c)
-add_executable(shell shell.c)
-target_link_libraries(shell PRIVATE array prompt_utils process)
-add_compile_definitions(_GNU_SOURCE)
-
-add_library(array array.c)
-
-add_library(prompt_utils prompt_utils.c)
-target_link_libraries(prompt_utils PRIVATE array)
-
-add_executable(prompt_utils_test prompt_utils_test.c)
-target_link_libraries(prompt_utils_test PRIVATE prompt_utils array)
-
-add_library(process process.c)
-target_link_libraries(process PRIVATE array)
-
-add_executable(process_test process_test.c)
-target_link_libraries(process_test PRIVATE process)
-
-
-
-set(CLANG_WARNINGS
- -Wall
- -Wextra # reasonable and standard
- -Wshadow # warn the user if a variable declaration shadows one from a
- # parent context
- -Wcast-align # warn for potential performance problem casts
- -Wunused # warn on anything being unused
- -Wpedantic # warn if non-standard C++ is used
- -Wconversion # warn on type conversions that may lose data
- -Wsign-conversion # warn on sign conversions
- -Wnull-dereference # warn if a null dereference is detected
- -Wdouble-promotion # warn if float is implicit promoted to double
- -Wformat=2 # warn on security issues around functions that format output
- # (ie printf)
- -Werror
- )
-set(GCC_WARNINGS
- ${CLANG_WARNINGS}
- -Wmisleading-indentation # warn if indentation implies blocks where blocks
- # do not exist
- -Wduplicated-cond # warn if if / else chain has duplicated conditions
- -Wduplicated-branches # warn if if / else branches have duplicated code
- -Wlogical-op # warn about logical operations being used where bitwise were
- # probably wanted
- )
-set(PROJECT_WARNINGS ${GCC_WARNINGS})
-target_compile_options(shell INTERFACE ${PROJECT_WARNINGS})
-target_compile_options(prompt_utils INTERFACE ${PROJECT_WARNINGS}) \ No newline at end of file
diff --git a/02_exercise/Makefile b/02_exercise/Makefile
deleted file mode 100644
index 5d1b360..0000000
--- a/02_exercise/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-.PHONY: all run pack clean
-TAR = shell prog
-SRC = $(wildcard *.c)
-OBJ = $(SRC:%.c=%.o)
-PCK = lab-2.zip
-
-CFLAGS = -std=gnu11 -c -g -Os -Wall -Werror -MMD -MP -D=_GNU_SOURCE
-
-DEP = $(OBJ:%.o=%.d)
--include $(DEP)
-
-%.o: %.c
- $(CC) $(CFLAGS) $< -o $@
-
-all: $(TAR)
-
-prog: prog.o
- $(CC) -o $@ $^
-
-shell: $(filter-out prog.o,$(OBJ))
- $(CC) -o $@ $^
-
-run: all
- ./shell
-
-pack:
- zip $(PCK) $(SRC) $(wildcard *.h) Makefile
-
-clean:
- $(RM) $(RMFILES) $(TAR) $(OBJ) $(DEP) $(PCK)
diff --git a/02_exercise/array.c b/02_exercise/array.c
deleted file mode 100644
index 4f08366..0000000
--- a/02_exercise/array.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/***************************************************************************//**
- * @file array.c
- * @author Dorian Weber
- * @brief Implementation des generalisierten Arrays.
- ******************************************************************************/
-
-#include "array.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-/* ********************************************************* public functions */
-
-/* (die runden Klammern um einige Funktionsnamen sind notwendig, da Makros
- * gleichen Namens existieren und der Präprozessor diese expandieren würde) */
-
-void* (arrayInit)(size_t capacity, size_t size) {
- ArrayHdr *hdr = malloc(sizeof(*hdr) + size*capacity);
-
- if (hdr == NULL)
- return NULL;
-
- hdr->len = 0;
- hdr->cap = capacity;
-
- return hdr + 1;
-}
-
-void arrayRelease(void* self) {
- free(((ArrayHdr*) self) - 1);
-}
-
-void* (arrayPush)(void* self, size_t size) {
- ArrayHdr *hdr = ((ArrayHdr*) self) - 1;
-
- if (hdr->len == hdr->cap) {
- hdr->cap *= 2;
- hdr = realloc(hdr, sizeof(*hdr) + size*hdr->cap);
-
- if (hdr == NULL) {
- fputs("program ran out of heap memory\n", stderr);
- exit(-1);
- }
- }
-
- ++hdr->len;
- return hdr + 1;
-}
-
-void (arrayPop)(void* self) {
- ArrayHdr *hdr = ((ArrayHdr*) self) - 1;
- assert(hdr->len > 0);
- --hdr->len;
-}
-
-/* Symbol für die Inline-Funktionen erzeugen und aus diesem Modul exportieren */
-extern void arrayClear(void* self);
-extern int arrayIsEmpty(const void* self);
-extern size_t arrayLen(const void* self);
diff --git a/02_exercise/array.h b/02_exercise/array.h
deleted file mode 100644
index 78d21c9..0000000
--- a/02_exercise/array.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/***************************************************************************//**
- * @file array.h
- * @author Dorian Weber
- * @brief Generischer Array-Typ.
- *
- * @details
- * Diese Datei enthält die Schnittstelle eines generischen Array-Typs. Um den
- * Element-Typ des Arrays festzulegen, deklariert man eine Variable als Zeiger
- * auf den Element-Typ. Diese kann danach initialisiert und so benutzt werden,
- * als wäre sie ein Zeiger auf ein Array variabler Länge.
- *
- * Hier ist ein Nutzungsbeispiel:
- * @code
- * int *array;
- *
- * arrayInit(array);
- * arrayPush(array) = 1;
- * arrayPush(array) = 2;
- * arrayPush(array) = 3;
- *
- * while (!arrayIsEmpty(array))
- * printf("%i\n", arrayPop(array));
- *
- * arrayRelease(array);
- * @endcode
- *
- * Viele der genutzten Funktionen sind in Form von Makros implementiert, die die
- * Variable, die den Zeiger auf das Array hält, aktualisieren, obwohl es so
- * aussieht, als würde sich dieser Wert niemals ändern. Das macht es riskant
- * mehr als einen Zeiger auf das Array zu halten, da jede Vergrößerung des
- * Arrays alle Zeiger auf und in das Array potentiell invalidiert. Obwohl diese
- * Fehlerquelle subtil und äußerst schwer diagnostizierbar ist - es ist eine
- * extrem einfache Abstraktion - führt diese Datenstruktur meiner Meinung nach
- * trotzdem zu einem massiven Produktivitätsgewinn; man sollte sich nur in etwa
- * im Klaren über die unterliegende Implementation sein, um genau die Untermenge
- * von Programmiertechniken auszuwählen, die korrekt funktioniert.
- ******************************************************************************/
-
-#ifndef ARRAY_H_INCLUDED
-#define ARRAY_H_INCLUDED
-
-/* *** includes ************************************************************* */
-
-#include <stddef.h>
-
-/* *** structures *********************************************************** */
-
-/**@brief Arrayheader.
- *
- * Diese Struktur wird jedem Array im Speicher vorangestellt und beinhaltet
- * Informationen über Kapazität und aktuelle Auslastung des Arrays. Die
- * Arrayelemente schließen sich dieser Struktur unmittelbar an, so dass der
- * Nutzer von dieser versteckten Information nichts bemerkt.
- */
-typedef struct ArrayHdr
-{
- size_t len; /**<@brief Anzahl der Array-Elemente. */
- size_t cap; /**<@brief Kapazität des reservierten Speichers. */
-} ArrayHdr;
-
-/* *** interface ************************************************************ */
-
-/**@internal
- * @brief Initialisiert und gibt einen Zeiger auf den Start des Arrays zurück.
- * @param capacity initiale Kapazität
- * @param size Größe der Arrayelemente
- * @return ein Zeiger auf den Start des Arrays, falls erfolgreich,\n
- * \c NULL im Falle eines Speicherfehlers
- */
-extern void* arrayInit(size_t capacity, size_t size);
-
-/**@brief Initialisiert ein neues Array.
- * @param self das Array
- * @return 0, falls keine Fehler bei der Initialisierung aufgetreten sind,\n
- * -1 ansonsten
- */
-#define arrayInit(self) \
- ((self = arrayInit(8, sizeof((self)[0]))) == NULL ? -1 : 0)
-
-/**@brief Gibt das Array und alle assoziierten Strukturen frei.
- * @param self das Array
- */
-extern void arrayRelease(void* self);
-
-/**@internal
- * @brief Reserviert Platz für einen neuen Wert im Array.
- * @param self das Array
- * @param size Größe der Arrayelemente
- * @return der neue Zeiger auf den Start des Arrays
- */
-extern void* arrayPush(void* self, size_t size);
-
-/**@brief Legt einen Wert auf das Array.
- * @param self das Array
- */
-#define arrayPush(self) \
- (self = arrayPush(self, sizeof((self)[0])), (self)+arrayLen(self)-1)[0]
-
-/**@brief Entfernt das oberste Element des Arrays.
- * @param self das Array
- */
-extern void arrayPop(void* self);
-
-/**@brief Entfernt und liefert das oberste Element des Arrays.
- * @param self das Array
- * @return das oberste Element von \p self
- */
-#define arrayPop(self) \
- (arrayPop(self), (self)+arrayLen(self))[0]
-
-/**@brief Gibt das oberste Element des Arrays zurück.
- * @param self das Array
- * @return das oberste Element von \p self
- */
-#define arrayTop(self) \
- (self)[arrayLen(self) - 1]
-
-/**@brief Setzt die Länge des Arrays auf 0 zurück.
-* @param self das Array
-*/
-inline void arrayClear(void* self) {
- ((ArrayHdr*) self)[-1].len = 0;
-}
-
-/**@brief Gibt zurück, ob das Array leer ist.
- * @param self das Array
- * @return 0, falls nicht leer\n
- 1, falls leer
- */
-inline int arrayIsEmpty(const void* self) {
- return ((ArrayHdr*) self)[-1].len == 0;
-}
-
-/**@brief Gibt die Anzahl der Array-Elemente zurück.
- * @param self das Array
- * @return Anzahl der Elemente des Arrays
- */
-inline size_t arrayLen(const void* self) {
- return ((ArrayHdr*) self)[-1].len;
-}
-
-#endif /* ARRAY_H_INCLUDED */
diff --git a/02_exercise/beispiele/dup/Makefile b/02_exercise/beispiele/dup/Makefile
deleted file mode 100644
index 0f73ac4..0000000
--- a/02_exercise/beispiele/dup/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-
-CFLAGS = -c -Os -Wall -Werror
-
-%.o: %.c
- $(CC) $(CFLAGS) $^ -o $@
-
-%: %.o
- $(CC) -o $@ $^
-
-all: dup
-
-run: all
- ./dup
-
-clean:
- $(RM) $(RMFILES) dup
diff --git a/02_exercise/beispiele/dup/dup.c b/02_exercise/beispiele/dup/dup.c
deleted file mode 100644
index ea3c5a6..0000000
--- a/02_exercise/beispiele/dup/dup.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* https://www.youtube.com/watch?v=gaXigSu72A4 */
-static inline void die(const char* msg) {
- perror(msg);
- exit(EXIT_FAILURE);
-}
-
-int main(int argc, char **argv) {
- int pdes[2];
- pid_t child;
-
- if (pipe(pdes) < 0)
- die("pipe()");
-
- if ((child = fork()) < 0)
- die("fork()");
-
- if (child == 0) {
- /* child process */
- close(pdes[0]);
- close(1); /* close stdout */
-
- if (dup(pdes[1]) < 0)
- die("dup()");
-
- /* now stdout and pdes[1] are equivalent (dup returns lowest free descriptor) */
- if (execlp("cat", "cat", "/etc/passwd", NULL) < 0)
- die("execlp()");
-
- exit(EXIT_SUCCESS);
- }
- else {
- /* parent process */
- close(0); /* close stdin */
- close(pdes[1]);
-
- if (dup(pdes[0]) < 0)
- die("dup()");
-
- /* now stdin and pdes[0] are equivalent (dup returns lowest free descriptor) */
- if (execlp("wc", "wc", "-l", NULL) < 0)
- die("execlp()");
-
- exit(EXIT_SUCCESS);
- }
-
- return 0;
-}
diff --git a/02_exercise/beispiele/fork_example/Makefile b/02_exercise/beispiele/fork_example/Makefile
deleted file mode 100644
index 8f69ed9..0000000
--- a/02_exercise/beispiele/fork_example/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-
-CFLAGS = -c -Os -Wall -Werror
-
-%.o: %.c
- $(CC) $(CFLAGS) $^ -o $@
-
-%: %.o
- $(CC) -o $@ $^
-
-all: fork
-
-run: all
- ./fork
-
-clean:
- $(RM) $(RMFILES) fork
diff --git a/02_exercise/beispiele/fork_example/fork.c b/02_exercise/beispiele/fork_example/fork.c
deleted file mode 100644
index 7377b0f..0000000
--- a/02_exercise/beispiele/fork_example/fork.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/wait.h>
-
-int main(void) {
- pid_t proc_id;
- int status = 0;
-
- proc_id = fork();
-
- if (proc_id < 0) {
- fprintf(stderr, "fork error\n");
- fflush(stderr);
- return EXIT_FAILURE;
- }
-
- if (proc_id == 0) {
- /* child process */
- printf("[child] process id: %d\n", (int) getpid());
-
- char* args[] = {"sleep", "1", NULL};
- execvp(args[0], args);
- exit(-1);
- }
- else {
- /* parent */
- printf("[parent] process id: %d\n", (int) getpid());
- pid_t child_id = wait(&status);
-
- printf("[parent] child %d returned: %d\n",
- child_id, WEXITSTATUS(status));
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/02_exercise/beispiele/fork_signal/Makefile b/02_exercise/beispiele/fork_signal/Makefile
deleted file mode 100644
index 499b8cb..0000000
--- a/02_exercise/beispiele/fork_signal/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-
-CFLAGS = -c -O0
-
-%.o: %.c
- $(CC) $(CFLAGS) $^ -o $@
-
-%: %.o
- $(CC) -o $@ $^
-
-all: fork signal
-
-run: all
- ./fork 10
- ./signal
-
-clean:
- $(RM) $(RMFILES) fork signal
diff --git a/02_exercise/beispiele/fork_signal/fork.c b/02_exercise/beispiele/fork_signal/fork.c
deleted file mode 100644
index b144577..0000000
--- a/02_exercise/beispiele/fork_signal/fork.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-int main(int argc, const char* argv[]) {
- pid_t pid;
- int h;
- int count;
-
- if (argc < 2) {
- printf("Usage: ./fork process#\n");
- return 0;
- }
-
- count = atoi(argv[1]) - 1;
- printf("Process#: %d\n", count + 1);
- printf("Parent started\n");
-
- pid = 1;
- for (h = 0; h < count; ++h) {
- if ((pid = fork()) < 0)
- printf("fork error\n");
- else if (pid == 0) {
- printf("Child %d started\n", h);
- sleep(1);
- printf("Child %d finished\n", h);
- exit(0);
- }
- }
-
- printf("Parent waiting\n");
- for (h = 0; h < count; ++h) {
- wait(NULL);
- }
- printf("Parent finished\n");
- return EXIT_SUCCESS;
-}
diff --git a/02_exercise/beispiele/fork_signal/signal.c b/02_exercise/beispiele/fork_signal/signal.c
deleted file mode 100644
index 500d2e1..0000000
--- a/02_exercise/beispiele/fork_signal/signal.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <signal.h>
-
-void sig_handler(int signo) {
- const char msg[] = "Speicherzugriffsfehler!\n";
- write(2, msg, sizeof(msg) - 1);
- exit(-1);
-}
-
-int main(void) {
- if (signal(SIGSEGV, sig_handler) == SIG_ERR) {
- perror("signal");
- exit(-1);
- }
-
- int array[1] = {0};
- array[1000000] = 3;
- return 0;
-}
diff --git a/02_exercise/beispiele/pipe_bidirect/Makefile b/02_exercise/beispiele/pipe_bidirect/Makefile
deleted file mode 100644
index 361ac97..0000000
--- a/02_exercise/beispiele/pipe_bidirect/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-
-CFLAGS = -c -Os -Wall -Werror
-
-%.o: %.c
- $(CC) $(CFLAGS) $^ -o $@
-
-%: %.o
- $(CC) -o $@ $^
-
-all: pingpong
-
-run: all
- @echo "writing into log.txt; stop execution with CTRL+C"
- ./pingpong
-
-clean:
- $(RM) $(RMFILES) pingpong
diff --git a/02_exercise/beispiele/pipe_bidirect/log.txt b/02_exercise/beispiele/pipe_bidirect/log.txt
deleted file mode 100644
index c59b0bb..0000000
--- a/02_exercise/beispiele/pipe_bidirect/log.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-[3225581]: ping
-[3225580]: pong
-Programmabbruch durch Nutzer
diff --git a/02_exercise/beispiele/pipe_bidirect/pingpong.c b/02_exercise/beispiele/pipe_bidirect/pingpong.c
deleted file mode 100644
index f38394f..0000000
--- a/02_exercise/beispiele/pipe_bidirect/pingpong.c
+++ /dev/null
@@ -1,125 +0,0 @@
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static int split(int fd[2]);
-static int redir(int fd, const char *file);
-static void sig_handler(int sig);
-
-static int parent;
-
-int main(void) {
- ssize_t bytes;
- char buf[256];
- int fd[2];
-
- // disable buffering for stdout
- setvbuf(stdout, NULL, _IONBF, 0);
-
- // redirect stdout to write into a file
- if (redir(1, "log.txt") < 0) {
- perror("redir()");
- exit(-1);
- }
-
- // install the signal handler for Ctrl+C
- if (signal(SIGINT, sig_handler) == SIG_ERR) {
- perror("signal()");
- exit(-1);
- }
-
- // split processes and assign file descriptors for communication
- switch (split(fd)) {
- case -1: // error
- exit(-1);
-
- case 0: // child
- while ((bytes = read(fd[0], buf, sizeof(buf))) > 0) {
- printf("[%u]: %s\n", getpid(), buf);
- sleep(1);
- write(fd[1], "pong", 5);
- }
- break;
-
- case 1: // parent
- parent = 1;
- write(fd[1], "ping", 5);
- while ((bytes = read(fd[0], buf, sizeof(buf))) > 0) {
- printf("[%u]: %s\n", getpid(), buf);
- sleep(1);
- write(fd[1], "ping", 5);
- }
- break;
- }
-
- // close the file descriptors
- close(fd[0]);
- close(fd[1]);
-
- return 0;
-}
-
-int split(int fd[2]) {
- int pfd[2][2];
-
- if (pipe(pfd[0]) < 0) {
- perror("pipe()");
- goto err_pipe1;
- }
-
- if (pipe(pfd[1]) < 0) {
- perror("pipe()");
- goto err_pipe2;
- }
-
- switch (fork()) {
- case -1:
- perror("fork()");
- goto err_fork;
-
- case 0: // child process
- close(pfd[0][1]); // close write for child
- close(pfd[1][0]); // close read for parent
- fd[0] = pfd[0][0]; // keep read for child
- fd[1] = pfd[1][1]; // keep write for parent
- return 0;
-
- default: // parent process
- close(pfd[1][1]); // close write for parent
- close(pfd[0][0]); // close read for child
- fd[0] = pfd[1][0]; // keep read for parent
- fd[1] = pfd[0][1]; // keep write for child
- return 1;
- }
-
-err_fork:
- close(pfd[1][0]);
- close(pfd[1][1]);
-err_pipe2:
- close(pfd[0][0]);
- close(pfd[0][1]);
-err_pipe1:
- return -1;
-}
-
-int redir(int fd, const char *file) {
- int fd2 = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-
- if (fd2 < 0)
- return -1;
-
- dup2(fd2, fd);
- close(fd2);
-
- return 0;
-}
-
-void sig_handler(int sig) {
- if (parent) {
- const char msg[] = "Programmabbruch durch Nutzer\n";
- write(1, msg, sizeof(msg) - 1);
- }
- exit(0);
-}
diff --git a/02_exercise/beispiele/pipe_example/Makefile b/02_exercise/beispiele/pipe_example/Makefile
deleted file mode 100644
index d69473e..0000000
--- a/02_exercise/beispiele/pipe_example/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/make
-.SUFFIXES:
-
-CFLAGS = -c -Os -Wall -Werror
-
-%.o: %.c
- $(CC) $(CFLAGS) $^ -o $@
-
-%: %.o
- $(CC) -o $@ $^
-
-all: pipe
-
-run: all
- ./pipe
-
-clean:
- $(RM) $(RMFILES) pipe
diff --git a/02_exercise/beispiele/pipe_example/pipe.c b/02_exercise/beispiele/pipe_example/pipe.c
deleted file mode 100644
index 422e4d5..0000000
--- a/02_exercise/beispiele/pipe_example/pipe.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define BUF_SIZE 32
-
-int pipe_fds[2];
-
-void term(const char *msg) {
- if (msg) {
- fprintf(stderr, "Error: %s\n", msg);
- fflush(stderr);
- }
-
- int close_fail = 0;
- int ret = close(pipe_fds[0]);
-
- if (ret < 0) {
- fprintf(stderr, "Error: Couldn't close reading end of pipe\n");
- fflush(stderr);
- close_fail = 1;
- }
-
- ret = close(pipe_fds[1]);
-
- if (ret < 0) {
- fprintf(stderr, "Error: Couldn't close writing end of pipe\n");
- fflush(stderr);
- close_fail = 1;
- }
-
- exit((msg || close_fail) ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
-int main(void) {
- int ret = pipe(pipe_fds);
-
- if (ret < 0)
- term("Couldn't create pipe");
-
- char out_buf[] = "hello";
- ret = write(pipe_fds[1], out_buf, strlen(out_buf) + 1);
-
- if (ret < 0)
- term("Couldn't write to pipe");
-
- printf("send msg: %s\n", out_buf);
-
- char in_buf[BUF_SIZE];
- memset(in_buf, 0, BUF_SIZE);
-
- ret = read(pipe_fds[0], in_buf, BUF_SIZE - 1);
-
- if (ret < 0)
- term("Couldn't read from pipe");
-
- printf("recv msg: %s\n", in_buf);
- return 0;
-}
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
diff --git a/02_exercise/process.h b/02_exercise/process.h
deleted file mode 100644
index 3b7e833..0000000
--- a/02_exercise/process.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef SHELL_PROCESS_H
-#define SHELL_PROCESS_H
-#include <stdbool.h>
-#include <stddef.h>
-
-typedef struct {
- char **argv;
- size_t argc;
- int in_fd;
- 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);
-
-void free_processes(Process ** processes);
-
-#endif // SHELL_PROCESS_H
diff --git a/02_exercise/process_test.c b/02_exercise/process_test.c
deleted file mode 100644
index a7b0b9c..0000000
--- a/02_exercise/process_test.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#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);
- assert(arrayLen(processes) == 1);
- assert(arrayLen(processes[0].argv) == 3);
- assert(strcmp(processes[0].argv[0], "cat") == 0);
- assert(strcmp(processes[0].argv[1], "my_txt") == 0);
- free_processes(&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);
- assert(strcmp(processes[0].argv[1], "my_txt") == 0);
- assert(processes[0].blocking == false);
- free_processes(&processes);
-}
-
-
-void test_pipe() {
- 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);
- assert(strcmp(processes[0].argv[1], "my_txt") == 0);
- assert(processes[0].out_fd != 0);
- assert(arrayLen(processes[1].argv) == 3);
- assert(strcmp(processes[1].argv[0], "grep") == 0);
- assert(strcmp(processes[1].argv[1], "txt") == 0);
- assert(processes[1].in_fd != 0);
- free_processes(&processes);
-}
-
-void test_ls(){
- Process *processes = NULL;
- parse_line("ls", &processes);
- assert(arrayLen(processes) == 1);
- 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_detached();
- test_pipe();
- return 0;
-}*/
diff --git a/02_exercise/prog.c b/02_exercise/prog.c
deleted file mode 100644
index efd2527..0000000
--- a/02_exercise/prog.c
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-static unsigned int hash(const void* key, size_t size) {
- const char* ptr = key;
- unsigned int hval;
-
- for (hval = 0x811c9dc5u; size --> 0; ++ptr) {
- hval ^= *ptr;
- hval *= 0x1000193u;
- }
-
- return hval;
-}
-
-static inline int roll(int sides) {
- return rand() / (RAND_MAX + 1.0) * sides;
-}
-
-int main(int argc, const char* argv[]) {
- int rc, delay;
- time_t now = time(0);
-
- /* initialize the random number generator */
- srand(hash(&now, sizeof(now)));
-
- /* determine exit code and time delay */
- switch (argc) {
- default:
- delay = atoi(argv[1]);
- rc = atoi(argv[2]);
- break;
-
- case 2:
- delay = atoi(argv[1]);
- rc = roll(2) - 1;
- break;
-
- case 1:
- delay = roll(10);
- rc = roll(2) - 1;
- break;
- }
-
- printf("Delay: %ds, Exit Code: %d\n", delay, rc);
- fflush(stdout);
- sleep(delay);
-
- return rc;
-}
diff --git a/02_exercise/prompt_utils.c b/02_exercise/prompt_utils.c
deleted file mode 100644
index 168c088..0000000
--- a/02_exercise/prompt_utils.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#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) {
- char *return_value = malloc(2);
- strcpy(return_value, ".");
- return return_value;
- }
- }
- {
- if (strcmp("/", from_dir) == 0) {
- char *return_value = malloc(strlen(to_dir) + 2);
- return_value[0] = '.';
- memcpy(return_value + 1, to_dir, strlen(to_dir) + 1);
- return return_value;
- }
- }
-
- // 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);
-
- // finding the longest common substring
- size_t array_len = from_dir_len < to_dir_len ? from_dir_len : to_dir_len;
- size_t i = 0;
- size_t common_position = 0;
- for (; i < array_len - 1; ++i) {
- if (from_dir_indeces[i + 1] != to_dir_indeces[i + 1]) {
- break;
- }
- size_t index = from_dir_indeces[i];
- size_t count = from_dir_indeces[i + 1] - from_dir_indeces[i];
- if (strncmp(from_dir + index, to_dir + index, count) != 0) {
- break;
- }
- common_position = from_dir_indeces[i + 1];
- }
-
- 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
- size_t length = strlen(to_dir + common_position) + strlen("./") + 1;
- return_value = malloc(length * sizeof(char));
- strcpy(return_value, ".");
- strcat(return_value, to_dir + common_position);
- } else {
- char const *const go_up = "/..";
- size_t length = strlen(to_dir + common_position) + strlen("..") +
- strlen(go_up) * (levels_up - 1) + 1;
- return_value = malloc(length * sizeof(char));
- strcpy(return_value, "..");
- for (size_t j = 0; j < levels_up - 1; ++j) {
- strcat(return_value, go_up);
- }
- if (strcmp("/", to_dir) != 0) {
- strcat(return_value, to_dir + common_position);
- }
- }
-
- arrayRelease((void *)from_dir_indeces);
- arrayRelease((void *)to_dir_indeces);
-
- return return_value;
-}
-
-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(indices);
- return NULL;
- }
- while ((current = strchr(current, seperator)) != NULL) {
- arrayPush(indices) = (size_t) (current - text);
- ++current;
- }
- arrayPush(indices) = strlen(text);
- return indices;
-}
diff --git a/02_exercise/prompt_utils.h b/02_exercise/prompt_utils.h
deleted file mode 100644
index 36d065d..0000000
--- a/02_exercise/prompt_utils.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef PROMPT_UTILS_H_INCLUDED
-#define PROMPT_UTILS_H_INCLUDED
-
-// 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 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
deleted file mode 100644
index 8bc29de..0000000
--- a/02_exercise/prompt_utils_test.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "array.h"
-#include "prompt_utils.h"
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-void test_get_separator_indices() {
- char const *const test_str = "/This/is/a/test";
- 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_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_separator_indices(to, '/');
- for (size_t i = 0; i < arrayLen(result2); i++) {
- printf("%ld : %s \n", result2[i], to + result2[i]);
- }
- char const *const path = relative_path(from, to);
- printf("The relative path of %s to %s is %s \n", from, to, path);
-
- assert(strcmp(path, expected) == 0);
-}
-void test_relative_path() {
- test_paths("/Test", "/Test/a", "./a");
- test_paths("/abc/def/ghi", "/abc/def/ghi", ".");
- test_paths("/Test", "/Test/a/asd", "./a/asd");
- test_paths("/Test/b/c", "/Test/b", "..");
- test_paths("/", "/Test/a/asd", "./Test/a/asd");
- test_paths("/Test/c", "/Test/b", "../b");
- test_paths("/B/C", "/", "../..");
-}
-
-/*
-int main(void) {
- test_relative_path();
- test_get_separator_indices();
- return 0;
-}
-*/
diff --git a/02_exercise/prompt_utils_test.h b/02_exercise/prompt_utils_test.h
deleted file mode 100644
index 59717d0..0000000
--- a/02_exercise/prompt_utils_test.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef PROMPT_UTILS_TEST_H_INCLUDED
-#define PROMPT_UTILS_TEST_H_INCLUDED
-
-void test_get_separator_indices();
-void test_relative_path();
-
-#endif
diff --git a/02_exercise/shell.c b/02_exercise/shell.c
deleted file mode 100644
index f456465..0000000
--- a/02_exercise/shell.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdbool.h>
-
-#include "array.h"
-#include "process.h"
-#include "prompt_utils.h"
-
-
-int main(void) {
- chdir(".");
- setvbuf(stdout, NULL, _IONBF, 0);
-
- char const *const original_wd = get_current_dir_name();
- char const *prompt = relative_path(original_wd, original_wd);
- bool done = false;
- while (!done) {
- char *line = NULL;
- size_t cap = 0;
- __ssize_t length = 0;
-
- printf("%s > ", prompt);
- if ((length = getline(&line, &cap, stdin)) < 0) {
- fprintf(stderr, "Failed to read from STDIN");
- exit(-1);
- }
-
- if (strspn(line, " \n\t") == strlen(line)) {
- continue;
- }
-
- line[length - 1] = '\0'; // cut the line feed
-
- Process * processes = NULL;
- parse_line(line, &processes);
-
- if (strcmp(processes[0].argv[0], "cd") == 0) {
-
- if(arrayLen(processes) != 1) {
- perror("Can't chain cd with other processes");
- }
- if (arrayLen(processes[0].argv) != 3) {
- fprintf(stderr, "usage: cd <path>");
- goto clean;
- }
-
- int ret = chdir(processes[0].argv[1]);
- if (ret)
- printf("[%i] ", ret);
-
- free((void *)prompt);
- char const *current_wd = get_current_dir_name();
- prompt = relative_path(original_wd, current_wd);
- free((void *)current_wd);
- } else if (strcmp(processes[0].argv[0], "exit") == 0) {
- done = true;
- } else {
- int ret;
- for (size_t i = 0; i < arrayLen(processes); ++i) {
- ret = exec_command(processes[i]);
- if (ret)
- printf("[%i] ", ret);
- }
-
- }
-
- clean:
- free((void *)line);
- free_processes(&processes);
- }
-
- free((void *)original_wd);
- free((void *)prompt);
-}