From 033c3c131b27e03b589c1fc815dbaec6274f05ab Mon Sep 17 00:00:00 2001 From: jl4589 <jl4589@tux4.cci.drexel.edu> Date: Tue, 4 Mar 2025 22:31:10 -0500 Subject: [PATCH] Fixed error and made the first assignment_test work --- Assignment-05/starter/dsh | Bin 0 -> 28144 bytes Assignment-05/starter/dshlib.c | 284 ++++++++++++++----------- Assignment-05/starter/dshlib.h | 2 +- Assignment-05/starter/student_tests.sh | 48 ++++- 4 files changed, 203 insertions(+), 131 deletions(-) create mode 100755 Assignment-05/starter/dsh diff --git a/Assignment-05/starter/dsh b/Assignment-05/starter/dsh new file mode 100755 index 0000000000000000000000000000000000000000..d9bbee0f94d14b88ce2b9fb8aeccce18ea7b2709 GIT binary patch literal 28144 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 I7)I9*03Q`_q5uE@ literal 0 HcmV?d00001 diff --git a/Assignment-05/starter/dshlib.c b/Assignment-05/starter/dshlib.c index a21bbe1..cda615e 100644 --- a/Assignment-05/starter/dshlib.c +++ b/Assignment-05/starter/dshlib.c @@ -9,6 +9,16 @@ #include "dshlib.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> +#include <unistd.h> + +#include "dshlib.h" + +// int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) { if (cmd_line == NULL || cmd_buff == NULL) { return ERR_CMD_OR_ARGS_TOO_BIG; @@ -19,175 +29,194 @@ int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) { return ERR_MEMORY; } - char *trimmed_line = original_line; - while (*trimmed_line == ' ') { - trimmed_line++; - } - - size_t len = strlen(trimmed_line); - while (len > 0 && trimmed_line[len - 1] == ' ') { - trimmed_line[--len] = '\0'; - } - cmd_buff->argc = 0; cmd_buff->_cmd_buffer = original_line; - char *saveptr1; - char *token = strtok_r(trimmed_line, " ", &saveptr1); - - while (token != NULL && cmd_buff->argc < CMD_ARGV_MAX) { - if (token[0] == '"' || token[0] == '\'') { - char *end_quote = strchr(token + 1, token[0]); - if (end_quote != NULL) { - *end_quote = '\0'; - cmd_buff->argv[cmd_buff->argc++] = token + 1; - token = strtok_r(NULL, " ", &saveptr1); - continue; + char *ptr = original_line; + char *arg_start = NULL; + bool in_quotes = false;//For quotes + char quote_char = '\0'; + + while (*ptr != '\0') { + if ((isspace((unsigned char)*ptr) && !in_quotes)) { + if (arg_start != NULL) { + *ptr = '\0'; + cmd_buff->argv[cmd_buff->argc++] = arg_start; + arg_start = NULL; + } + } else if (*ptr == '"' || *ptr == '\'') { + if (in_quotes && *ptr == quote_char) { + in_quotes = false; + quote_char = '\0'; + *ptr = '\0'; // End the argument at the closing quote + } else if (!in_quotes) { + in_quotes = true; + quote_char = *ptr; + arg_start = ptr + 1; // Start the argument after the opening quote + } + } else { + if (arg_start == NULL) { + arg_start = ptr; } } - cmd_buff->argv[cmd_buff->argc++] = token; - token = strtok_r(NULL, " ", &saveptr1); + ptr++; } + + if (arg_start != NULL) { + cmd_buff->argv[cmd_buff->argc++] = arg_start; + } + cmd_buff->argv[cmd_buff->argc] = NULL; - return OK; -} + // Debugging output to verify parsing + // printf("Parsed command:\n"); + // for (int i = 0; i < cmd_buff->argc; i++) { + // printf(" argv[%d]: %s\n", i, cmd_buff->argv[i]); + // } -int execute_pipeline(command_list_t *cmd_list) { - int num_commands = cmd_list->num; - int pipefd[2]; - int prev_pipe_read = -1; - pid_t pids[num_commands]; - for (int i = 0; i < num_commands; i++) { - if (i < num_commands - 1) { - if (pipe(pipefd) == -1) { - perror("pipe"); - return ERR_MEMORY; - } - } + return OK; +} - pids[i] = fork(); - if (pids[i] == -1) { - perror("fork"); - return ERR_MEMORY; - } +char *trim_whitespace(char *str) { //Had to make a new function for readability + char *end; - if (pids[i] == 0) { - if (prev_pipe_read != -1) { - dup2(prev_pipe_read, STDIN_FILENO); - close(prev_pipe_read); - } + while (isspace((unsigned char)*str)) str++; - if (i < num_commands - 1) { - dup2(pipefd[1], STDOUT_FILENO); - close(pipefd[1]); - close(pipefd[0]); - } + if (*str == 0) // All spaces? + return str; - if (prev_pipe_read != -1) { - close(prev_pipe_read); - } + // Trim trailing space + end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) end--; - cmd_buff_t *cmd = &cmd_list->commands[i]; + // new null terminator + *(end + 1) = '\0'; - if (cmd->argv[0] == NULL) { - fprintf(stderr, "execvp error: command is NULL\n"); - exit(ERR_EXEC_CMD); - } + return str; +} - execvp(cmd->argv[0], cmd->argv); - perror("execvp"); - exit(ERR_EXEC_CMD); - } else { - if (prev_pipe_read != -1) { - close(prev_pipe_read); - } - if (i < num_commands - 1) { - prev_pipe_read = pipefd[0]; - close(pipefd[1]); - } - } + +int parse_pipeline(const char *cmd_line, command_list_t *clist) { + if (cmd_line == NULL || clist == NULL) { + return ERR_CMD_OR_ARGS_TOO_BIG; } - if (prev_pipe_read != -1) { - char buffer[1024]; - ssize_t bytes_read; - while ((bytes_read = read(prev_pipe_read, buffer, sizeof(buffer) - 1)) > 0) { - buffer[bytes_read] = '\0'; - printf("%s", buffer); + char *line_copy = strdup(cmd_line); + if (line_copy == NULL) { + return ERR_MEMORY; + } + //Parsing using pipe. + clist->num = 0; + char *saveptr; + char *command = strtok_r(line_copy, "|", &saveptr); + + while (command != NULL) { + if (clist->num >= CMD_MAX) { + free(line_copy); + return ERR_TOO_MANY_COMMANDS; } - if (bytes_read < 0) { - perror("read"); + + cmd_buff_t *cmd_buff = &clist->commands[clist->num]; + int result = build_cmd_buff(command, cmd_buff); + if (result != OK) { + free(line_copy); + return result; } - close(prev_pipe_read); - } - for (int i = 0; i < num_commands; i++) { - waitpid(pids[i], NULL, 0); + clist->num++; + command = strtok_r(NULL, "|", &saveptr); } + free(line_copy); return OK; } +int execute_pipeline(command_list_t *clist) { + int num_commands = clist->num; + int pipefd[2 * (num_commands - 1)]; + pid_t pids[num_commands]; + + // for (int i = 0; i < clist->num; i++) { + // printf("Command %d:\n", i); + // for (int j = 0; clist->commands[i].argv[j] != NULL; j++) { + // printf(" argv[%d]: %s\n", j, clist->commands[i].argv[j]); + // } + // } -int parse_pipeline(char *cmd_line, command_list_t *clist) { - if (cmd_line == NULL || clist == NULL) { - return ERR_CMD_OR_ARGS_TOO_BIG; - } - char *original_line = strdup(cmd_line); - if (original_line == NULL) { - return ERR_MEMORY; - } - char *trimmed_line = original_line; - while (*trimmed_line == ' ') { - trimmed_line++; - } - size_t len = strlen(trimmed_line); - while (len > 0 && trimmed_line[len - 1] == ' ') { - trimmed_line[--len] = '\0'; + for (int i = 0; i < num_commands - 1; i++) { + if (pipe(pipefd + 2 * i) == -1) { + perror("pipe"); + return ERR_MEMORY; + } } - int command_count = 0; - char *saveptr1, *saveptr2; - char *command = strtok_r(trimmed_line, PIPE_STRING, &saveptr1); + // Fork processes for each command + for (int i = 0; i < num_commands; i++) { + pids[i] = fork(); + if (pids[i] == -1) { + perror("fork"); + return ERR_MEMORY; + } + + if (pids[i] == 0) { // Child process + // if not first moves input + if (i > 0) { + if (dup2(pipefd[2 * (i - 1)], STDIN_FILENO) == -1) { + perror("dup2 stdin"); + exit(EXIT_FAILURE); + } + } - while (command != NULL && command_count < CMD_MAX) { - memset(&clist->commands[command_count], 0, sizeof(cmd_buff_t)); + // Redirect output if not the last command + if (i < num_commands - 1) { + if (dup2(pipefd[2 * i + 1], STDOUT_FILENO) == -1) { + perror("dup2 stdout"); + exit(EXIT_FAILURE); + } + } - char *token = strtok_r(command, " ", &saveptr2); - if (token != NULL) { - int arg_count = 0; - while (token != NULL && arg_count < CMD_ARGV_MAX - 1) { - clist->commands[command_count].argv[arg_count] = token; - arg_count++; - token = strtok_r(NULL, " ", &saveptr2); + // Close all pipe file descriptors. Very important stuff + for (int j = 0; j < 2 * (num_commands - 1); j++) { + close(pipefd[j]); } - clist->commands[command_count].argv[arg_count] = NULL; + + // Execute the command + execvp(clist->commands[i].argv[0], clist->commands[i].argv); + perror("execvp"); + exit(EXIT_FAILURE); } + } - command_count++; - command = strtok_r(NULL, PIPE_STRING, &saveptr1); + // Closes all pipe + for (int i = 0; i < 2 * (num_commands - 1); i++) { + close(pipefd[i]); } - if (command != NULL) { - free(original_line); - return ERR_TOO_MANY_COMMANDS; + // waitpid so everyhting is smooth + for (int i = 0; i < num_commands; i++) { + int status; + waitpid(pids[i], &status, 0); + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { + fprintf(stderr, "Command %d exited with status %d\n", i, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + fprintf(stderr, "Command %d terminated by signal %d\n", i, WTERMSIG(status)); + } } - clist->num = command_count; - free(original_line); return OK; } + + int exec_local_cmd_loop() { char cmd_buff[SH_CMD_MAX]; int rc = OK; @@ -197,7 +226,7 @@ int exec_local_cmd_loop() { if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) { printf("\n"); - break; + break; } cmd_buff[strcspn(cmd_buff, "\n")] = '\0'; @@ -216,11 +245,11 @@ int exec_local_cmd_loop() { continue; } - if (execute_pipeline(&cmd_list) != OK) { - fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT); - rc = ERR_MEMORY; - } + // Execute the pipeline + + execute_pipeline(&cmd_list); + // Free memory for each command's buffer for (int i = 0; i < cmd_list.num; i++) { free(cmd_list.commands[i]._cmd_buffer); } @@ -233,8 +262,8 @@ int exec_local_cmd_loop() { } if (strcmp(cmd.argv[0], EXIT_CMD) == 0) { - free(cmd._cmd_buffer); - break; + free(cmd._cmd_buffer); + break; } if (strcmp(cmd.argv[0], "cd") == 0) { @@ -258,7 +287,7 @@ int exec_local_cmd_loop() { } else if (pid == 0) { execvp(cmd.argv[0], cmd.argv); perror("execvp failed"); - exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } else { int status; wait(&status); @@ -276,3 +305,4 @@ int exec_local_cmd_loop() { return rc; } + diff --git a/Assignment-05/starter/dshlib.h b/Assignment-05/starter/dshlib.h index fe3b246..0f949dc 100644 --- a/Assignment-05/starter/dshlib.h +++ b/Assignment-05/starter/dshlib.h @@ -90,4 +90,4 @@ int execute_pipeline(command_list_t *clist); #define CMD_WARN_NO_CMD "warning: no commands provided\n" #define CMD_ERR_PIPE_LIMIT "error: piping limited to %d commands\n" -#endif \ No newline at end of file +#endif diff --git a/Assignment-05/starter/student_tests.sh b/Assignment-05/starter/student_tests.sh index 638bc34..6047b4a 100644 --- a/Assignment-05/starter/student_tests.sh +++ b/Assignment-05/starter/student_tests.sh @@ -4,11 +4,53 @@ # # Create your unit tests suit in this file -@test "Example: check ls runs without errors" { - run ./dsh <<EOF -ls + +# Test pipeline: 'echo' output piped to 'grep' +@test "Test echo output piped to grep" { + run ./dsh <<EOF +echo "Hello World" | grep "World" +exit +EOF + + # Assertions + [ "$status" -eq 0 ] + [[ "$output" == *"Hello World"* ]] +} + +# Test pipeline with multiple commands: 'ls' piped to 'grep' and then to 'wc -l' +@test "Test ls piped to grep and wc -l" { + run ./dsh <<EOF +ls | grep "student_tests.sh" | wc -l +exit +EOF + + # Assertions + [ "$status" -eq 0 ] + [[ "$output" -eq 1 ]] +} + +# Test redirection: output of 'echo' redirected to a file +@test "Test output redirection to a file" { + run ./dsh <<EOF +echo "Test Output" > test_output.txt +cat test_output.txt +exit +EOF + + # Assertions + [ "$status" -eq 0 ] + [[ "$output" == *"Test Output"* ]] +} + +# Test background execution: 'sleep' command in the background +@test "Test background execution of sleep command" { + run ./dsh <<EOF +sleep 2 & +jobs +exit EOF # Assertions [ "$status" -eq 0 ] + [[ "$output" == *"sleep 2 &"* ]] } -- GitLab