diff --git a/result.txt b/result.txt index f70ed64..561402c 100755 --- a/result.txt +++ b/result.txt @@ -1,10 +1,10 @@ -total 52 -drwxr-xr-x 4 root root 120 Mar 16 22:47 . -dr-xr-x---. 14 root root 4096 Mar 16 15:20 .. -drwxr-xr-x 8 root root 201 Mar 16 22:04 .git +total 56 +drwxr-xr-x 4 root root 120 Mar 16 23:39 . +dr-xr-x---. 14 root root 4096 Mar 16 23:39 .. +drwxr-xr-x 8 root root 201 Mar 16 22:49 .git -rw-r--r-- 1 root root 46 Mar 10 17:40 README.md --rwx------ 1 root root 0 Mar 16 22:47 result.txt +-rwx------ 1 root root 0 Mar 16 23:39 result.txt drwxr-xr-x 2 root root 64 Mar 16 11:27 .vscode --rwxr-xr-x 1 root root 23728 Mar 16 22:46 yeeshell --rw-r--r-- 1 root root 13535 Mar 16 22:46 yeeshell.c --rw-r--r-- 1 root root 3914 Mar 16 22:44 yeeshell.h +-rwxr-xr-x 1 root root 27936 Mar 16 23:39 yeeshell +-rw-r--r-- 1 root root 15053 Mar 16 23:38 yeeshell.c +-rw-r--r-- 1 root root 4043 Mar 16 23:36 yeeshell.h diff --git a/yeeshell b/yeeshell index 05f3d9a..c8a9602 100755 Binary files a/yeeshell and b/yeeshell differ diff --git a/yeeshell.c b/yeeshell.c index 712e915..bed1ce3 100644 --- a/yeeshell.c +++ b/yeeshell.c @@ -168,93 +168,172 @@ int check_redirect(char **args, char *redirect_filename, char **redirect_args) return redirect_flag; } +int check_pipe(char **args, char **pipe_arg_1, char **pipe_arg_2) +{ + int pipe_flag = 0, i = 0, j = 0; + + while (args[i] != NULL) + { + if (!strcmp(args[i], "|")) + { + pipe_flag = 1; + break; + } + pipe_arg_1[j++] = args[i++]; + } + + j = 0; + i++; + while (args[i] != NULL) + { + pipe_arg_2[j++] = args[i++]; + } + return pipe_flag; +} + int execute(char *cmdline, char **args) { - int bg = 0, i = 0, redirect_flag = 0, fd = 1; + int bg = 0, i = 0, redirect_flag = 0, fd = 1, pipe_num = 0; pid_t pid; char *redirect_filename = NULL; - redirect_filename = (char *)calloc(REDIRECT_FILENAME_MAX_SIZE, sizeof(char)); char *redirect_args[ARGS_MAX_QUANTITY]; + char *pipe_arg_1[ARGS_MAX_QUANTITY]; + char *pipe_arg_2[ARGS_MAX_QUANTITY]; + + redirect_filename = (char *)calloc(REDIRECT_FILENAME_MAX_SIZE, sizeof(char)); memset(redirect_args, NULL, sizeof(redirect_args)); + sigset_t mask_all, mask_prev; sigprocmask(SIG_BLOCK, NULL, &mask_all); sigaddset(&mask_all, SIGCHLD); + bg = parseline(cmdline, args); redirect_flag = check_redirect(args, redirect_filename, redirect_args); + pipe_num = check_pipe(args, pipe_arg_1, pipe_arg_2); if (args[0] == NULL) { return 1; } - if (!built_in(args)) + if (pipe_num == 0) { - /* Prevent child processes from ending between parent processes, that is, between addJob and deleteJob. */ - sigprocmask(SIG_BLOCK, &mask_all, &mask_prev); /* Shield SIGCHLD */ - - if ((pid = fork()) == 0) /* Child process */ + if (!built_in(args)) /* built-in cmd? */ { - if (redirect_flag == 1) - { - fd = open(redirect_filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR); - close(1); - dup(fd); - } - else if (redirect_flag == 2) + /* Prevent child processes from ending between parent processes, that is, between addJob and deleteJob. */ + sigprocmask(SIG_BLOCK, &mask_all, &mask_prev); /* Shield SIGCHLD */ + + if ((pid = fork()) == 0) /* Child process */ { - fd = open(redirect_filename, O_RDONLY, S_IRUSR); - close(0); - dup(fd); - } + if (redirect_flag == 1) /* redirect? */ + { + fd = open(redirect_filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR); + close(1); + dup(fd); + } + else if (redirect_flag == 2) + { + fd = open(redirect_filename, O_RDONLY, S_IRUSR); + close(0); + dup(fd); + } - /* The child process inherits the parent's signal mask and will inherit it after exec, - so it needs to restore the signal mask before executing. */ - sigprocmask(SIG_SETMASK, &mask_prev, NULL); /* Child process, unblock SIGCHLD */ + /* The child process inherits the parent's signal mask and will inherit it after exec, + so it needs to restore the signal mask before executing. */ + sigprocmask(SIG_SETMASK, &mask_prev, NULL); /* Child process, unblock SIGCHLD */ - /* Set the pid of the current process to the group number of the process group it belongs to. */ - /* avoid being grouped with tsh */ - setpgid(0, 0); + /* Set the pid of the current process to the group number of the process group it belongs to. */ + /* avoid being grouped with tsh */ + setpgid(0, 0); - if ((redirect_flag == 1) || (redirect_flag == 2)) - { + if ((redirect_flag == 1) || (redirect_flag == 2)) + { - if (execvp(redirect_args[0], redirect_args) <= 0) + if (execvp(redirect_args[0], redirect_args) <= 0) + { + printf("%s: Command not found\n", args[0]); + exit(0); + } + close(fd); + } + else { - printf("%s: Command not found\n", args[0]); - exit(0); + if (execvp(args[0], args) <= 0) + { + printf("%s: Command not found\n", args[0]); + exit(0); + } } - close(fd); } else { - if (execvp(args[0], args) <= 0) + if (bg) /* bg task */ + { + addjob(jobs, pid, BG, cmdline); + } + else /* fg task */ + { + addjob(jobs, pid, FG, cmdline); + } + + sigprocmask(SIG_SETMASK, &mask_prev, NULL); + + if (bg) /* Don't wait for background tasks to finish */ { - printf("%s: Command not found\n", args[0]); - exit(0); + printf("[%d](%d)%s", pid2jid(pid), pid, cmdline); + } + else /* Wait for foreground tasks to finish */ + { + waitfg(pid); } } } - else + } + else + { + int fds[2]; + pid_t prog_1, prog_2; + sigprocmask(SIG_BLOCK, &mask_all, &mask_prev); + + if ((prog_1 = fork()) == 0) /* Child process 1 */ { - if (bg) /* bg task */ - { - addjob(jobs, pid, BG, cmdline); - } - else /* fg task */ - { - addjob(jobs, pid, FG, cmdline); - } + dup2(fds[1], 1); + dup2(fds[1], 2); + close(fds[0]); + close(fds[1]); sigprocmask(SIG_SETMASK, &mask_prev, NULL); + setpgid(0, 0); - if (bg) /* Don't wait for background tasks to finish */ + if (execvp(pipe_arg_1[0], pipe_arg_1) <= 0) { - printf("[%d](%d)%s", pid2jid(pid), pid, cmdline); + printf("%s: Command not found\n", pipe_arg_1[0]); + exit(0); } - else /* Wait for foreground tasks to finish */ + _exit(127); + } + + if ((prog_2 = fork()) == 0) /* Child process 1 */ + { + dup2(fds[0], 0); + close(fds[0]); + close(fds[1]); + + sigprocmask(SIG_SETMASK, &mask_prev, NULL); + setpgid(0, 0); + + if (execvp(pipe_arg_2[0], pipe_arg_2) <= 0) { - waitfg(pid); + printf("%s: Command not found\n", pipe_arg_2[0]); + exit(0); } + _exit(127); } + + close(fds[0]); + close(fds[1]); + + waitfg(prog_1); + waitfg(prog_2); } return 1; } diff --git a/yeeshell.h b/yeeshell.h index 38d76df..eb16d4a 100644 --- a/yeeshell.h +++ b/yeeshell.h @@ -38,6 +38,9 @@ int parseline(char *cmdline, char **args); /* check_redirect - check if the command contains redirection */ int check_redirect(char **args, char *redirect_filename, char **redirect_args); +/* check_redirect - check if the command contains pipe */ +int check_pipe(char **args, char **pipe_arg_1, char **pipe_arg_2); + /* execute - Execute the command line */ int execute(char *cmdline, char **args);