From 2dfb4e933a3c3d66670b506b5f6aca55266df6e5 Mon Sep 17 00:00:00 2001 From: Stefan Zabka Date: Sun, 24 May 2020 21:10:30 +0200 Subject: Intial split --- 02_exercise/CMakeLists.txt | 20 +++++++++---- 02_exercise/builtins.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 02_exercise/builtins.h | 7 +++++ 02_exercise/shell.c | 56 ++--------------------------------- 4 files changed, 96 insertions(+), 60 deletions(-) create mode 100644 02_exercise/builtins.c create mode 100644 02_exercise/builtins.h 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 +#include +#include +#include +#include +#include + + +#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 ` - 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]); -- cgit v1.2.3-54-g00ecf