From 74abc79434fe895d0ca863e4d1d6c5c16b54f296 Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 1 Jun 2020 15:46:28 +0200 Subject: trying to connect server and shell, weird --- 03_exercise/srv/builtins.c | 120 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 03_exercise/srv/builtins.c (limited to '03_exercise/srv/builtins.c') diff --git a/03_exercise/srv/builtins.c b/03_exercise/srv/builtins.c new file mode 100644 index 0000000..f5497a3 --- /dev/null +++ b/03_exercise/srv/builtins.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include + + +#include "array.h" +#include "builtins.h" + +void handle(int sig) { + /* Do nothing. */ +} + +typedef struct { + pid_t pid; + bool done; +} hack_struct; + +void builtin_wait(process p, bool bind) { + struct sigaction handler; + handler.sa_handler = handle; + sigemptyset(&handler.sa_mask); + handler.sa_flags = 0; + + hack_struct *pcs; + arrayInit(pcs); + + size_t i = 1; + bool error = false; + while (!error && p.argv[i] != NULL) { + char *end; + hack_struct pc; + pc.pid = strtol(p.argv[i], &end, 10); + pc.done = false; + if (*end != '\0') { + fprintf(stderr, "Not a valid pid: %s\n", p.argv[i]); + error = true; + break; + } + arrayPush(pcs) = pc; + ++i; + } + + if (error || arrayLen(pcs) == 0) { + printf("plz giv pid\n"); + arrayRelease(pcs); + return; + } + + int options = WUNTRACED; + if (!bind) { + options |= WNOHANG; + } + + int done_count = 0; + while (done_count != arrayLen(pcs)) { + for (int j = 0; j < arrayLen(pcs); ++j) { + int status; + hack_struct *current_pc = &j[pcs]; + if (current_pc->done) { + continue; + } + + if (bind) { + printf("Resuming %ld...\n", (long) current_pc->pid); + }/* else { + printf("Waiting for %ld...\n", (long) current_pc->pid); + }*/ + // install signal handler without SA_RESTART, so waitpid gets interrupted + sigaction(SIGINT, &handler, NULL); + pid_t res; + if ((res = waitpid(current_pc->pid, &status, options)) < 0) { + if (EINTR == errno) { + // cancelled by ctrl-c + if (bind) { + current_pc->done = true; + ++done_count; + kill(current_pc->pid, SIGKILL); + waitpid(current_pc->pid, &status, options); + printf("Killed [%ld]\n", (long) current_pc->pid); + } else { + kill(current_pc->pid, SIGCONT); + } + } else { + perror("Could not wait for process"); + ++done_count; + current_pc->done = true; + } + } else if (res == 0) { + // wait terminated because nohang + } else { + current_pc->done = true; + ++done_count; + if (bind) { + printf("[%i] ", WEXITSTATUS(status)); + } else { + printf("[%i] TERMINATED\n", current_pc->pid); + if (WIFEXITED(status)) { + printf("[%i] exited normally with status: %i\n", current_pc->pid, + WEXITSTATUS(status)); + } else if (WIFSTOPPED(status)) { + printf("[%i] was stopped by signal: %s\n", current_pc->pid, + strsignal(WSTOPSIG(status))); + } else if (WIFSIGNALED(status)) { + printf("[%i] was terminated by signal: %s\n", current_pc->pid, + strsignal(WTERMSIG(status))); + } else { + printf("[%i] exited (not sure why), exit status: %i\n", current_pc->pid, + WEXITSTATUS(status)); + } + } + } + signal(SIGINT, SIG_IGN); + } + } + + arrayRelease(pcs); +} -- cgit v1.2.3-54-g00ecf