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 +++++++++++++++++++++++++++++---------------- 02_exercise/prompt_utils.c | 20 ++++----- 2 files changed, 77 insertions(+), 48 deletions(-) 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); } diff --git a/02_exercise/prompt_utils.c b/02_exercise/prompt_utils.c index 168c088..751a81b 100644 --- a/02_exercise/prompt_utils.c +++ b/02_exercise/prompt_utils.c @@ -23,26 +23,26 @@ char const *relative_path(char const *const from_dir, char const *const to_dir) } // splitting path into pieces so we can do strcmp on each of them - size_t const *const from_dir_indeces = get_separator_indices(from_dir, '/'); - size_t const *const to_dir_indeces = get_separator_indices(to_dir, '/'); + size_t const *const from_dir_indices = get_separator_indices(from_dir, '/'); + size_t const *const to_dir_indices = get_separator_indices(to_dir, '/'); - size_t from_dir_len = arrayLen(from_dir_indeces); - size_t to_dir_len = arrayLen(to_dir_indeces); + size_t from_dir_len = arrayLen(from_dir_indices); + size_t to_dir_len = arrayLen(to_dir_indices); // finding the longest common substring size_t array_len = from_dir_len < to_dir_len ? from_dir_len : to_dir_len; size_t i = 0; size_t common_position = 0; for (; i < array_len - 1; ++i) { - if (from_dir_indeces[i + 1] != to_dir_indeces[i + 1]) { + if (from_dir_indices[i + 1] != to_dir_indices[i + 1]) { break; } - size_t index = from_dir_indeces[i]; - size_t count = from_dir_indeces[i + 1] - from_dir_indeces[i]; + size_t index = from_dir_indices[i]; + size_t count = from_dir_indices[i + 1] - from_dir_indices[i]; if (strncmp(from_dir + index, to_dir + index, count) != 0) { break; } - common_position = from_dir_indeces[i + 1]; + common_position = from_dir_indices[i + 1]; } size_t levels_up = from_dir_len - i - 1; @@ -67,8 +67,8 @@ char const *relative_path(char const *const from_dir, char const *const to_dir) } } - arrayRelease((void *)from_dir_indeces); - arrayRelease((void *)to_dir_indeces); + arrayRelease((void *)from_dir_indices); + arrayRelease((void *)to_dir_indices); return return_value; } -- cgit v1.2.3-54-g00ecf