diff --git a/assignments/assignment-5/starter/dsh b/assignments/assignment-5/starter/dsh index 3bd5b8ef487637348974bfa0bb6239633ffe36a4..122f476185ab42843e019abfc92ae7f91acb299d 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 0531d2209392ebd5427de44f6105ee7f6986ec4a..df3d58964bc0d719dbf4ec907338562474fa91df 100644 --- a/assignments/assignment-5/starter/dshlib.c +++ b/assignments/assignment-5/starter/dshlib.c @@ -99,9 +99,9 @@ Built_In_Cmds exec_built_in_cmd(cmd_buff_t *cmd) { } int build_cmd_list(char *cmd_line, command_list_t *clist) { - printf("Before trimming the cmd_line in build_cmd_list: '%s'\n", cmd_line); + //printf("Before trimming the cmd_line in build_cmd_list: '%s'\n", cmd_line); trim_spaces(cmd_line); - printf("Trimmed cmd_line: '%s'\n", cmd_line); + //printf("Trimmed cmd_line: '%s'\n", cmd_line); char *cmd_tok_save = NULL; char *cmd_tok = strtok_r(cmd_line, PIPE_STRING, &cmd_tok_save); @@ -111,7 +111,7 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { while(cmd_tok != NULL) { trim_spaces(cmd_tok); - printf("Command %d: '%s'\n", index, cmd_tok); + //printf("Command %d: '%s'\n", index, cmd_tok); if(index >= CMD_MAX) { return ERR_TOO_MANY_COMMANDS; @@ -121,7 +121,7 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { cmd->argc = 0; cmd->_cmd_buffer = cmd_tok; - printf("Command %d (before args parsing): '%s'\n", index, cmd_tok); + //printf("Command %d (before args parsing): '%s'\n", index, cmd_tok); char *arg_tok_save = NULL; char *arg_tok = strtok_r(cmd_tok, " ", &arg_tok_save); @@ -129,7 +129,7 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { while(arg_tok != NULL && cmd->argc < CMD_ARGV_MAX) { trim_spaces(arg_tok); - printf("Command %d: argv[%d]: '%s'\n", index, cmd->argc, arg_tok); + //printf("Command %d: argv[%d]: '%s'\n", index, cmd->argc, arg_tok); cmd->argv[cmd->argc] = arg_tok; cmd->argc++; @@ -137,17 +137,20 @@ int build_cmd_list(char *cmd_line, command_list_t *clist) { arg_tok = strtok_r(NULL, " ", &arg_tok_save); } - printf("Command %d finished parsing. argc = %d\n", index, cmd->argc); + cmd->argv[cmd->argc] = NULL; + + //printf("Command %d finished parsing. argc = %d\n", index, cmd->argc); index++; cmd_tok = strtok_r(NULL, PIPE_STRING, &cmd_tok_save); } clist->num = index; - printf("Total number of commands: %d\n", clist->num); + //printf("Total number of commands: %d\n", clist->num); return OK; } +/* int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist) { int pipe_fds[2]; pid_t pid; @@ -173,36 +176,44 @@ int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist) { } if(pid == 0) { - - // Debug: Print argv to verify contents + printf("Command %d: Before redirecting, STDOUT_FILENO = %d\n", cmd_index, STDOUT_FILENO); + + // Debug: Print the arguments for execvp to check if the command is correct printf("Command %d: execvp arguments:\n", cmd_index); for (int i = 0; cmd->argv[i] != NULL; i++) { - printf("argv[%d]: %s\n", i, cmd->argv[i]); + printf("argv[%d]: '%s'\n", i, cmd->argv[i]); } - if(cmd_index > 0) { - if(dup2(clist->pipes[cmd_index - 1][0], STDIN_FILENO) == -1) { - perror("Failed to redirect stdin"); - exit(1); - } - printf("Command %d: stdin redirected from pipe[%d][0] to STDIN_FILENO\n", cmd_index, cmd_index - 1); - } - - if(!is_last_cmd) { - if(dup2(pipe_fds[1], STDOUT_FILENO) == -1) { - perror("Failed to redirect stdout"); - exit(1); - } - printf("Command %d: stdout redirected to pipe[%d][1] from STDOUT_FILENO\n", cmd_index, cmd_index); - } + // Ensure stdin redirection for the second command + if (cmd_index > 0) { + if (dup2(clist->pipes[cmd_index - 1][0], STDIN_FILENO) == -1) { + perror("Failed to redirect stdin"); + exit(1); + } + printf("Command %d: stdin redirected from pipe[%d][0] to STDIN_FILENO\n", cmd_index, cmd_index - 1); + close(clist->pipes[cmd_index - 1][0]); + printf("Command %d: Closed pipe[%d][0] in child process\n", cmd_index, cmd_index - 1); + } + + // Redirect stdout if it's not the last command + if (!is_last_cmd) { + if (dup2(pipe_fds[1], STDOUT_FILENO) == -1) { + perror("Failed to redirect stdout"); + exit(1); + } + printf("Command %d: stdout redirected to pipe[%d][1] from STDOUT_FILENO\n", cmd_index, cmd_index); + //close(pipe_fds[1]); // Close the write end of the pipe + //printf("Command %d: Closed pipe[%d][1] in child process\n", cmd_index, cmd_index); + } for(int i = 0; i < clist->num - 1; i++) { - printf("Command %d: Closing pipe[%d][0] and pipe[%d][1]\n", cmd_index, i, i); - close(clist->pipes[i][0]); - close(clist->pipes[i][1]); - } + if (i != cmd_index - 1) { // Don't close the pipe we're reading from + close(clist->pipes[i][0]); + close(clist->pipes[i][1]); + printf("Command %d: Closed clist->pipes[%d][0] and clist->pipes[%d][1] in child process\n", cmd_index, i, i); + } + } - close(pipe_fds[0]); close(pipe_fds[1]); if(execvp(cmd->argv[0], cmd->argv) == -1) { @@ -213,15 +224,10 @@ int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist) { else { if(!is_last_cmd) { close(pipe_fds[1]); - printf("Command %d: Parent closing pipe[%d][1]\n", cmd_index, cmd_index); - } - - /* - for(int i = 0; i < clist->num - 1; i++) { - close(clist->pipes[i][0]); - close(clist->pipes[i][1]); + printf("Command %d: Parent closing write end pipe[%d][1]\n", cmd_index, cmd_index); + //close(pipe_fds[0]); + //printf("Command %d: Parent closing read end pipe[%d][0]\n", cmd_index, cmd_index); } - */ if(cmd_index > 0) { close(clist->pipes[cmd_index - 1][0]); @@ -235,6 +241,102 @@ int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist) { return OK; } +*/ + +int exec_cmd(cmd_buff_t *cmd, int cmd_index, command_list_t *clist) { + int pipe_fds[2]; + pid_t pid; + + int is_last_cmd = (cmd_index == clist->num - 1); + + printf("Command %d: is_last_cmd = %d\n", cmd_index, is_last_cmd); + + // Create pipe for non-last commands + if (!is_last_cmd) { + if (pipe(pipe_fds) == -1) { + perror("Pipe failed"); + return -1; + } + printf("Command %d: Pipe created with fd[0] = %d, fd[1] = %d\n", cmd_index, pipe_fds[0], pipe_fds[1]); + } + + pid = fork(); + + if (pid == -1) { + perror("Fork failed"); + return -1; + } + + if (pid == 0) { // Child process + printf("Command %d: Before redirecting, STDOUT_FILENO = %d\n", cmd_index, STDOUT_FILENO); + + printf("Debug: Command %d, before redirecting, pipe_fds[1] = %d\n", cmd_index, pipe_fds[1]); + + // Debug: Print the arguments for execvp to check if the command is correct + printf("Command %d: execvp arguments:\n", cmd_index); + for (int i = 0; cmd->argv[i] != NULL; i++) { + printf("argv[%d]: '%s'\n", i, cmd->argv[i]); + } + + // Redirect input from previous command, if it's not the first command + if (cmd_index > 0) { + if (dup2(clist->pipes[cmd_index - 1][0], STDIN_FILENO) == -1) { + perror("Failed to redirect stdin"); + exit(1); + } + printf("Command %d: stdin redirected from pipe[%d][0] to STDIN_FILENO\n", cmd_index, cmd_index - 1); + close(clist->pipes[cmd_index - 1][0]); // Close the read end of the previous pipe + printf("Command %d: Closed pipe[%d][0] in child process\n", cmd_index, cmd_index - 1); + } + + // Redirect stdout to the pipe if this is not the last command + if (!is_last_cmd) { + if (dup2(pipe_fds[1], STDOUT_FILENO) == -1) { + perror("Failed to redirect stdout"); + exit(1); + } + printf("Command %d: stdout redirected to pipe[%d][1] from STDOUT_FILENO\n", cmd_index, cmd_index); + close(pipe_fds[1]); // Close the write end of the pipe after redirection + printf("Command %d: Closed pipe[%d][1] in child process\n", cmd_index, cmd_index); + } + + // Close all unnecessary file descriptors in child process + for (int i = 0; i < clist->num - 1; i++) { + if (i != cmd_index - 1) { // Don't close the pipe we're reading from + close(clist->pipes[i][0]); + close(clist->pipes[i][1]); + printf("Command %d: Closed clist->pipes[%d][0] and clist->pipes[%d][1] in child process\n", cmd_index, i, i); + } + } + + // Execute the command + if (execvp(cmd->argv[0], cmd->argv) == -1) { + perror("Execvp failed"); + printf("Debug: Execvp failed for command %d. Pipe fds: pipe_fds[0] = %d, pipe_fds[1] = %d\n", cmd_index, pipe_fds[0], pipe_fds[1]); + exit(1); + } + } else { // Parent process + // Close the write end of the pipe in the parent if it's not the last command + if (!is_last_cmd) { + close(pipe_fds[1]); // Parent closes the write end of the pipe + printf("Command %d: Parent closing write end pipe[%d][1]\n", cmd_index, cmd_index); + } + + // Close the read end of the previous pipe in the parent process + if (cmd_index > 0) { + close(clist->pipes[cmd_index - 1][0]); // Parent closes the previous read end + printf("Command %d: Parent closing pipe[%d][0]\n", cmd_index, cmd_index - 1); + } + + // Wait for the child process to finish + int status; + waitpid(pid, &status, 0); + printf("Command %d: Child process finished with status %d\n", cmd_index, status); + } + return OK; +} + + int exec_local_cmd_loop() { char *cmd_buff = malloc(SH_CMD_MAX * sizeof(char)); @@ -255,7 +357,7 @@ int exec_local_cmd_loop() { break; } - printf("Raw input: '%s'\n", cmd_buff); + //printf("Raw input: '%s'\n", cmd_buff); // remove the trailing \n from cmd_buff cmd_buff[strcspn(cmd_buff, "\n")] = '\0'; @@ -263,7 +365,7 @@ int exec_local_cmd_loop() { // IMPLEMENT THE REST OF THE REQUIREMENTS trim_spaces(cmd_buff); - printf("Trimmed input in exec_local_cmd_loop: '%s'\n", cmd_buff); + //printf("Trimmed input in exec_local_cmd_loop: '%s'\n", cmd_buff); if(strlen(cmd_buff) == 0) { printf(CMD_WARN_NO_CMD); @@ -276,7 +378,7 @@ int exec_local_cmd_loop() { } rc = build_cmd_list(cmd_buff, &clist); - printf("RC value: %d\n", rc); + //printf("RC value: %d\n", rc); switch(rc) { case OK: