summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-05-25 19:42:24 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-05-25 19:42:24 +0200
commit589ec07d1ec29e9e33714fcc0f213e79c1f36a9a (patch)
tree785e8d77493c0eeac4ea94799daf24f75ad2016d
parent41775b83ad93264b487bf0dc353b145922ee6d73 (diff)
downloadbetriebssysteme-fixing_signals.tar.gz
betriebssysteme-fixing_signals.zip
DO NOT MERGE, use previous. Trying to get ctrl-z to work.. no success yet, maybe breaks stufffixing_signals
-rw-r--r--02_exercise/CMakeLists.txt2
-rw-r--r--02_exercise/builtins.c27
-rw-r--r--02_exercise/process.c10
-rw-r--r--02_exercise/shell.c18
-rw-r--r--02_exercise/signal_handler.c30
-rw-r--r--02_exercise/signal_handler.h13
6 files changed, 62 insertions, 38 deletions
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 <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. */
-}
-
+#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 <string.h>
#include <unistd.h>
#include <wait.h>
+#include <errno.h>
#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 <string.h>
#include <unistd.h>
#include <stdbool.h>
-#include <wait.h>
#include <errno.h>
#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 <wait.h>
+#include <stdio.h>
+#include <unistd.h>
+
+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 <signal.h>
+
+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