diff --git a/assignments/assignment-5/starter/bats/student_tests.sh b/assignments/assignment-5/starter/bats/student_tests.sh index fdc56b3a09b6b070e497a2afb9d8474347b87ec0..3df49078700d5554345acae7dfe9957c0bdd58fc 100644 --- a/assignments/assignment-5/starter/bats/student_tests.sh +++ b/assignments/assignment-5/starter/bats/student_tests.sh @@ -86,3 +86,57 @@ EOF # Assertions [ "$status" -eq 0 ] } + +@test "Check if > works" { + run ./dsh <<EOF +echo "hello, class" > out.txt +cat out.txt +rm out.txt +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="\"hello,class\"dsh3>dsh3>dsh3>dsh3>" + + echo "Captured stdout:" + echo "Output: $stripped_output" + echo "Expected: $expected_output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] +} + +@test "Check if >> works" { + run ./dsh <<EOF +echo "hello, class" > out.txt +cat out.txt +echo "this is the second line" >> out.txt +cat out.txt +rm out.txt +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="\"hello,class\"\"hello,class\"\"thisisthesecondline\"dsh3>dsh3>dsh3>dsh3>dsh3>dsh3>" + + echo "Captured stdout:" + echo "Output: $stripped_output" + echo "Expected: $expected_output" + echo "Exit Status: $status" + + # Check exact match + [ "$stripped_output" = "$expected_output" ] + + # Assertions + [ "$status" -eq 0 ] +} diff --git a/assignments/assignment-5/starter/dsh b/assignments/assignment-5/starter/dsh index d7d0c175eba2254a6950a18d144f42c2d0dc6a52..ebb6c2dff3b3b37f3e43b695b1d32c79f3482609 100755 Binary files a/assignments/assignment-5/starter/dsh and b/assignments/assignment-5/starter/dsh differ diff --git a/assignments/assignment-5/starter/dshlib.c b/assignments/assignment-5/starter/dshlib.c index f24530c2487e5a6aad113cceb6a2d211afaedc0b..6942f5f3c07c85a3bbb466df815d241ad720812a 100644 --- a/assignments/assignment-5/starter/dshlib.c +++ b/assignments/assignment-5/starter/dshlib.c @@ -120,6 +120,8 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { cmd_buff_t *cmd = &clist->commands[index]; cmd->argc = 0; cmd->_cmd_buffer = cmd_tok; + cmd->input_redirect = NULL; + cmd->output_redirect = NULL; //printf("Command %d (before args parsing): '%s'\n", index, cmd_tok); @@ -131,8 +133,29 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { //printf("Command %d: argv[%d]: '%s'\n", index, cmd->argc, arg_tok); - cmd->argv[cmd->argc] = arg_tok; - cmd->argc++; + if(strcmp(arg_tok, "<") == 0) { + arg_tok = strtok_r(NULL, " ", &arg_tok_save); + if(arg_tok != NULL) { + cmd->input_redirect = arg_tok; + } + } + else if(strcmp(arg_tok, ">>") == 0) { + arg_tok = strtok_r(NULL, " ", &arg_tok_save); + if(arg_tok != NULL) { + cmd->output_redirect = arg_tok; + cmd->output_append = 1; + } + } + else if(strcmp(arg_tok, ">") == 0) { + arg_tok = strtok_r(NULL, " ", &arg_tok_save); + if(arg_tok != NULL) { + cmd->output_redirect = arg_tok; + } + } + else { + cmd->argv[cmd->argc] = arg_tok; + cmd->argc++; + } arg_tok = strtok_r(NULL, " ", &arg_tok_save); } @@ -172,12 +195,40 @@ int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist, int pipefd_i close(pipefd[0]); } - if(cmd_index > 0) { + if(cmd->input_redirect != NULL) { + int input_fd = open(cmd->input_redirect, O_RDONLY); + if(input_fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + dup2(input_fd, STDIN_FILENO); + close(input_fd); + } + else if(cmd_index > 0) { dup2(pipefd_in, STDIN_FILENO); close(pipefd_in); } - if(cmd_index < clist->num - 1) { + if(cmd->output_redirect != NULL) { + int flags = O_WRONLY | O_CREAT; + if(cmd->output_append) { + flags |= O_APPEND; + //printf("OPENING FILE IN APPEND MODE: output_redirect = %s\n", cmd->output_redirect); + } + else { + flags |= O_TRUNC; + //printf("OPENING FILE IN OVERWRITE MODE: output_redirect = %s\n", cmd->output_redirect); + } + int output_fd = open(cmd->output_redirect, flags, 0644); + if(output_fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + //printf("FILE OPENED: output_fd = %d\n", output_fd); + dup2(output_fd, STDOUT_FILENO); + close(output_fd); + } + else if(cmd_index < clist->num - 1) { close(STDOUT_FILENO); dup2(pipefd[1], STDOUT_FILENO); close(pipefd[1]); diff --git a/assignments/assignment-5/starter/dshlib.h b/assignments/assignment-5/starter/dshlib.h index 47d87e7a035f81b74da82f77674e2a8491ec34f0..be62155d31015e2b98a0d2f806196582369cbdb3 100644 --- a/assignments/assignment-5/starter/dshlib.h +++ b/assignments/assignment-5/starter/dshlib.h @@ -21,6 +21,9 @@ typedef struct cmd_buff int argc; char *argv[CMD_ARGV_MAX]; char *_cmd_buffer; + char *input_redirect; + char *output_redirect; + int output_append; } cmd_buff_t; /* WIP - Move to next assignment diff --git a/assignments/assignment-5/starter/output.txt b/assignments/assignment-5/starter/output.txt deleted file mode 100644 index d46f5ff9bbc9f842450c3b400b3b286fb84f50e9..0000000000000000000000000000000000000000 --- a/assignments/assignment-5/starter/output.txt +++ /dev/null @@ -1,2 +0,0 @@ -Output of first command: -whoami