summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNiklas Halle <niklas@niklashalle.net>2020-05-25 21:16:56 +0200
committerNiklas Halle <niklas@niklashalle.net>2020-05-25 21:16:56 +0200
commitd8dd0f9726034e3a53bc0ee49490bc9f1254b78e (patch)
treeda3b92e09108fda70fe304938c9fe998705cefc9
parent9b1a0928001aacc4420617ab1b6c84dcb16f7e75 (diff)
downloadbetriebssysteme-d8dd0f9726034e3a53bc0ee49490bc9f1254b78e.tar.gz
betriebssysteme-d8dd0f9726034e3a53bc0ee49490bc9f1254b78e.zip
lots of stuff
-rw-r--r--02_exercise/builtins.c105
-rw-r--r--02_exercise/prompt_utils.c20
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;
}