diff options
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | src/lsh_builtins.c | 4 | ||||
| -rw-r--r-- | src/lsh_main_func.c | 71 | ||||
| -rwxr-xr-x | src/main.c | 8 | ||||
| -rw-r--r-- | src/main.h | 10 |
5 files changed, 74 insertions, 25 deletions
@@ -23,13 +23,15 @@ Going to try and make it mostly POSIX compliant. - [x] single quotes - [x] pop quotes a'b'c -> abc - [ ] prompt uses PS1 - - [ ] pipes | + - [x] pipes | - [ ] && - [x] ; - [ ] vi mode - - [ ] redirections > < + - [ ] redirection > + - [ ] redirection < - [ ] append >> - [ ] heredoc << - [ ] & +- [ ] Env="something" ... executable args - [ ] rcfile - [ ] rcfile in config dir diff --git a/src/lsh_builtins.c b/src/lsh_builtins.c index 0986cfe..dda49c4 100644 --- a/src/lsh_builtins.c +++ b/src/lsh_builtins.c @@ -101,7 +101,7 @@ int export(char **args){ -int lsh_execute(char **args) +int lsh_execute(char **args, CMD *cmd) { int i; @@ -116,6 +116,6 @@ int lsh_execute(char **args) } } - return lsh_launch(args); + return lsh_launch(args, cmd); } #endif diff --git a/src/lsh_main_func.c b/src/lsh_main_func.c index 1604073..ff05a2b 100644 --- a/src/lsh_main_func.c +++ b/src/lsh_main_func.c @@ -3,7 +3,6 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <sys/wait.h> #include <unistd.h> #include <stdbool.h> @@ -44,7 +43,24 @@ char *lsh_read_line(void) } } -char * strtok_cmd(char *token, cmd_t *type){ +int cleanup_token(char **parse_args_last_p, int ch_i){ + (*parse_args_last_p)[ch_i]='\0'; + if((*parse_args_last_p)[ch_i+1]=='\0') + return -1; + + //remove spaces and tabs around sep char + int i=ch_i-1; + while ((*parse_args_last_p)[i]==' '|| (*parse_args_last_p)[0]=='\t'){ + (*parse_args_last_p)[i--]='\0'; + } + + *parse_args_last_p=&(*parse_args_last_p)[ch_i+1]; + while((*parse_args_last_p)[0]==' ' || (*parse_args_last_p)[0]=='\t') + *parse_args_last_p=&(*parse_args_last_p)[1]; + return 0; +} + +char *strtok_cmd(char *token, cmd_t *type){ *type=Stdout; static char* parse_args_last_p; if(token != NULL){ @@ -85,16 +101,18 @@ char * strtok_cmd(char *token, cmd_t *type){ if (pass_check) in_quote=' '; } - } else if(parse_args_last_p[ch_i]==';'){ - if(parse_args_last_p[ch_i]=='\0') - break; - parse_args_last_p[ch_i]='\0'; - if(parse_args_last_p[ch_i+1]=='\0') - break; - parse_args_last_p=&parse_args_last_p[ch_i+1]; - while(parse_args_last_p[0]==' ' || parse_args_last_p[0]=='\t') - parse_args_last_p=&parse_args_last_p[1]; - return return_char; + } else{ + switch (parse_args_last_p[ch_i]){ + case ';': + if(cleanup_token(&parse_args_last_p, ch_i)!=0) break; + return return_char; + break; + case '|': + if(cleanup_token(&parse_args_last_p, ch_i)!=0) break; + *type=Pipe; + return return_char; + break; + } } ch_i++; @@ -116,6 +134,10 @@ CMD **lsh_split_command(char *line) tokens[position] = malloce(sizeof(CMD)); tokens[position]->cmd = token; tokens[position]->type = cmd_type; + tokens[position]->stdInFd = 0; + tokens[position]->next = NULL; + if(position>0) tokens[position-1]->next = tokens[position]; + position++; if (position * bufsize >= bufsize) { @@ -133,17 +155,33 @@ CMD **lsh_split_command(char *line) return tokens; } -int lsh_launch(char **args) +int lsh_launch(char **args, CMD *cmd) { pid_t pid, wpid; int status; + int stdOutPipe[2]; + pipe(stdOutPipe); + if(cmd->type==Pipe){ + cmd->next->stdInFd=stdOutPipe[0]; + } pid = fork(); if (pid == 0) { // Child process - if (execvp(args[0], args) == -1) { - perror("lsh"); + if(cmd->type!=Stdout){ + close(stdOutPipe[0]); // close reading end in the child + + dup2(stdOutPipe[1], 1); // send stdout to the pipe + dup2(stdOutPipe[1], 2); // send stderr to the pipe + + close(stdOutPipe[1]); // this descriptor is no longer needed } + + if(cmd->stdInFd!=0) + dup2(cmd->stdInFd,STDIN_FILENO); + + if (execvp(args[0], args) == -1) perror("lsh"); + exit(EXIT_FAILURE); } else if (pid < 0) { // Error forking @@ -153,6 +191,9 @@ int lsh_launch(char **args) do { wpid = waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + + close(stdOutPipe[1]); // close the write end of the pipe in the parent + if(cmd->stdInFd!=0) close(cmd->stdInFd); } return 1; @@ -26,8 +26,7 @@ void lsh_loop(SHELL_OB *shell_obj){ int j=0; while (cmds[j]){ args = lsh_split_line(cmds[j]->cmd); - status = lsh_execute(args); - free(cmds[j]); + status = lsh_execute(args,cmds[j]); j++; int i=0; @@ -36,6 +35,11 @@ void lsh_loop(SHELL_OB *shell_obj){ free(args); } + int i=0; + while(cmds[i]){ + free(cmds[i]); + i++; + } free(cmds); free(line); } while (status); @@ -10,14 +10,16 @@ typedef enum{ Stdout=0, Redirect=1, Pipe=2, - If=3, - Continue=4 + Continue=3, + If=4, } cmd_t; -typedef struct{ +typedef struct CMD{ char *cmd; cmd_t type; - char *Stdout; + int stdInFd; + struct CMD *next; + int status; } CMD; #endif |
