diff --git a/hw5/starter/.debug/launch.json b/hw5/starter/.debug/launch.json deleted file mode 100644 index 72e404dc24f1893e3fe252a15d6e112e4807ad4c..0000000000000000000000000000000000000000 --- a/hw5/starter/.debug/launch.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "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 deleted file mode 100644 index 3fb660801e6eae56c837af79541c9eadffc14a0a..0000000000000000000000000000000000000000 --- a/hw5/starter/.debug/tasks.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "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/student_tests.sh b/hw5/starter/bats/student_tests.sh index 81c6d864599a79f7b01b6b82b3996975c6684c17..0cec17d2884de098f1603b3192f3ae3dc9a83b7c 100755 --- a/hw5/starter/bats/student_tests.sh +++ b/hw5/starter/bats/student_tests.sh @@ -13,9 +13,64 @@ EOF [ "$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="dsh3>warning:nocommandsprovideddsh3>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" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "Simple Command" { + current=$(pwd) + cd /tmp + run "${current}/dsh" <<EOF +pwd +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="/tmpdsh3>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 ] +} + @test "Change directory then do ls" { current=$(pwd) cd /tmp + rm -rf student-test mkdir -p student-test cd student-test touch test_file @@ -48,6 +103,7 @@ EOF @test "Change directory" { current=$(pwd) cd /tmp + rm -rf student-test mkdir -p student-test run "${current}/dsh" <<EOF @@ -75,3 +131,455 @@ EOF [ "$status" -eq 0 ] } +@test "It handles quoted spaces" { + run "./dsh" <<EOF + echo "CS 283 fun " +EOF + + # Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '\t\n\r\f\v') + + # Expected output with all whitespace removed for easier matching + expected_output="CS 283 fun dsh3> dsh3> cmd loop returned 0" + + # 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" ] + + [ "$status" -eq 0 ] +} + + +@test "2 commands with pipe" { + 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 ] +} + +@test "3 commands with pipes" { + current=$(pwd) + cd /tmp + rm -r student-test + mkdir -p student-test + cd student-test + touch test_file + cd .. + +run "${current}/dsh" <<EOF +cd student-test | ls | grep test +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="test_filedsh3>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 ] + +} + +@test "try more max (8) commands" { + run ./dsh <<EOF +ls | ls | cd bats | ls | ls | ls | ls | grep dsh_cli.c | 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="dsh_cli.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 ] + +} + +@test "try more than max (8) commands" { + run ./dsh <<EOF +ls | ls | ls | ls | ls | ls | ls | grep dsh_cli.c | 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="dsh_cli.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 ] + +} + +# Didn't find a way to pass this test / not sure we need to implement this way +# @test "echo + some commands" { + +# current=$(pwd) +# cd /tmp +# rm -rf student-test +# mkdir -p student-test + +# run "${current}/dsh" <<EOF +# cd student-test | echo "$(pwd) hello" +# 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="/tmp/student-test hellodsh3>dsh3>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" ] + +# [ "$status" -eq 0 ] +# } + +@test "mv command" { + + rm -f mv_file mv_file_1 + + touch mv_file + +run "./dsh" <<EOF +mv mv_file mv_file_1 +ls | grep mv_file +EOF + +rm -f mv_file_1 + + # 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="mv_file_1dsh3>dsh3>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 "${output}" + echo "${stripped_output} -> ${expected_output}" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "test mkdir command" { + + +run "./dsh" <<EOF +mkdir -p mkdir-test +ls | grep mkdir-test +EOF + +rm -rf mkdir-test + + # 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="mkdir-testdsh3>dsh3>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 "${output}" + echo "${stripped_output} -> ${expected_output}" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] + +} + +@test "test rm command" { + + touch rm_test_file rm_test_file_1 + +run "./dsh" <<EOF +rm rm_test_file +ls | grep rm_test +EOF + +rm -f rm_test_file_1 + + # 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="rm_test_file_1dsh3>dsh3>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 "${output}" + echo "${stripped_output} -> ${expected_output}" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] +} + +@test "test remove file/directory command" { + + rm -rf student-test student-test-1 student-test-2 + mkdir -p student-test student-test-1 student-test-2 + +run "./dsh" <<EOF +rm -r student-test-1 +ls | grep test +EOF + +rm -rf student-test student-test-2 + + # 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="student-teststudent-test-2dsh3>dsh3>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 "${output}" + echo "${stripped_output} -> ${expected_output}" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] +} + +@test "test cat command" { + rm -rf cat.txt + touch cat.txt + echo "This is a test file" >> cat.txt + run ./dsh <<EOF +cat cat.txt +EOF + +rm -rf cat.txt + + # 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="Thisisatestfiledsh3>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 ] + +} + +@test "test cp command" { + + rm -rf cp_dic_1 cp_dic_2 + mkdir cp_dic_1 cp_dic_2 + cd cp_dic_1 + touch cp_file_1 + cd .. + cd cp_dic_2 + touch cp_file_2 + cd .. + +run "./dsh" <<EOF +cp cp_dic_1/cp_file_1 cp_dic_2/ +cd cp_dic_2 +ls | grep cp_file +EOF + +rm -rf cp_dic_1 cp_dic_2 +# 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="cp_file_1cp_file_2dsh3>dsh3>dsh3>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 ] +} + +@test "When having wrong command" { + run ./dsh <<EOF +echo " hello world " | hello +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="dsh3>Wrongcommanddsh3>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 ] + +} + +@test "Multiple wrong commands" { + run ./dsh <<EOF +echo " hello world " | hello | hi | ok +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="dsh3>Wrongcommanddsh3>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 ] + +} + +@test "yes command" { + run ./dsh << EOF +yes "hello world " | head -n 3 +EOF +# Strip all whitespace (spaces, tabs, newlines) from the output + stripped_output=$(echo "$output" | tr -d '\t\n\r\f\v') + + # Expected output with all whitespace removed for easier matching + expected_output="hello world hello world hello world dsh3> dsh3> cmd loop returned 0" + + # 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/dsh b/hw5/starter/dsh index 17eb738db6d41ae14226d5f9b92810ee0ffdfe49..8f75936244cda90cfe61191de587f5fffa167d62 100755 Binary files a/hw5/starter/dsh and b/hw5/starter/dsh differ diff --git a/hw5/starter/dshlib.c b/hw5/starter/dshlib.c index 81d339f8d97a4a7c368ee558e68b0473347590b2..c2801d67e19c11adfff6376db8912bd4a6da0a81 100644 --- a/hw5/starter/dshlib.c +++ b/hw5/starter/dshlib.c @@ -66,6 +66,8 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) pipe = strchr(pointer, PIPE_CHAR); + if (clist->num < CMD_MAX){ + if (pipe==NULL){ build_cmd_buff(pointer, cmd_buff); pointer = pipe; @@ -85,11 +87,16 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) } - if (clist->num < CMD_MAX){ clist->commands[clist->num] = *cmd_buff; + clist->num = clist->num+1; } - clist->num = clist->num+1; + + else { + free(cmd_buff->_cmd_buffer); + free(cmd_buff); + return OK; + } free(cmd_buff->_cmd_buffer); free(cmd_buff); @@ -193,10 +200,14 @@ int execute_pipeline(command_list_t *clist){ continue; }else{ - execvp(clist->commands[i].argv[0], clist->commands[i].argv); - perror("execvp"); + if (execvp(clist->commands[i].argv[0], clist->commands[i].argv)==-1){ + printf("Wrong command"); + exit(ERR_EXEC_CMD); + } + exit(EXIT_FAILURE); } + exit(EXIT_FAILURE); } }