From 91196bcd9705dec2cef878c683b42db5486f5abd Mon Sep 17 00:00:00 2001 From: cxb23 <cxb23@tux2.cci.drexel.edu> Date: Tue, 11 Feb 2025 22:52:03 -0500 Subject: [PATCH] finished assignment 3-SHellP1 --- 3-ShellP1/.dsh_cli.c.swp | Bin 0 -> 12288 bytes 3-ShellP1/dsh | Bin 0 -> 21704 bytes 3-ShellP1/dsh_cli.c | 107 ++++++++++++++++++++ 3-ShellP1/dshlib.c | 94 +++++++++++++++++ 3-ShellP1/dshlib.h | 51 ++++++++++ 3-ShellP1/makefile | 27 +++++ 3-ShellP1/test.sh | 212 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 491 insertions(+) create mode 100644 3-ShellP1/.dsh_cli.c.swp create mode 100755 3-ShellP1/dsh create mode 100644 3-ShellP1/dsh_cli.c create mode 100644 3-ShellP1/dshlib.c create mode 100644 3-ShellP1/dshlib.h create mode 100644 3-ShellP1/makefile create mode 100644 3-ShellP1/test.sh diff --git a/3-ShellP1/.dsh_cli.c.swp b/3-ShellP1/.dsh_cli.c.swp new file mode 100644 index 0000000000000000000000000000000000000000..bd2da2d883ffa99b5f61bda6b50285fee38b2780 GIT binary patch literal 12288 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 InGaG10RH^Apa1{> literal 0 HcmV?d00001 diff --git a/3-ShellP1/dsh b/3-ShellP1/dsh new file mode 100755 index 0000000000000000000000000000000000000000..4439dfcd727ea2321e58bd7d1b48782c488683a7 GIT binary patch literal 21704 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 adm%i~*a7GiH5d;;OL;-qS!f#2xC{W}eCV72 literal 0 HcmV?d00001 diff --git a/3-ShellP1/dsh_cli.c b/3-ShellP1/dsh_cli.c new file mode 100644 index 0000000..e5a80e9 --- /dev/null +++ b/3-ShellP1/dsh_cli.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dshlib.h" + +void printDragon() { + printf("[DRAGON for extra credit would print here]\n"); +} + +/* + * Implement your main function by building a loop that prompts the + * user for input. Use the SH_PROMPT constant from dshlib.h and then + * use fgets to accept user input. Since we want fgets to also handle + * end of file so we can run this headless for testing we need to check + * the return code of fgets. I have provided an example below of how + * to do this assuming you are storing user input inside of the cmd_buff + * variable. + * + * while(1){ + * printf("%s", SH_PROMPT); + * if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){ + * printf("\n"); + * break; + * } + * //remove the trailing \n from cmd_buff + * cmd_buff[strcspn(cmd_buff,"\n")] = '\0'; + * + * //IMPLEMENT THE REST OF THE REQUIREMENTS + * } + * + * Also, use the constants in the dshlib.h in this code. + * SH_CMD_MAX maximum buffer size for user input + * EXIT_CMD constant that terminates the dsh program + * SH_PROMPT the shell prompt + * OK the command was parsed properly + * WARN_NO_CMDS the user command was empty + * ERR_TOO_MANY_COMMANDS too many pipes used + * + * Expected output: + * + * CMD_OK_HEADER if the command parses properly. You will + * follow this by the command details + * + * CMD_WARN_NO_CMD if the user entered a blank command + * CMD_ERR_PIPE_LIMIT if the user entered too many commands using + * the pipe feature, e.g., cmd1 | cmd2 | ... | + * + * See the provided test cases for output expectations. + */ +int main() +{ + char *cmd_buff = malloc(ARG_MAX * sizeof(char)); + int rc = OK; + command_list_t *clist = malloc(sizeof(command_list_t)); + clist->num = 0; + + while (1) + { + printf("%s", SH_PROMPT); + if (fgets(cmd_buff, ARG_MAX, stdin) == NULL) + { + printf("\n"); + break; + } + // remove the trailing \n from cmd_buff + cmd_buff[strcspn(cmd_buff, "\n")] = '\0'; + + // IMPLEMENT THE REST OF THE REQUIREMENTS + if (strcmp(cmd_buff, EXIT_CMD) == 0) { + exit(rc); + } + + if (strcmp(cmd_buff, "dragon") == 0) { + printDragon(); + continue; + } + + if (strcmp(cmd_buff, "\0") == 0) { + rc = WARN_NO_CMDS; + printf(CMD_WARN_NO_CMD); + continue; + } + + rc = build_cmd_list(cmd_buff, clist); + + if (rc == ERR_TOO_MANY_COMMANDS) { + printf(CMD_ERR_PIPE_LIMIT, CMD_MAX); + continue; + } + + printf(CMD_OK_HEADER, clist->num); + + for (int i = 0; i < clist->num; i++) { + if (strlen(clist->commands[i].args) > 0) { + printf("<%d> %s [%s]\n", i + 1, clist->commands[i].exe, clist->commands[i].args); + } else { + printf("<%d> %s\n", i + 1, clist->commands[i].exe); + } + } + } + + free(cmd_buff); + free(clist); + return rc; +} + diff --git a/3-ShellP1/dshlib.c b/3-ShellP1/dshlib.c new file mode 100644 index 0000000..4e3f473 --- /dev/null +++ b/3-ShellP1/dshlib.c @@ -0,0 +1,94 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "dshlib.h" + +int numInstanceOf(char *str, const char c) { + int count = 0; + while (*str != '\0') { + if (*str == c) count++; + str++; + } + + return count; +} + +/* + * build_cmd_list + * cmd_line: the command line from the user + * clist *: pointer to clist structure to be populated + * + * This function builds the command_list_t structure passed by the caller + * It does this by first splitting the cmd_line into commands by spltting + * the string based on any pipe characters '|'. It then traverses each + * command. For each command (a substring of cmd_line), it then parses + * that command by taking the first token as the executable name, and + * then the remaining tokens as the arguments. + * + * NOTE your implementation should be able to handle properly removing + * leading and trailing spaces! + * + * errors returned: + * + * OK: No Error + * ERR_TOO_MANY_COMMANDS: There is a limit of CMD_MAX (see dshlib.h) +strcat(command.args, inner_token); * commands. + * ERR_CMD_OR_ARGS_TOO_BIG: One of the commands provided by the user + * was larger than allowed, either the + * executable name, or the arg string. + * + * Standard Library Functions You Might Want To Consider Using + * memset(), strcmp(), strcpy(), strtok(), strlen(), strchr() + */ +int build_cmd_list(char *cmd_line, command_list_t *clist) +{ + if (numInstanceOf(cmd_line, PIPE_CHAR) > CMD_MAX-1) return ERR_TOO_MANY_COMMANDS; + + if ((int)strlen(cmd_line) > SH_CMD_MAX) return ERR_CMD_OR_ARGS_TOO_BIG; + + clist->num = 0; + + char *outer_saveptr = NULL; + char *inner_saveptr = NULL; + char *outer_token = strtok_r(cmd_line, PIPE_STRING, &outer_saveptr); + + while (outer_token != NULL) { + if (clist->num > CMD_MAX) return ERR_TOO_MANY_COMMANDS; + + command_t command; + memset(&command, 0, sizeof(command_t)); + + + + char *inner_token = strtok_r(outer_token, SPACE_STRING, &inner_saveptr); + + if (inner_token == NULL) { + outer_token = strtok_r(NULL, PIPE_STRING, &outer_saveptr); + continue; + } + + if (strlen(inner_token) > EXE_MAX) return ERR_CMD_OR_ARGS_TOO_BIG; + + strcpy(command.exe, inner_token); + command.args[0] = '\0'; + + inner_token = strtok_r(NULL, SPACE_STRING, &inner_saveptr); + while (inner_token != NULL) { + if (strlen(command.args) + strlen(inner_token) + 1 > ARG_MAX) return ERR_CMD_OR_ARGS_TOO_BIG; + + if (strlen(command.args) > 0) strcat(command.args, SPACE_STRING); + strcat(command.args, inner_token); + + inner_token = strtok_r(NULL, SPACE_STRING, &inner_saveptr); + } + + clist->commands[clist->num] = command; + clist->num++; + + outer_token = strtok_r(NULL, PIPE_STRING, &outer_saveptr); + } + + return OK; +} diff --git a/3-ShellP1/dshlib.h b/3-ShellP1/dshlib.h new file mode 100644 index 0000000..d0dfe14 --- /dev/null +++ b/3-ShellP1/dshlib.h @@ -0,0 +1,51 @@ +#ifndef __DSHLIB_H__ +#define __DSHLIB_H__ + +// Constants for command structure sizes +#define EXE_MAX 64 +#define ARG_MAX 256 +#define CMD_MAX 8 +// Longest command that can be read from the shell +#define SH_CMD_MAX EXE_MAX + ARG_MAX + +typedef struct command +{ + char exe[EXE_MAX]; + char args[ARG_MAX]; +} command_t; + +typedef struct command_list +{ + int num; + command_t commands[CMD_MAX]; +} command_list_t; + +// Special character #defines +#define SPACE_CHAR ' ' +#define SPACE_STRING " " +#define PIPE_CHAR '|' +#define PIPE_STRING "|" + +#define SH_PROMPT "dsh> " +#define EXIT_CMD "exit" + +// Standard Return Codes +#define OK 0 +#define WARN_NO_CMDS -1 +#define ERR_TOO_MANY_COMMANDS -2 +#define ERR_CMD_OR_ARGS_TOO_BIG -3 + +// starter code +#define M_NOT_IMPL "The requested operation is not implemented yet!\n" +#define EXIT_NOT_IMPL 3 +#define NOT_IMPLEMENTED_YET 0 + +// prototypes +int build_cmd_list(char *cmd_line, command_list_t *clist); + +// output constants +#define CMD_OK_HEADER "PARSED COMMAND LINE - TOTAL COMMANDS %d\n" +#define CMD_WARN_NO_CMD "warning: no commands provided\n" +#define CMD_ERR_PIPE_LIMIT "error: piping limited to %d commands\n" + +#endif diff --git a/3-ShellP1/makefile b/3-ShellP1/makefile new file mode 100644 index 0000000..d61ca77 --- /dev/null +++ b/3-ShellP1/makefile @@ -0,0 +1,27 @@ +# Compiler settings +CC = gcc +CFLAGS = -Wall -Wextra -g + +# Target executable name +TARGET = dsh + +# Find all source and header files +SRCS = $(wildcard *.c) +HDRS = $(wildcard *.h) + +# Default target +all: $(TARGET) + +# Compile source to executable +$(TARGET): $(SRCS) $(HDRS) + $(CC) $(CFLAGS) -o $(TARGET) $(SRCS) + +# Clean up build files +clean: + rm -f $(TARGET) + +test: + ./test.sh + +# Phony targets +.PHONY: all clean diff --git a/3-ShellP1/test.sh b/3-ShellP1/test.sh new file mode 100644 index 0000000..676c62b --- /dev/null +++ b/3-ShellP1/test.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bats + +@test "Simple Command" { + run ./dsh <<EOF +test_command +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>test_commanddsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "Simple Command with Args" { + run ./dsh <<EOF +cmd -a1 -a2 +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd[-a1-a2]dsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + + +@test "No command provided" { + run ./dsh <<EOF + +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>warning:nocommandsprovideddsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "Two commands" { + run ./dsh <<EOF +command_one | command_two +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>command_one<2>command_twodsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "three commands with args" { + run ./dsh <<EOF +cmd1 a1 a2 a3 | cmd2 a4 a5 a6 | cmd3 a7 a8 a9 +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS3<1>cmd1[a1a2a3]<2>cmd2[a4a5a6]<3>cmd3[a7a8a9]dsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "try max (8) commands" { + run ./dsh <<EOF +cmd1 | cmd2 | cmd3 | cmd4 | cmd5 | cmd6 | cmd7 | cmd8 +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS8<1>cmd1<2>cmd2<3>cmd3<4>cmd4<5>cmd5<6>cmd6<7>cmd7<8>cmd8dsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "try too many commands" { + run ./dsh <<EOF +cmd1 | cmd2 | cmd3 | cmd4 | cmd5 | cmd6 | cmd7 | cmd8 | cmd9 +exit +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>error:pipinglimitedto8commandsdsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "kitchen sink - multiple commands" { + run ./dsh <<EOF +cmd1 +cmd2 arg arg2 +p1 | p2 +p3 p3a1 p3a2 | p4 p4a1 p4a2 +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '[:space:]') + + # Expected output with all whitespace removed for easier matching + expected_output="dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd1dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS1<1>cmd2[argarg2]dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>p1<2>p2dsh>PARSEDCOMMANDLINE-TOTALCOMMANDS2<1>p3[p3a1p3a2]<2>p4[p4a1p4a2]dsh>" + + # These echo commands will help with debugging and will only print + #if the test fails + echo "Captured stdout:" + echo "Output: $output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} -- GitLab