summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Zabka <zabkaste@hu-berlin.de>2020-05-24 21:10:30 +0200
committerStefan Zabka <zabkaste@hu-berlin.de>2020-05-24 21:10:54 +0200
commit2dfb4e933a3c3d66670b506b5f6aca55266df6e5 (patch)
tree862248da4597f3735455b5f84341439b735aec6c
parent4461c8ade2280cdb27076243caa153447ad29d71 (diff)
downloadbetriebssysteme-2dfb4e933a3c3d66670b506b5f6aca55266df6e5.tar.gz
betriebssysteme-2dfb4e933a3c3d66670b506b5f6aca55266df6e5.zip
Intial splitbuiltins_file
-rw-r--r--02_exercise/CMakeLists.txt20
-rw-r--r--02_exercise/builtins.c73
-rw-r--r--02_exercise/builtins.h7
-rw-r--r--02_exercise/shell.c56
4 files changed, 96 insertions, 60 deletions
diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt
index 9cae089..e47f0ee 100644
--- a/02_exercise/CMakeLists.txt
+++ b/02_exercise/CMakeLists.txt
@@ -5,30 +5,38 @@ project(shell C)
set(CMAKE_C_COMPILER gcc)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
+add_compile_definitions(_GNU_SOURCE)
+
find_package(Sanitizers)
add_executable(prog prog.c)
-add_executable(shell shell.c)
-target_link_libraries(shell PRIVATE array prompt_utils process)
+add_executable(shell shell.c)
+target_link_libraries(shell PRIVATE array prompt_utils process builtin)
+target_compile_options(shell INTERFACE ${PROJECT_WARNINGS})
add_sanitizers(shell)
-add_compile_definitions(_GNU_SOURCE)
+
+add_library(builtin builtins.c)
+target_compile_options(builtin INTERFACE ${PROJECT_WARNINGS})
add_library(array array.c)
+
add_library(prompt_utils prompt_utils.c)
target_link_libraries(prompt_utils PRIVATE array)
+target_compile_options(prompt_utils INTERFACE ${PROJECT_WARNINGS})
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)
+target_compile_options(process INTERFACE ${PROJECT_WARNINGS})
add_executable(process_test process_test.c)
target_link_libraries(process_test PRIVATE process)
-target_compile_options(shell INTERFACE ${PROJECT_WARNINGS})
-target_compile_options(prompt_utils INTERFACE ${PROJECT_WARNINGS})
-target_compile_options(process INTERFACE ${PROJECT_WARNINGS})
+
+
diff --git a/02_exercise/builtins.c b/02_exercise/builtins.c
new file mode 100644
index 0000000..ac655d8
--- /dev/null
+++ b/02_exercise/builtins.c
@@ -0,0 +1,73 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <wait.h>
+#include <stdlib.h>
+
+
+#include "array.h"
+#include "builtins.h"
+
+void handle(int sig) {
+ /* Do nothing. */
+}
+
+
+void builtin_wait(process p) {
+
+ struct sigaction handler;
+ handler.sa_handler = handle;
+ sigemptyset(&handler.sa_mask);
+ handler.sa_flags = 0;
+ bool error = false;
+ pid_t *pids;
+ arrayInit(pids);
+ size_t i = 1;
+ while (!error && p.argv[i] != NULL) {
+ char *end;
+ pid_t tmp = strtol(p.argv[i], &end, 10);
+ if (*end != '\0') {
+ fprintf(stderr, "Not a valid pid: %s", p.argv[i]);
+ error = true;
+ break;
+ }
+ arrayPush(pids) = tmp;
+ ++i;
+ }
+
+ if (!error) {
+ while (!arrayIsEmpty(pids)) {
+ int status;
+ pid_t current_pid = arrayPop(pids);
+ printf("Waiting for %ld...\n", (long)current_pid);
+ // install signal handler without SA_RESTART, so waitpid gets interrupted
+ sigaction(SIGINT, &handler, NULL);
+ if (waitpid(current_pid, &status, WUNTRACED) < 0) {
+ if (EINTR == errno) {
+ // cancelled by ctrl-c
+ } else {
+ perror("Could not wait on process");
+ }
+ } else {
+ printf("[%i] TERMINATED\n", current_pid);
+ if (WIFEXITED(status)) {
+ printf("[%i] exited normally with status: %i\n", current_pid,
+ WEXITSTATUS(status));
+ } else if (WIFSTOPPED(status)) {
+ printf("[%i] was stopped by signal: %s\n", current_pid,
+ strsignal(WSTOPSIG(status)));
+ } else if (WIFSIGNALED(status)) {
+ printf("[%i] was terminated by signal: %s\n", current_pid,
+ strsignal(WTERMSIG(status)));
+ } else {
+ printf("[%i] exited (not sure why), exit status: %i\n", current_pid,
+ WEXITSTATUS(status));
+ }
+ }
+ signal(SIGINT, SIG_DFL);
+ }
+ }
+
+ arrayRelease(pids);
+} \ No newline at end of file
diff --git a/02_exercise/builtins.h b/02_exercise/builtins.h
new file mode 100644
index 0000000..1779216
--- /dev/null
+++ b/02_exercise/builtins.h
@@ -0,0 +1,7 @@
+#ifndef BUILTINS_H
+#define BUILTINS_H
+
+#include "process.h"
+void builtin_wait(process p);
+
+#endif \ No newline at end of file
diff --git a/02_exercise/shell.c b/02_exercise/shell.c
index e21957d..f4b6738 100644
--- a/02_exercise/shell.c
+++ b/02_exercise/shell.c
@@ -9,19 +9,13 @@
#include "array.h"
#include "process.h"
#include "prompt_utils.h"
+#include "builtins.h"
-void handle(int sig) {
- /* Do nothing. */
-}
int main(void) {
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
- struct sigaction handler;
- handler.sa_handler = handle;
- sigemptyset(&handler.sa_mask);
- handler.sa_flags = 0;
printf("Welcome! Available built-ins are:\n"
"cd: `cd <path>` - if no path is given, return to the current dir\n"
@@ -85,53 +79,7 @@ int main(void) {
} else if (strcmp(processes[0].argv[0], "exit") == 0) {
done = true;
} else if (strcmp(processes[0].argv[0], "wait") == 0) {
- bool error = false;
- pid_t *pids;
- arrayInit(pids);
- size_t i = 1;
- while (!error && processes[0].argv[i] != NULL) {
- char *end;
- pid_t tmp = strtol(processes[0].argv[i], &end, 10);
- if (*end != '\0') {
- fprintf(stderr, "Not a valid pid: %s", processes[0].argv[i]);
- error = true;
- break;
- }
- arrayPush(pids) = tmp;
- ++i;
- }
-
- if (!error) {
- while (!arrayIsEmpty(pids)) {
- int status;
- pid_t current_pid = arrayPop(pids);
- printf("Waiting for %ld...\n", (long) current_pid);
- // install signal handler without SA_RESTART, so waitpid gets interrupted
- sigaction(SIGINT, &handler, NULL);
- if (waitpid(current_pid, &status, WUNTRACED) < 0) {
- if (EINTR == errno) {
- // cancelled by ctrl-c
- } else {
- perror("Could not wait on process");
- }
- } else {
- printf("[%i] TERMINATED\n", current_pid);
- if (WIFEXITED(status)) {
- printf("[%i] exited normally with status: %i\n", current_pid, WEXITSTATUS(status));
- } else if (WIFSTOPPED(status)) {
- printf("[%i] was stopped by signal: %s\n", current_pid, strsignal(WSTOPSIG(status)));
- } else if (WIFSIGNALED(status)) {
- printf("[%i] was terminated by signal: %s\n", current_pid, strsignal(WTERMSIG(status)));
- } else {
- printf("[%i] exited (not sure why), exit status: %i\n", current_pid, WEXITSTATUS(status));
- }
- }
- signal(SIGINT, SIG_DFL);
- }
- }
-
- arrayRelease(pids);
-
+ builtin_wait(processes[0]);
} else {
for (size_t i = 0; i < arrayLen(processes); ++i) {
int ret = exec_command(processes[i]);