summary refs log tree commit diff
diff options
context:
space:
mode:
authorSingustromo <singustromo@disroot.org>2024-05-18 11:34:29 +0200
committerSingustromo <singustromo@disroot.org>2024-05-18 11:34:29 +0200
commit66c0ffd70e623ef63453d5c769e35cef381fcca1 (patch)
tree9a27dd4c3c9a4e39f4d9acf48c014f5658b163a5
downloadoperating-systems_3_clash-66c0ffd70e623ef63453d5c769e35cef381fcca1.tar.gz
operating-systems_3_clash-66c0ffd70e623ef63453d5c769e35cef381fcca1.zip
initial commit
-rw-r--r--.gitignore4
-rw-r--r--Makefile34
-rw-r--r--aufgabe.pdfbin0 -> 97763 bytes
-rwxr-xr-xref/clash.bsteambin0 -> 14648 bytes
-rw-r--r--ref/plist.o.bsteambin0 -> 2496 bytes
-rw-r--r--src/plist.c98
-rw-r--r--src/plist.h66
7 files changed, 202 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8306ee3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+build/**
+clash
+
+MD5SUM
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b65e010
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,34 @@
+.PHONY: clean test test-spec
+
+SHELL = /bin/bash
+
+CC = gcc
+CFLAGS = -Wall -Werror -std=c11 -pedantic -D_XOPEN_SOURCE=700
+VPATH=src # search for a prerequisite in those directories (delimiter is :)
+
+BUILD_TARGET=wsort
+BUILD_DIR=build
+OBJS = $(patsubst %.o, $(BUILD_DIR)/%.o, strictmem.o dynamic_array.o $(BUILD_TARGET).o)
+
+$(BUILD_TARGET): $(OBJS)
+	$(CC) -o $@ $(CFLAGS) $(OBJS)
+
+clean:
+	rm -r $(BUILD_TARGET) $(BUILD_DIR)
+
+TESTFILES=$(wildcard data/wlist*)
+
+test:
+	@time (for f in $(TESTFILES); do file="$${f##*/}"; ./$(BUILD_TARGET) < data/"$$file" > "$$file"; done)
+	@md5sum --quiet -c MD5SUM
+	@rm -f wlist*
+
+test-spec:
+	@time (for f in data/wlist*; do file="$${f##*/}"; ./$(BUILD_TARGET).bsteam < data/"$$file" > "$$file"; done)
+	@md5sum wlist* > MD5SUM
+	@rm -f wlist*
+
+
+$(BUILD_DIR)/%.o:%.c
+	@[ -d $(BUILD_DIR) ] || mkdir $(BUILD_DIR)
+	$(CC) -c -o $@ $(CFLAGS) $<
diff --git a/aufgabe.pdf b/aufgabe.pdf
new file mode 100644
index 0000000..a5b676e
--- /dev/null
+++ b/aufgabe.pdf
Binary files differdiff --git a/ref/clash.bsteam b/ref/clash.bsteam
new file mode 100755
index 0000000..82cc4a9
--- /dev/null
+++ b/ref/clash.bsteam
Binary files differdiff --git a/ref/plist.o.bsteam b/ref/plist.o.bsteam
new file mode 100644
index 0000000..5fe4b50
--- /dev/null
+++ b/ref/plist.o.bsteam
Binary files differdiff --git a/src/plist.c b/src/plist.c
new file mode 100644
index 0000000..2a4ecb7
--- /dev/null
+++ b/src/plist.c
@@ -0,0 +1,98 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include "plist.h"
+
+/* Die Funktionen insertElement() und removeElement() bitte unveraendert lassen!
+ * Falls Sie einen Bug in dieser Implementierung finden, melden Sie diesen bitte
+ * an bs@lists.ruhr-uni-bochum.de
+ */
+
+struct queue_element {
+	pid_t pid;
+	char *cmdLine;
+	struct queue_element *next;
+};
+
+static struct queue_element *head;
+
+void walkList(bool (*callback) (pid_t, const char *)) {
+	// TODO: implement me
+}
+
+int insertElement(pid_t pid, const char *cmdLine) {
+	struct queue_element *current = head;
+	struct queue_element *previous = NULL;
+
+	while (current) {
+		if (current->pid == pid) {
+			return -1;
+		}
+
+		previous = current;
+		current = current->next;
+	}
+
+	current = malloc(sizeof(struct queue_element));
+	if (current == NULL) {
+		return -2;
+	}
+
+	current->cmdLine = strdup(cmdLine);
+	if (current->cmdLine == NULL) {
+		free(current);
+		return -2;
+	}
+
+	current->pid  = pid;
+	current->next = NULL;
+
+	/* Einhaengen des neuen Elements */
+	if (previous == NULL) {
+		head = current;
+	} else {
+		previous->next = current;
+	}
+
+	return pid;
+}
+
+int removeElement(pid_t pid, char *buf, size_t buflen) {
+	if (head == NULL) {
+		return -1;
+	}
+
+	struct queue_element *current = head;
+	struct queue_element *previous = NULL;
+
+	while (current) {
+		if (current->pid == pid) {
+			if (previous == NULL) {
+				head = head->next;
+			} else {
+				previous->next = current->next;
+			}
+
+			strncpy(buf, current->cmdLine, buflen);
+			if (buflen > 0) {
+				buf[buflen-1]='\0';
+			}
+			int retVal = (int)strlen(current->cmdLine);
+
+			/* Speicher freigeben */
+			free(current->cmdLine);
+			current->cmdLine = NULL;
+			current->next = NULL;
+			current->pid = 0;
+			free(current);
+			return retVal;
+		}
+
+		previous = current;
+		current = current->next;
+	}
+
+	/* PID not found */
+	return -1;
+}
diff --git a/src/plist.h b/src/plist.h
new file mode 100644
index 0000000..616e9a6
--- /dev/null
+++ b/src/plist.h
@@ -0,0 +1,66 @@
+#ifndef PLIST_H
+#define PLIST_H
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+/** \file plist.h
+ *
+ *  \brief Linked List for maintaining process id - command line pairs.
+ *
+ *  This implementation is not thread safe.
+ */
+
+/**
+ *  \brief Inserts a new pid-command line pair into the linked list.
+ *
+ * During the insert operation, the passed commandLine is copied to
+ * an internally allocated buffer. The caller may free or otherwise
+ * reuse the memory occupied by commandLine after return from
+ * insertElement.
+ *
+ *  \param pid The process id of the pair that is to be inserted.
+ *  \param commandLine The commandLine corresponding to the process with id pid.
+ *
+ *  \return pid on success, negative value on error
+ *    \retval pid  success
+ *    \retval  -1  a pair with the given pid already exists
+ *    \retval  -2  insufficient memory to complete the operation
+ */
+int insertElement(pid_t pid, const char *commandLine);
+
+/**
+ *  \brief Remove a specific pid-command line pair from the linked list.
+ *
+ * The linked list is searched for a pair with the given pid. If such a pair is
+ * found, the '\\0'-terminated command line is copied to the buffer provided by
+ * the caller. If the length of the command line exceeds the size of the
+ * buffer, only the first (buffersize-1) characters of the command line are
+ * copied to the buffer and terminated with the '\\0' character. Upon
+ * completion, removeElement deallocates all resources that were occupied by
+ * the removed pair.
+ *
+ *  \param pid The process id of the pair that is to be removed.
+ *  \param commandLineBuffer A buffer provided by the caller that the '\\0'-terminated commandline is written to.
+ *  \param bufferSize The size of commandLineBuffer.
+ *
+ *  \return actual length of the command line on success, negative value on error.
+ *    \retval >0  success, actual length of the command line
+ *    \retval -1  a pair with the given pid does not exist
+ */
+int removeElement(pid_t pid, char *commandLineBuffer, size_t bufferSize);
+
+/**
+ *  \brief Invokes a callback function on each element in the list.
+ *
+ * 	The callback function is passed the pid-command line pair for the current
+ * 	list element. The callback function shall return false to request further
+ * 	processing of the list. A return value of true will cause the early
+ * 	termination of the list walk. The callback function must not modify the
+ * 	process list.
+ *
+ *  \param callback Pointer to the function to be invoked for each list element.
+ */
+void walkList(bool (*callback)(pid_t, const char *));
+
+#endif