From d8d82cf3c08a6853d7932cf4ef8550f5db5250d9 Mon Sep 17 00:00:00 2001 From: stitchy Date: Wed, 15 Nov 2023 22:56:55 +0000 Subject: [PATCH] Fix small behaviors --- smallsh/main.c | 58 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/smallsh/main.c b/smallsh/main.c index 762dcaf..c32abe1 100644 --- a/smallsh/main.c +++ b/smallsh/main.c @@ -5,16 +5,11 @@ int stop_msg = 0; int main() { - /* - struct sigaction sa; - sa.sa_handler = sigstop_handle; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - */ - + // Signal Handling signal(SIGINT, sigint_handle); signal(SIGTSTP, sigstop_handle); + // Reusable Variables int status = 0; size_t input_size = 2048; size_t getline_len; @@ -22,9 +17,10 @@ int main() { while(1) { + // Check and reap children that have exited clean_children(); - //signal handling + // Handle Switching Between Stop Mode if(stop_msg) { if(stop_flag) printf("Entering Stop Mode: Background Processes Do Not Work (&)\n"); @@ -34,11 +30,13 @@ int main() { } + // Shell Value Grabbing printf(": "); fflush(stdout); getline_len = getline(&input, &input_size, stdin); input[getline_len - 1] = '\0'; + // Fill in PID for '$$' expand_dollar(input, input_size); // Ignore whitespace or comments @@ -47,8 +45,7 @@ int main() { continue; } - - + // Format Line as Array char*** array = malloc(sizeof(char**)); int num_strings = input_format(input, input_size, array); @@ -68,6 +65,7 @@ int main() { } } +// Build the array with each argument out of line int input_format(char* input, size_t input_size, char*** array) { const int max_args = 512; @@ -99,6 +97,7 @@ void inbuilt_cd(char* args) { int run_command(char*** array, int num_array) { + // Point all executables to /usr/bin (bad Idea but it works) char* comb_string = malloc(sizeof(char) * 100); sprintf(comb_string, "/usr/bin/"); strcat(comb_string, (*array)[0]); @@ -131,6 +130,7 @@ int run_command(char*** array, int num_array) { } } + // Make array not have nullspace between non-null values sterilize_array(array, num_array); // Check to see if the process has input redirected @@ -152,17 +152,21 @@ int run_command(char*** array, int num_array) { } } + // Make array not have nullspace between non-null values sterilize_array(array, num_array); + // Forking/Child processes int f = fork(); pid_t pid; if(!f) { + // Handle Redirected output if(redirect_o) { int fd = open(redirect_o_str, O_WRONLY | O_CREAT, 0666); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); } + // Or direct to null if in background else if(background) { int fd = open("/dev/null", O_WRONLY, 0666); //Direct to dev null @@ -170,24 +174,32 @@ int run_command(char*** array, int num_array) { dup2(fd, STDERR_FILENO); } + // Handle Redirected input if(redirect_i) { int fd = open(redirect_i_str, O_RDONLY); dup2(fd, STDIN_FILENO); } + + // Or direct to null if in background else if(background) { int fd = open("/dev/null", O_RDONLY); dup2(fd, STDIN_FILENO); } + // Spawn new Process pid = execv(comb_string, (*array)); + // Handle error on spawning process perror(comb_string); exit(1); } + + // If in background, tell user the pid that was spawned else if(background){ printf("background pid is %d\n", f); } + // Wait on the process if it is running in forground int status; if(!background) waitpid(f, &status, 0); @@ -195,7 +207,6 @@ int run_command(char*** array, int num_array) { free(comb_string); return status; - } @@ -207,14 +218,15 @@ void expand_dollar(char* input, size_t input_size) { char* dollar; + // Check for two '$$'s and exchange them to the pid if they exist dollar = strstr(input, "$$"); while(dollar != NULL) { - dollar[0] = '%'; - dollar[1] = 's'; - sprintf(buffer, input, pid); - strcpy(input, buffer); - dollar = strstr(input, "$$"); + dollar[0] = '%'; + dollar[1] = 's'; + sprintf(buffer, input, pid); + strcpy(input, buffer); + dollar = strstr(input, "$$"); } } @@ -246,7 +258,8 @@ void sterilize_array(char*** array, size_t num_array) { void sigint_handle() { } -void sigstop_handle(int n) { +void sigstop_handle() { + // Negate flags so that it handles both starting and stopping stop_flag = !stop_flag; stop_msg = !stop_msg; } @@ -257,9 +270,14 @@ void clean_children() { int pid = 43110; while(pid >0) { int status; - pid = waitpid(0, &status, WNOHANG); + pid = waitpid(0, &status, WNOHANG | WUNTRACED ); - if(pid > 0) - printf("\nbackground pid %d is done: exit value %d\n", pid, WEXITSTATUS(status)); + // Handle terminated with status or signal + if(pid > 0) { + if(WIFSIGNALED(status)) + printf("\nbackground pid %d is done: terminated with signal %d\n", pid, WTERMSIG(status)); + else + printf("\nbackground pid %d is done: exit value %d\n", pid, WEXITSTATUS(status)); + } } }