diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d0e4917 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "yeeshell.h": "c", + "types.h": "c", + "signal.h": "c" + } +} \ No newline at end of file diff --git a/yeeshell.c b/yeeshell.c index c7e0e5f..d9f0663 100644 --- a/yeeshell.c +++ b/yeeshell.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "yeeshell.h" /* record cmdline history */ @@ -64,6 +66,7 @@ int main() { free(history[i]); } + free(history); exit(EXIT_SUCCESS); } @@ -137,14 +140,36 @@ int parseline(char *cmdline, char **args) return bg; } +int redirect(char **args, char *redirect_file, char **redirect_args) +{ + int i = 0; + while (args[i] != NULL) + { + redirect_args[i] = args[i]; + if (args[i + 1] == ">") + { + redirect_file = args[i + 2]; + return OUT_REDRT; + } + else if (args[i + 1] == "<") + { + redirect_file = args[i + 2]; + return IN_REDRT; + } + } + return NO_REDRT; +} + int execute(char *cmdline, char **args) { - int bg = 0, i = 0; + int bg = 0, redirect_flag = 0, fd = 0; + char *redirect_file, *redirect_args[ARGS_MAX_QUANTITY]; pid_t pid; sigset_t mask_all, mask_prev; sigprocmask(SIG_BLOCK, NULL, &mask_all); sigaddset(&mask_all, SIGCHLD); bg = parseline(cmdline, args); + redirect_flag = redirect(args, redirect_file, redirect_args); if (args[0] == NULL) { @@ -164,6 +189,38 @@ int execute(char *cmdline, char **args) /* 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); + + switch (redirect_flag) + { + case 0: /* no redirection */ + if (execvp(args[0], args) <= 0) + { + printf("%s: Command not found\n", args[0]); + exit(0); + } + break; + case 1: /* redirect output */ + fd = open(redirect_file, O_CREAT | O_WRONLY | O_TRUNC, 0664); + dup(fd, 1); + if (execvp(args[0], redirect_args) <= 0) + { + printf("%s: Command not found\n", args[0]); + exit(0); + } + break; + case 2: /* redirect input */ + fd = open(info.in_file, O_CREAT | O_RDONLY, 0666); + close(fileno(stdin)); + dup2(fd, fileno(stdin)); + close(fd); + if (execvp(args[0], redirect_args) <= 0) + { + printf("%s: Command not found\n", args[0]); + exit(0); + } + break; + } + if (execvp(args[0], args) <= 0) { printf("%s: Command not found\n", args[0]); @@ -172,10 +229,6 @@ int execute(char *cmdline, char **args) } else { - do - { - } while (!args[i++]); - if (bg) /* bg task */ { addjob(jobs, pid, BG, cmdline); diff --git a/yeeshell.h b/yeeshell.h index 7fa40cb..c2cd9c6 100644 --- a/yeeshell.h +++ b/yeeshell.h @@ -14,6 +14,10 @@ #define BG 2 /* running in background */ #define ST 3 /* stopped */ +#define NO_REDRT 0 /* no redirection */ +#define OUT_REDRT 1 /* the latter is output */ +#define IN_REDRT 2 /* the former is input */ + /* job_t - The job struct */ struct job_t { @@ -29,6 +33,9 @@ char *readline(); /* parseline - Evaluate the command line that the user has just typed in */ int parseline(char *cmdline, char **args); +/* redirect - Judge if the command contains redirection */ +int redirect(char **args, char *redirect_file, char **redirect_args); + /* execute - Execute the command line */ int execute(char *cmdline, char **args);