summaryrefslogtreecommitdiffstats
path: root/02_exercise/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to '02_exercise/builtins.c')
-rw-r--r--02_exercise/builtins.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/02_exercise/builtins.c b/02_exercise/builtins.c
new file mode 100644
index 0000000..ac655d8
--- /dev/null
+++ b/02_exercise/builtins.c
@@ -0,0 +1,73 @@
+#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. */
+}
+
+
+void builtin_wait(process p) {
+
+ struct sigaction handler;
+ handler.sa_handler = handle;
+ sigemptyset(&handler.sa_mask);
+ handler.sa_flags = 0;
+ bool error = false;
+ pid_t *pids;
+ arrayInit(pids);
+ size_t i = 1;
+ while (!error && p.argv[i] != NULL) {
+ char *end;
+ pid_t tmp = strtol(p.argv[i], &end, 10);
+ if (*end != '\0') {
+ fprintf(stderr, "Not a valid pid: %s", p.argv[i]);
+ error = true;
+ break;
+ }
+ arrayPush(pids) = tmp;
+ ++i;
+ }
+
+ if (!error) {
+ while (!arrayIsEmpty(pids)) {
+ int status;
+ pid_t current_pid = arrayPop(pids);
+ 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
+ } else {
+ perror("Could not wait on process");
+ }
+ } 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)));
+ } else {
+ printf("[%i] exited (not sure why), exit status: %i\n", current_pid,
+ WEXITSTATUS(status));
+ }
+ }
+ signal(SIGINT, SIG_DFL);
+ }
+ }
+
+ arrayRelease(pids);
+} \ No newline at end of file