diff options
Diffstat (limited to '02_exercise')
-rw-r--r-- | 02_exercise/shell.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/02_exercise/shell.c b/02_exercise/shell.c index 20156b2..e21957d 100644 --- a/02_exercise/shell.c +++ b/02_exercise/shell.c @@ -4,15 +4,25 @@ #include <unistd.h> #include <stdbool.h> #include <wait.h> +#include <errno.h> #include "array.h" #include "process.h" #include "prompt_utils.h" +void handle(int sig) { + /* Do nothing. */ +} + int main(void) { setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); + struct sigaction handler; + handler.sa_handler = handle; + sigemptyset(&handler.sa_mask); + handler.sa_flags = 0; + printf("Welcome! Available built-ins are:\n" "cd: `cd <path>` - if no path is given, return to the current dir\n" "wait: `wait pid1 ... pidN` - wait on the processes and report their exit conditions\n" @@ -96,13 +106,27 @@ int main(void) { 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) { - perror("Could not wait on process"); + if (EINTR == errno) { + // cancelled by ctrl-c + } else { + perror("Could not wait on process"); + } } else { printf("[%i] TERMINATED\n", current_pid); - printf("[%i] EXIT STATUS: %i\n", current_pid, status); // TODO: exit status is wrong + 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)); + } } - // TODO: catch ctrl-c + signal(SIGINT, SIG_DFL); } } |