summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-05-21 19:46:13 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-05-21 19:46:13 +0200
commit68f5ff29c0aae1a176c25996aab0144badd0f092 (patch)
treefdbe84c3d7755e116dd10fe2a30a45d4f2dc4ca1
parent8da59918c22df70eaec28150867c7e8bfd4bc1ae (diff)
downloadbetriebssysteme-68f5ff29c0aae1a176c25996aab0144badd0f092.tar.gz
betriebssysteme-68f5ff29c0aae1a176c25996aab0144badd0f092.zip
you can now put stuff in the background, yay
-rw-r--r--02_exercise/shell.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/02_exercise/shell.c b/02_exercise/shell.c
index 1bdeab6..7032a99 100644
--- a/02_exercise/shell.c
+++ b/02_exercise/shell.c
@@ -1,4 +1,3 @@
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -12,19 +11,19 @@
int parse_line(char const *line, char ***parts, size_t *part_count);
// returns the return code of the executed program
-int exec_command(const char *path, char *const argv[], unsigned timeout);
+int exec_command(const char *path, char *const argv[], bool background);
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) {
+ bool bg = false;
char *line = NULL;
size_t cap = 0;
- __ssize_t length = 0;
+ __ssize_t length;
printf("%s > ", prompt);
if ((length = getline(&line, &cap, stdin)) < 0) {
@@ -42,7 +41,19 @@ int main(void) {
size_t argument_count;
parse_line(line, &arguments, &argument_count);
- if (strcmp(arguments[0], "cd") == 0) {
+ if (argument_count <= 0)
+ goto clean;
+
+ char *command = arguments[0];
+ char *last_arg = arguments[argument_count - 2];
+
+ if (strcmp(last_arg, "&") == 0) {
+ bg = true;
+ arrayRelease(arguments[argument_count - 2]);
+ arguments[argument_count - 2] = NULL;
+ }
+
+ if (strcmp(command, "cd") == 0) {
if (arrayLen(arguments) != 3) {
fprintf(stderr, "usage: cd <path>");
goto clean;
@@ -56,10 +67,10 @@ int main(void) {
char const *current_wd = get_current_dir_name();
prompt = relative_path(original_wd, current_wd);
free((void *)current_wd);
- } else if (strcmp(arguments[0], "exit") == 0) {
+ } else if (strcmp(command, "exit") == 0) {
done = true;
} else {
- int ret = exec_command(arguments[0], arguments, 0);
+ int ret = exec_command(command, arguments, bg);
if (ret)
printf("[%i] ", ret);
}
@@ -111,19 +122,7 @@ int parse_line(char const *line, char ***parts, size_t *part_count) {
return 0;
}
-void print_prompt() {
- size_t length = 1024;
- char *buffer = malloc(length * sizeof(char));
- getcwd(buffer, length);
- if (buffer == NULL) {
- printf(".> ");
- } else {
- printf("%s > ", buffer);
- }
-}
-
-int exec_command(const char *path, char *const argv[], unsigned timeout) {
- timeout = timeout ^ timeout;
+int exec_command(const char *path, char *const argv[], bool background) {
int pid;
int pipefd[2];
int status;
@@ -132,7 +131,7 @@ int exec_command(const char *path, char *const argv[], unsigned timeout) {
pipe(pipefd);
if ((pid = fork()) == 0) {
close(pipefd[0]);
- dup2(pipefd[1], 1); // includes close(1);
+ dup2(pipefd[1], 1);
close(pipefd[1]);
execvp(path, argv);
fprintf(stderr, "could not execute \"%s\"\n", path);
@@ -147,14 +146,29 @@ int exec_command(const char *path, char *const argv[], unsigned timeout) {
close(pipefd[1]);
- __ssize_t length = 0;
- while ((length = read(pipefd[0], buf, 10)) > 0) {
- buf[length] = '\0';
- fprintf(stdout, "%s", buf);
- fflush(stdout);
+ int new_pid;
+ if (background) {
+ new_pid = fork();
}
- waitpid(pid, &status, 0);
+ if (!background || new_pid == 0) {
+ if (background)
+ printf("[%i]\n", pid);
+
+ __ssize_t length;
+ while ((length = read(pipefd[0], buf, 10)) > 0) {
+ buf[length] = '\0';
+ printf("%s", buf);
+ }
+
+ waitpid(pid, &status, 0);
+
+ if (background) {
+ printf("[%i] TERMINATED\n", pid);
+ printf("[%i] EXIT STATUS: %i\n", pid, status);
+ exit(0);
+ }
+ }
close(pipefd[0]);