From 5258d376cd576c5d0bd3592947c696dbcbc703ef Mon Sep 17 00:00:00 2001
From: dt686 <dt686@tux4.cci.drexel.edu>
Date: Tue, 4 Mar 2025 23:44:05 -0500
Subject: [PATCH] HW5
---
hw5/starter/.debug/launch.json | 29 +++
hw5/starter/.debug/tasks.json | 20 +++
hw5/starter/bats/assignment_tests.sh | 36 ++++
hw5/starter/bats/student_tests.sh | 14 ++
hw5/starter/dsh | Bin 0 -> 22816 bytes
hw5/starter/dsh_cli.c | 13 ++
hw5/starter/dshlib.c | 258 +++++++++++++++++++++++++++
hw5/starter/dshlib.h | 93 ++++++++++
hw5/starter/makefile | 31 ++++
9 files changed, 494 insertions(+)
create mode 100644 hw5/starter/.debug/launch.json
create mode 100644 hw5/starter/.debug/tasks.json
create mode 100755 hw5/starter/bats/assignment_tests.sh
create mode 100755 hw5/starter/bats/student_tests.sh
create mode 100755 hw5/starter/dsh
create mode 100644 hw5/starter/dsh_cli.c
create mode 100644 hw5/starter/dshlib.c
create mode 100644 hw5/starter/dshlib.h
create mode 100644 hw5/starter/makefile
diff --git a/hw5/starter/.debug/launch.json b/hw5/starter/.debug/launch.json
new file mode 100644
index 0000000..72e404d
--- /dev/null
+++ b/hw5/starter/.debug/launch.json
@@ -0,0 +1,29 @@
+{
+ "configurations": [
+ {
+ "name": "(gdb) 5-ShellP3",
+ "type": "cppdbg",
+ "request": "launch",
+ "program": "${workspaceFolder}/5-ShellP3/starter/dsh",
+ "args": [""],
+ "stopAtEntry": false,
+ "cwd": "${workspaceFolder}/5-ShellP3/starter",
+ "environment": [],
+ "externalConsole": false,
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ },
+ {
+ "description": "Set Disassembly Flavor to Intel",
+ "text": "-gdb-set disassembly-flavor intel",
+ "ignoreFailures": true
+ }
+ ],
+ "preLaunchTask": "Build 5-ShellP3"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/hw5/starter/.debug/tasks.json b/hw5/starter/.debug/tasks.json
new file mode 100644
index 0000000..3fb6608
--- /dev/null
+++ b/hw5/starter/.debug/tasks.json
@@ -0,0 +1,20 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build 5-ShellP3",
+ "type": "shell",
+ "command": "make",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "options": {
+ "cwd": "${workspaceFolder}/5-ShellP3/starter"
+ },
+ "problemMatcher": ["$gcc"],
+ "detail": "Runs the 'make' command to build the project."
+ }
+ ]
+ }
+
\ No newline at end of file
diff --git a/hw5/starter/bats/assignment_tests.sh b/hw5/starter/bats/assignment_tests.sh
new file mode 100755
index 0000000..ac34560
--- /dev/null
+++ b/hw5/starter/bats/assignment_tests.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env bats
+
+############################ DO NOT EDIT THIS FILE #####################################
+# File: assignement_tests.sh
+#
+# DO NOT EDIT THIS FILE
+#
+# Add/Edit Student tests in student_tests.sh
+#
+# All tests in this file must pass - it is used as part of grading!
+########################################################################################
+
+@test "Pipes" {
+ run "./dsh" <<EOF
+ls | grep dshlib.c
+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="dshlib.cdsh3>dsh3>cmdloopreturned0"
+
+ # 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"
+ echo "${stripped_output} -> ${expected_output}"
+
+ # Check exact match
+ [ "$stripped_output" = "$expected_output" ]
+
+ # Assertions
+ [ "$status" -eq 0 ]
+}
diff --git a/hw5/starter/bats/student_tests.sh b/hw5/starter/bats/student_tests.sh
new file mode 100755
index 0000000..638bc34
--- /dev/null
+++ b/hw5/starter/bats/student_tests.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bats
+
+# File: student_tests.sh
+#
+# Create your unit tests suit in this file
+
+@test "Example: check ls runs without errors" {
+ run ./dsh <<EOF
+ls
+EOF
+
+ # Assertions
+ [ "$status" -eq 0 ]
+}
diff --git a/hw5/starter/dsh b/hw5/starter/dsh
new file mode 100755
index 0000000000000000000000000000000000000000..dc37ffbfde3fa167970a552639af5b08334ee4ea
GIT binary patch
literal 22816
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⪼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
IBpR0i0Iq*Ql>h($
literal 0
HcmV?d00001
diff --git a/hw5/starter/dsh_cli.c b/hw5/starter/dsh_cli.c
new file mode 100644
index 0000000..9262cf4
--- /dev/null
+++ b/hw5/starter/dsh_cli.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dshlib.h"
+
+/* DO NOT EDIT
+ * main() logic moved to exec_local_cmd_loop() in dshlib.c
+*/
+int main(){
+ int rc = exec_local_cmd_loop();
+ printf("cmd loop returned %d\n", rc);
+}
\ No newline at end of file
diff --git a/hw5/starter/dshlib.c b/hw5/starter/dshlib.c
new file mode 100644
index 0000000..f689daa
--- /dev/null
+++ b/hw5/starter/dshlib.c
@@ -0,0 +1,258 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+
+#include "dshlib.h"
+
+/*
+ * Implement your exec_local_cmd_loop 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.
+ *
+ * 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
+ * ERR_MEMORY dynamic memory management failure
+ *
+ * errors returned
+ * OK No error
+ * ERR_MEMORY Dynamic memory management failure
+ * WARN_NO_CMDS No commands parsed
+ * ERR_TOO_MANY_COMMANDS too many pipes used
+ *
+ * console messages
+ * CMD_WARN_NO_CMD print on WARN_NO_CMDS
+ * CMD_ERR_PIPE_LIMIT print on ERR_TOO_MANY_COMMANDS
+ * CMD_ERR_EXECUTE print on execution failure of external command
+ *
+ * Standard Library Functions You Might Want To Consider Using (assignment 1+)
+ * malloc(), free(), strlen(), fgets(), strcspn(), printf()
+ *
+ * Standard Library Functions You Might Want To Consider Using (assignment 2+)
+ * fork(), execvp(), exit(), chdir()
+ */
+
+int build_cmd_list(char *cmd_line, command_list_t *clist)
+{
+ char *pointer = cmd_line;
+ char* pipe = strchr(pointer, PIPE_CHAR);
+
+ clist->num = 0;
+
+ while(pointer != NULL){
+ cmd_buff_t *cmd_buff = malloc(sizeof(cmd_buff_t));
+ cmd_buff->_cmd_buffer = malloc(SH_CMD_MAX);
+
+ pipe = strchr(pointer, PIPE_CHAR);
+
+ if (pipe==NULL){
+ build_cmd_buff(pointer, cmd_buff);
+ pointer = pipe;
+
+ } else{
+ size_t sub_length = pipe - pointer;
+
+ char *sub_string = malloc(sub_length + 1);
+
+ strncpy(sub_string, pointer, sub_length);
+ sub_string[sub_length] = '\0';
+
+ build_cmd_buff(sub_string, cmd_buff);
+ free(sub_string);
+
+ pointer = pipe + 1;
+
+ }
+
+ if (clist->num < CMD_MAX){
+ clist->commands[clist->num] = *cmd_buff;
+
+ }
+ clist->num = clist->num+1;
+
+ free(cmd_buff->_cmd_buffer);
+ free(cmd_buff);
+
+ }
+
+ return OK;
+}
+
+int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff){
+ char *pointer = cmd_line;
+ while (*pointer == ' '){
+ pointer++;
+ }
+ char *space;
+ cmd_buff->argc = 0;
+ int count = 0;
+ char *org = pointer;
+
+ while (pointer!=NULL){
+ if (*pointer=='\"'){
+ pointer++;
+ org = pointer;
+ while(*pointer!='\"'){
+ pointer++;
+ }
+ space = pointer;
+ pointer++;
+
+ } else{
+ space = strchr(pointer, SPACE_CHAR);
+ if (space==NULL){
+ size_t exe_length = strlen(pointer);
+ cmd_buff->argv[count] = malloc(exe_length + 1);
+ strncpy(cmd_buff->argv[count], org, exe_length);
+ cmd_buff->argv[count][exe_length] = '\0';
+ if (strcmp(cmd_buff->argv[count],"") != 0){
+ count++;
+ cmd_buff->argc++;
+ }
+ pointer = space;
+ continue;
+ }
+ }
+
+ size_t exe_length = space - org;
+ cmd_buff->argv[count] = malloc(exe_length + 1);
+ strncpy(cmd_buff->argv[count], org, exe_length);
+ cmd_buff->argv[count][exe_length] = '\0';
+ count++;
+ cmd_buff->argc++;
+ pointer = space+1;
+ org = pointer;
+ }
+
+ cmd_buff->argv[cmd_buff->argc] = NULL;
+ return 0;
+}
+
+// Modify from the sample code that the professor provided
+int execute_pipeline(command_list_t *clist){
+
+ int pipes[clist->num - 1][2]; // Array of pipes
+ pid_t pids[clist->num]; // Array to store process IDs
+
+ // Create all necessary pipes
+ for (int i = 0; i < clist->num-1; i++) {
+ if (pipe(pipes[i]) == -1) {
+ perror("pipe");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ // Create processes for each command
+ for (int i = 0; i < clist->num; i++) {
+ pids[i] = fork();
+ if (pids[i] == -1) {
+ perror("fork");
+ exit(EXIT_FAILURE);
+ }
+
+ if (pids[i] == 0) { // Child process
+ // Set up input pipe for all except first process
+ if (i > 0) {
+ dup2(pipes[i-1][0], STDIN_FILENO);
+ }
+
+ // Set up output pipe for all except last process
+ if (i < clist->num - 1) {
+ dup2(pipes[i][1], STDOUT_FILENO);
+ }
+
+ // Close all pipe ends in child
+ for (int j = 0; j < clist->num - 1; j++) {
+ close(pipes[j][0]);
+ close(pipes[j][1]);
+ }
+
+ // Execute command
+ execvp(clist->commands[i].argv[0], clist->commands[i].argv);
+ perror("execvp");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ // Parent process: close all pipe ends
+ for (int i = 0; i < clist->num - 1; i++) {
+ close(pipes[i][0]);
+ close(pipes[i][1]);
+ }
+
+ // Wait for all children
+ for (int i = 0; i < clist->num; i++) {
+ waitpid(pids[i], NULL, 0);
+ }
+
+ exit(OK);
+
+ // return OK;
+
+}
+
+
+int exec_local_cmd_loop()
+{
+ char *cmd_buff = malloc(SH_CMD_MAX);
+ cmd_buff_t *cmd = malloc(sizeof(cmd_buff_t));
+ cmd->_cmd_buffer = malloc(SH_CMD_MAX);
+ command_list_t clist;
+
+ // TODO IMPLEMENT MAIN LOOP
+ while(1){
+
+ if (fgets(cmd_buff, ARG_MAX, stdin) == NULL){
+ printf("\n");
+ break;
+ }
+ printf("%s", SH_PROMPT);
+ //remove the trailing \n from cmd_buff
+ cmd_buff[strcspn(cmd_buff,"\n")] = '\0';
+
+ if (cmd_buff[0] == '\0'){
+ printf(CMD_WARN_NO_CMD);
+ continue;
+ }
+
+ if (strcmp(cmd_buff, EXIT_CMD) == 0){
+ break;
+ }
+ build_cmd_list(cmd_buff, &clist);
+
+ int supervisor = fork();
+ if (supervisor == 0) {
+ execute_pipeline(&clist); // Supervisor process
+ }
+ if (supervisor == -1) {
+ perror("fork supervisor");
+ exit(EXIT_FAILURE);
+ }
+
+ waitpid(supervisor, NULL, 0);
+
+ }
+
+ return OK;
+}
diff --git a/hw5/starter/dshlib.h b/hw5/starter/dshlib.h
new file mode 100644
index 0000000..fe3b246
--- /dev/null
+++ b/hw5/starter/dshlib.h
@@ -0,0 +1,93 @@
+#ifndef __DSHLIB_H__
+ #define __DSHLIB_H__
+
+
+//Constants for command structure sizes
+#define EXE_MAX 64
+#define ARG_MAX 256
+#define CMD_MAX 8
+#define CMD_ARGV_MAX (CMD_MAX + 1)
+// 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 cmd_buff
+{
+ int argc;
+ char *argv[CMD_ARGV_MAX];
+ char *_cmd_buffer;
+} cmd_buff_t;
+
+/* WIP - Move to next assignment
+#define N_ARG_MAX 15 //MAX number of args for a command
+typedef struct command{
+ char exe [EXE_MAX];
+ char args[ARG_MAX];
+ int argc;
+ char *argv[N_ARG_MAX + 1]; //last argv[LAST] must be \0
+}command_t;
+*/
+
+typedef struct command_list{
+ int num;
+ cmd_buff_t commands[CMD_MAX];
+}command_list_t;
+
+//Special character #defines
+#define SPACE_CHAR ' '
+#define PIPE_CHAR '|'
+#define PIPE_STRING "|"
+
+#define SH_PROMPT "dsh3> "
+#define EXIT_CMD "exit"
+#define EXIT_SC 99
+
+//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
+#define ERR_CMD_ARGS_BAD -4 //for extra credit
+#define ERR_MEMORY -5
+#define ERR_EXEC_CMD -6
+#define OK_EXIT -7
+
+//prototypes
+int alloc_cmd_buff(cmd_buff_t *cmd_buff);
+int free_cmd_buff(cmd_buff_t *cmd_buff);
+int clear_cmd_buff(cmd_buff_t *cmd_buff);
+int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff);
+int close_cmd_buff(cmd_buff_t *cmd_buff);
+int build_cmd_list(char *cmd_line, command_list_t *clist);
+int free_cmd_list(command_list_t *cmd_lst);
+
+//built in command stuff
+typedef enum {
+ BI_CMD_EXIT,
+ BI_CMD_DRAGON,
+ BI_CMD_CD,
+ BI_NOT_BI,
+ BI_EXECUTED,
+} Built_In_Cmds;
+Built_In_Cmds match_command(const char *input);
+Built_In_Cmds exec_built_in_cmd(cmd_buff_t *cmd);
+
+//main execution context
+int exec_local_cmd_loop();
+int exec_cmd(cmd_buff_t *cmd);
+int execute_pipeline(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
\ No newline at end of file
diff --git a/hw5/starter/makefile b/hw5/starter/makefile
new file mode 100644
index 0000000..b14b072
--- /dev/null
+++ b/hw5/starter/makefile
@@ -0,0 +1,31 @@
+# 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:
+ bats $(wildcard ./bats/*.sh)
+
+valgrind:
+ echo "pwd\nexit" | valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 ./$(TARGET)
+ echo "pwd\nexit" | valgrind --tool=helgrind --error-exitcode=1 ./$(TARGET)
+
+# Phony targets
+.PHONY: all clean test
\ No newline at end of file
--
GitLab