From 589ec07d1ec29e9e33714fcc0f213e79c1f36a9a Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 25 May 2020 19:42:24 +0200 Subject: DO NOT MERGE, use previous. Trying to get ctrl-z to work.. no success yet, maybe breaks stuff --- 02_exercise/CMakeLists.txt | 2 +- 02_exercise/builtins.c | 27 ++++++--------------------- 02_exercise/process.c | 10 ++++++++-- 02_exercise/shell.c | 18 ++++-------------- 02_exercise/signal_handler.c | 30 ++++++++++++++++++++++++++++++ 02_exercise/signal_handler.h | 13 +++++++++++++ 6 files changed, 62 insertions(+), 38 deletions(-) create mode 100644 02_exercise/signal_handler.c create mode 100644 02_exercise/signal_handler.h diff --git a/02_exercise/CMakeLists.txt b/02_exercise/CMakeLists.txt index e47f0ee..6a2077f 100644 --- a/02_exercise/CMakeLists.txt +++ b/02_exercise/CMakeLists.txt @@ -12,7 +12,7 @@ find_package(Sanitizers) add_executable(prog prog.c) -add_executable(shell shell.c) +add_executable(shell shell.c signal_handler.c signal_handler.h) target_link_libraries(shell PRIVATE array prompt_utils process builtin) target_compile_options(shell INTERFACE ${PROJECT_WARNINGS}) add_sanitizers(shell) diff --git a/02_exercise/builtins.c b/02_exercise/builtins.c index 4ab4c7c..1d1cc69 100644 --- a/02_exercise/builtins.c +++ b/02_exercise/builtins.c @@ -1,22 +1,16 @@ -#include #include #include #include #include #include - #include "array.h" #include "builtins.h" - -void handle(int sig) { - /* Do nothing. */ -} - +#include "signal_handler.h" void builtin_wait(process p, bool bind) { struct sigaction handler; - handler.sa_handler = handle; + handler.sa_handler = signal_handler; sigemptyset(&handler.sa_mask); handler.sa_flags = 0; @@ -43,24 +37,15 @@ void builtin_wait(process p, bool bind) { pid_t current_pid = arrayPop(pids); if (bind) { printf("Resuming %ld...\n", (long) current_pid); + sigaction(SIGINT, &handler, NULL); } else { 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 - if (bind) { - kill(current_pid, SIGKILL); - waitpid(current_pid, &status, WUNTRACED); - printf("Killed [%ld]\n", (long)current_pid); - } else { - kill(current_pid, SIGCONT); - } - } else { - perror("Could not wait for process"); - } + sigaction(SIGINT, &handler, NULL); + handle_interrupt(current_pid); } else { printf("[%i] TERMINATED\n", current_pid); if (WIFEXITED(status)) { @@ -77,7 +62,7 @@ void builtin_wait(process p, bool bind) { WEXITSTATUS(status)); } } - signal(SIGINT, SIG_DFL); + sigaction(SIGINT, &handler, NULL); } } diff --git a/02_exercise/process.c b/02_exercise/process.c index 0b69074..2479955 100644 --- a/02_exercise/process.c +++ b/02_exercise/process.c @@ -3,10 +3,11 @@ #include #include #include +#include #include "array.h" #include "process.h" - +#include "signal_handler.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) { @@ -142,7 +143,12 @@ int exec_command(process p) { printf("[%i]\n", p.pid); if (waitpid(p.pid, &status, p.blocking ? 0 : WNOHANG) < 0) { - fprintf(stderr, "wait error'ed out\n"); + if (EINTR == errno) { + // cancelled by ctrl-c + handle_interrupt(p.pid); + } else { + perror("Could not wait for process"); + } } return WEXITSTATUS(status); diff --git a/02_exercise/shell.c b/02_exercise/shell.c index 03ff6b3..f32bb95 100644 --- a/02_exercise/shell.c +++ b/02_exercise/shell.c @@ -3,28 +3,16 @@ #include #include #include -#include #include #include "array.h" #include "process.h" -#include "prompt_utils.h" #include "builtins.h" +#include "prompt_utils.h" +#include "signal_handler.h" process *processes; -void signal_handler(int signal) { - printf("Received signal %d", signal); - if (signal == SIGINT) { - for (size_t i = 0; i < arrayLen(processes); ++i) { - pid_t pid = processes[i].pid; - if (pid != 0) { - kill(pid, SIGINT); - } - } - } -} - int main(void) { setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); @@ -59,6 +47,8 @@ int main(void) { exit(-1); } + interrupt_issued = 0; + if (strspn(line, " \n\t") == strlen(line)) { // skip empty lines - empty being just spaces or tabs continue; diff --git a/02_exercise/signal_handler.c b/02_exercise/signal_handler.c new file mode 100644 index 0000000..e135739 --- /dev/null +++ b/02_exercise/signal_handler.c @@ -0,0 +1,30 @@ +#include "signal_handler.h" + +#include +#include +#include + +void signal_handler(int signal) { + if (signal == SIGINT) { + interrupt_issued = 1; + } else if (signal == SIGTSTP) { + stop_issued = 1; + kill(getpid(), SIGINT); + } +} + +void handle_interrupt(pid_t pid) { + int status; + if (stop_issued) { + stop_issued = 0; + interrupt_issued = 0; + } else if (interrupt_issued) { + interrupt_issued = 0; + kill(pid, SIGKILL); + waitpid(pid, &status, 0); + printf("Killed [%ld]\n", (long)pid); + return; + } + kill(pid, SIGCONT); + printf("[%ld]\n", (long)pid); +} \ No newline at end of file diff --git a/02_exercise/signal_handler.h b/02_exercise/signal_handler.h new file mode 100644 index 0000000..b30c5ec --- /dev/null +++ b/02_exercise/signal_handler.h @@ -0,0 +1,13 @@ +#ifndef BETRIEBSYSTEME_SIGNAL_HANDLER_H +#define BETRIEBSYSTEME_SIGNAL_HANDLER_H + +#include + +static volatile sig_atomic_t stop_issued = 0; +static volatile sig_atomic_t interrupt_issued = 0; + +void signal_handler(int sig); + +void handle_interrupt(pid_t pid); + +#endif //BETRIEBSYSTEME_SIGNAL_HANDLER_H -- cgit v1.2.3-54-g00ecf