summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-05-24 12:58:25 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-05-24 12:58:25 +0200
commitbed31a7634701b2c19ef8eef3ccb3039c03b1cda (patch)
tree50352a24134173031603c168b4b9a574fd551fe8
parent32db24465d74f99409a182bd07140231f65a13e3 (diff)
downloadbetriebssysteme-bed31a7634701b2c19ef8eef3ccb3039c03b1cda.tar.gz
betriebssysteme-bed31a7634701b2c19ef8eef3ccb3039c03b1cda.zip
minor changes
-rw-r--r--02_exercise/process.c36
-rw-r--r--02_exercise/process.h11
-rw-r--r--02_exercise/process_test.c10
-rw-r--r--02_exercise/shell.c10
4 files changed, 34 insertions, 33 deletions
diff --git a/02_exercise/process.c b/02_exercise/process.c
index 8dc331a..8f6589d 100644
--- a/02_exercise/process.c
+++ b/02_exercise/process.c
@@ -8,9 +8,10 @@
#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) {
+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;
@@ -18,19 +19,13 @@ int parse_command(char const *line, char const *end, Process *p) {
for (size_t i = 0; line + i < end; ++i) {
char c = line[i];
- if (c == ' ' || c == '\0') {
+ if (c == '\t' || 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);
- }
+ arrayInit(part);
} else {
arrayPush(part) = c;
}
@@ -49,7 +44,7 @@ int parse_command(char const *line, char const *end, Process *p) {
return 0;
}
-int parse_line(char const *const line, Process **processes) {
+int parse_line(char const *const line, process **processes) {
// splits the line at | and then parses the commands
int ret_code;
@@ -61,7 +56,7 @@ int parse_line(char const *const line, Process **processes) {
bool done = false;
char const *cursor = line;
while (!done) {
- Process p = {.in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true};
+ process p = {.argv = NULL, .argc = 0, .in_fd = 0, .out_fd = 0, .pid = 0, .blocking = true};
char const *end = strchr(cursor, '|');
if (end == NULL) {
@@ -78,7 +73,7 @@ int parse_line(char const *const line, Process **processes) {
}
size_t p_len = arrayLen(*processes);
- Process *last = *processes + (p_len - 1);
+ 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) {
@@ -101,10 +96,11 @@ int parse_line(char const *const line, Process **processes) {
(*processes)[i].blocking = false;
}
}
+
return ret_code;
}
-int exec_command(Process p) {
+int exec_command(process p) {
int status;
if (!p.blocking) {
@@ -118,10 +114,12 @@ int exec_command(Process p) {
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, "command not found: \"%s\"\n", p.argv[0]);
fflush(stderr);
@@ -157,14 +155,16 @@ int exec_command(Process p) {
return WEXITSTATUS(status);
}
-void 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)
+ char *tmp = arrayTop(p.argv);
+ if (tmp) {
arrayRelease(tmp);
+ }
+ arrayPop(p.argv) = NULL;
}
arrayRelease(p.argv);
}
diff --git a/02_exercise/process.h b/02_exercise/process.h
index 3b7e833..6e9208c 100644
--- a/02_exercise/process.h
+++ b/02_exercise/process.h
@@ -1,7 +1,8 @@
#ifndef SHELL_PROCESS_H
#define SHELL_PROCESS_H
-#include <stdbool.h>
+
#include <stddef.h>
+#include <stdbool.h>
typedef struct {
char **argv;
@@ -10,20 +11,20 @@ typedef struct {
int out_fd;
int pid;
bool blocking;
-} Process;
+} 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);
+int parse_line(char const *line, process **processes);
/*
* returns the return code of the executed program
*/
-int exec_command(Process p);
+int exec_command(process p);
-void free_processes(Process ** processes);
+void free_processes(process **processes);
#endif // SHELL_PROCESS_H
diff --git a/02_exercise/process_test.c b/02_exercise/process_test.c
index a7b0b9c..591a06f 100644
--- a/02_exercise/process_test.c
+++ b/02_exercise/process_test.c
@@ -5,7 +5,7 @@
#include "process.h"
void test_simple_case() {
- Process *processes = NULL;
+ process *processes = NULL;
parse_line("cat my_txt ", &processes);
assert(arrayLen(processes) == 1);
assert(arrayLen(processes[0].argv) == 3);
@@ -15,7 +15,7 @@ void test_simple_case() {
}
void test_detached() {
- Process *processes = NULL;
+ process *processes = NULL;
parse_line("cat my_txt &", &processes);
assert(arrayLen(processes) == 1);
assert(arrayLen(processes[0].argv) == 3);
@@ -27,7 +27,7 @@ void test_detached() {
void test_pipe() {
- Process *processes = NULL;
+ process *processes = NULL;
parse_line("echo my_txt | grep txt", &processes);
assert(arrayLen(processes) == 2);
assert(arrayLen(processes[0].argv) == 3);
@@ -42,10 +42,10 @@ 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);
diff --git a/02_exercise/shell.c b/02_exercise/shell.c
index f456465..d1e52ec 100644
--- a/02_exercise/shell.c
+++ b/02_exercise/shell.c
@@ -28,19 +28,20 @@ int main(void) {
}
if (strspn(line, " \n\t") == strlen(line)) {
+ // skip empty lines - empty being just spaces or tabs
continue;
}
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) {
-
- if(arrayLen(processes) != 1) {
+ 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;
@@ -57,9 +58,8 @@ int main(void) {
} 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]);
+ int ret = exec_command(processes[i]);
if (ret)
printf("[%i] ", ret);
}