From d8dd0f9726034e3a53bc0ee49490bc9f1254b78e Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Mon, 25 May 2020 21:16:56 +0200 Subject: lots of stuff --- 02_exercise/builtins.c | 105 +++++++++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 38 deletions(-) (limited to '02_exercise/builtins.c') diff --git a/02_exercise/builtins.c b/02_exercise/builtins.c index 8b23c74..9f23927 100644 --- a/02_exercise/builtins.c +++ b/02_exercise/builtins.c @@ -13,6 +13,10 @@ 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; @@ -20,70 +24,95 @@ void builtin_wait(process p, bool bind) { sigemptyset(&handler.sa_mask); handler.sa_flags = 0; - pid_t *pids; - arrayInit(pids); + hack_struct *pcs; + arrayInit(pcs); size_t i = 1; - bool error = false; + bool error = false; while (!error && p.argv[i] != NULL) { - char *end; - pid_t tmp = strtol(p.argv[i], &end, 10); + 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", p.argv[i]); + fprintf(stderr, "Not a valid pid: %s\n", p.argv[i]); error = true; break; } - arrayPush(pids) = tmp; + arrayPush(pcs) = pc; ++i; } - if (!error) { - while (!arrayIsEmpty(pids)) { - int status; - pid_t current_pid = arrayPop(pids); - if (bind) { - printf("Resuming %ld...\n", (long) current_pid); - } else { - printf("Waiting for %ld...\n", (long) current_pid); + 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); - if (waitpid(current_pid, &status, WUNTRACED) < 0) { + pid_t res; + if ((res = waitpid(current_pc->pid, &status, options)) < 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); + kill(current_pc->pid, SIGKILL); + waitpid(current_pc->pid, &status, options); + printf("Killed [%ld]\n", (long) current_pc->pid); } else { - kill(current_pid, SIGCONT); + 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 { - if (bind) { - printf("[%i] ", WEXITSTATUS(status)); - } 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))); + current_pc->done = true; + ++done_count; + if (bind) { + printf("[%i] ", WEXITSTATUS(status)); } else { - printf("[%i] exited (not sure why), exit status: %i\n", current_pid, - WEXITSTATUS(status)); + 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_DFL); + signal(SIGINT, SIG_IGN); } } - arrayRelease(pids); + arrayRelease(pcs); } -- cgit v1.2.3-54-g00ecf