diff --git a/hw4/starter/bats/student_tests.sh b/hw4/starter/bats/student_tests.sh
index 638bc341446f7580a80c2aff52971b8023407ea8..f9e0212ba36ac3fe32fc67f2a09d54b462310c8f 100755
--- a/hw4/starter/bats/student_tests.sh
+++ b/hw4/starter/bats/student_tests.sh
@@ -12,3 +12,251 @@ EOF
# Assertions
[ "$status" -eq 0 ]
}
+
+@test "Change directory" {
+ current=$(pwd)
+ cd /tmp
+ mkdir -p student-test
+
+ run "${current}/dsh" <<EOF
+cd student-test
+pwd
+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-testdsh2>dsh2>dsh2>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 with no argument" {
+ current=$(pwd)
+ cd /tmp
+ run "${current}/dsh" <<EOF
+cd
+pwd
+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="/tmpdsh2>dsh2>dsh2>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 "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="dsh2>warning:nocommandsprovideddsh2>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 "Too many arguments for cd" {
+ current=$(pwd)
+ cd /tmp
+ run "${current}/dsh" <<EOF
+cd arg1 arg2
+pwd
+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="/tmpdsh2>Toomanyargumentsdsh2>dsh2>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 "cd to the parent directory" {
+ current=$(pwd)
+ cd /tmp
+ mkdir -p student-test
+ cd student-test
+ run "${current}/dsh" <<EOF
+cd ..
+pwd
+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="/tmpdsh2>dsh2>dsh2>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 "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 '[:space:]')
+
+ # Expected output with all whitespace removed for easier matching
+ expected_output="CS283fundsh2>dsh2>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 "ls -l works well" {
+ current=$(pwd)
+
+ cd /tmp
+ mkdir -p ls-test
+ cd ls-test
+
+ run "${current}/dsh" <<EOF
+ls -l
+EOF
+ # Strip all whitespace (spaces, tabs, newlines) from the output
+ stripped_output=$(echo "$output" | tr -d '[:space:]')
+ head_output=$(echo "$stripped_output" | cut -c 1-40)
+ tail_output=$(echo "$stripped_output" | cut -c 55-)
+ output_except_time="$head_output$tail_output"
+ # Expected output with all whitespace removed for easier matching
+ expected_output="total0dsh2>dsh2>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_except_time} -> ${expected_output}"
+
+ # Check exact match
+ [ "$output_except_time" = "$expected_output" ]
+
+ [ "$status" -eq 0 ]
+
+}
+
+@test "uname test" {
+ run "./dsh" <<EOF
+uname -a
+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="Linuxtux25.15.0-121-generic#131-UbuntuSMPFriAug908:29:53UTC2024x86_64x86_64x86_64GNU/Linuxdsh2>dsh2>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 "ls works well" {
+ run "./dsh" << EOF
+ls
+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="batsdragon.cdshdsh_cli.cdsh.dSYMdshlib.cdshlib.hinput.txtmakefileshell_roadmap.mdstudent-testtestdsh2>dsh2>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 ]
+
+}
diff --git a/hw4/starter/dshlib.c b/hw4/starter/dshlib.c
index 4b002a070c1966f1d015f430b978d39dba57b874..350d00aca00dd87ff0541eea30da31d502999667 100644
--- a/hw4/starter/dshlib.c
+++ b/hw4/starter/dshlib.c
@@ -131,6 +131,7 @@ int exec_local_cmd_loop()
// TODO IMPLEMENT parsing input to cmd_buff_t *cmd_buff
cmd = parse_command(cmd_buff, cmd);
+
// TODO IMPLEMENT if built-in command, execute builtin logic for exit, cd (extra credit: dragon)
// the cd command should chdir to the provided directory; if no directory is provided, do nothing
if (strcmp(cmd_buff, EXIT_CMD) == 0){
@@ -141,7 +142,7 @@ int exec_local_cmd_loop()
if (cmd.argc < 2){
continue;
- } else {
+ } else if (cmd.argc == 2) {
// if(chdir(cmd.argv[1]) == 0){
// printf("Success");
// } else{
@@ -150,21 +151,28 @@ int exec_local_cmd_loop()
// printf("ok\n");
chdir(cmd.argv[1]);
// printf()
+ } else {
+ printf("Too many arguments\n");
}
- } else {
- pid_t pid = fork();
- if (pid==0){
+ // TODO IMPLEMENT if not built-in command, fork/exec as an external command
+ // for example, if the user input is "ls -l", you would fork/exec the command "ls" with the arg "-l"
+ }else {
+
+ int f_result = fork();
+
+ if (f_result==0){
int i = execvp(cmd.argv[0], cmd.argv);
if (i==-1){
- printf("fail\n");
- exit(1);
+ perror("fail\n");
+ exit(42);
}
- exit(0);
+
} else {
int wait_code;
- waitpid(pid, &wait_code, 0);
+ wait(&wait_code);
+ int status = WEXITSTATUS(wait_code);
}
}
@@ -174,12 +182,7 @@ int exec_local_cmd_loop()
}
-
-
- // TODO IMPLEMENT if not built-in command, fork/exec as an external command
- // for example, if the user input is "ls -l", you would fork/exec the command "ls" with the arg "-l"
free(cmd_buff);
return OK;
}
-
diff --git a/hw4/starter/input.txt b/hw4/starter/input.txt
new file mode 100644
index 0000000000000000000000000000000000000000..95d09f2b10159347eece71399a7e2e907ea3df4f
--- /dev/null
+++ b/hw4/starter/input.txt
@@ -0,0 +1 @@
+hello world
\ No newline at end of file