diff options
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | src/lsh_main_func.c | 56 | ||||
| -rwxr-xr-x | src/main.c | 1 | ||||
| -rw-r--r-- | src/main.h | 8 |
4 files changed, 57 insertions, 14 deletions
@@ -26,12 +26,12 @@ Going to try and make it mostly POSIX compliant. - [x] pipes | - [ ] && - [x] ; - - [ ] vi mode - - [ ] redirection > + - [x] redirection > + - [x] append >> - [ ] redirection < - - [ ] append >> - [ ] heredoc << - [ ] & + - [ ] vi mode - [ ] Env="something" ... executable args - [ ] rcfile - [ ] rcfile in config dir diff --git a/src/lsh_main_func.c b/src/lsh_main_func.c index ff05a2b..52c016b 100644 --- a/src/lsh_main_func.c +++ b/src/lsh_main_func.c @@ -6,9 +6,11 @@ #include <sys/wait.h> #include <unistd.h> #include <stdbool.h> +#include <fcntl.h> #include "main.h" #include "helper_functions.c" +#include "lsh_split_line.c" #define LSH_RL_BUFSIZE 1024 char *lsh_read_line(void) @@ -50,13 +52,14 @@ int cleanup_token(char **parse_args_last_p, int ch_i){ //remove spaces and tabs around sep char int i=ch_i-1; - while ((*parse_args_last_p)[i]==' '|| (*parse_args_last_p)[0]=='\t'){ + while ((*parse_args_last_p)[i]==' '|| (*parse_args_last_p)[0]=='\t') (*parse_args_last_p)[i--]='\0'; - } + i=ch_i+1; + while((*parse_args_last_p)[i]==' ' || (*parse_args_last_p)[i]=='\t') + (*parse_args_last_p)[i++]='\0'; + + *parse_args_last_p=&(*parse_args_last_p)[i]; - *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; } @@ -104,14 +107,28 @@ char *strtok_cmd(char *token, cmd_t *type){ } else{ switch (parse_args_last_p[ch_i]){ case ';': - if(cleanup_token(&parse_args_last_p, ch_i)!=0) break; + if(cleanup_token(&parse_args_last_p, ch_i)==-1) break; return return_char; break; case '|': - if(cleanup_token(&parse_args_last_p, ch_i)!=0) break; + if(cleanup_token(&parse_args_last_p, ch_i)==-1) break; *type=Pipe; return return_char; break; + case '>': + if(cleanup_token(&parse_args_last_p, ch_i)==-1) break; + *type=Redirect; + // detect and cleanup append + if(parse_args_last_p[0]=='>'){ + parse_args_last_p=&parse_args_last_p[1]; + int i=0; + while(parse_args_last_p[i]==' ' || parse_args_last_p[i]=='\t') + parse_args_last_p[i++]='\0'; + parse_args_last_p=&parse_args_last_p[i]; + *type=Append; + } + return return_char; + break; } } @@ -136,6 +153,7 @@ CMD **lsh_split_command(char *line) tokens[position]->type = cmd_type; tokens[position]->stdInFd = 0; tokens[position]->next = NULL; + tokens[position]->out_dir= NULL; if(position>0) tokens[position-1]->next = tokens[position]; position++; @@ -149,6 +167,12 @@ CMD **lsh_split_command(char *line) } } + // do not make Redirect or Append a actual command to run + // sets the current commands out_dir (redirection) to the next tokens value + if(cmd_type==Redirect || cmd_type==Append){ + token = strtok_cmd(NULL,&cmd_type); + tokens[position-1]->out_dir=handle_vars(token); + } token = strtok_cmd(NULL,&cmd_type); } tokens[position] = NULL; @@ -160,15 +184,31 @@ int lsh_launch(char **args, CMD *cmd) pid_t pid, wpid; int status; int stdOutPipe[2]; + int redir_out; pipe(stdOutPipe); if(cmd->type==Pipe){ cmd->next->stdInFd=stdOutPipe[0]; } + if (cmd->type==Redirect){ + redir_out = open(cmd->out_dir,O_RDWR|O_CREAT|O_TRUNC, 0600); + if (-1 == redir_out) { + fprintf(stderr,"opening %s",cmd->out_dir); + return -1; + } + } else if(cmd->type==Append){ + redir_out = open(cmd->out_dir,O_RDWR|O_CREAT|O_APPEND, 0600); + if (-1 == redir_out) { + fprintf(stderr,"opening %s",cmd->out_dir); + return -1; + } + } pid = fork(); if (pid == 0) { // Child process - if(cmd->type!=Stdout){ + if (cmd->type==Redirect || cmd->type==Append){ + dup2(redir_out, 1); // send stdout to the pipe + } else if(cmd->type!=Stdout){ close(stdOutPipe[0]); // close reading end in the child dup2(stdOutPipe[1], 1); // send stdout to the pipe @@ -37,6 +37,7 @@ void lsh_loop(SHELL_OB *shell_obj){ int i=0; while(cmds[i]){ + if(cmds[i]->out_dir!=NULL) free(cmds[i]->out_dir); free(cmds[i]); i++; } @@ -9,15 +9,17 @@ typedef struct{ typedef enum{ Stdout=0, Redirect=1, - Pipe=2, - Continue=3, - If=4, + Append=2, + Pipe=3, + Continue=4, + If=5, } cmd_t; typedef struct CMD{ char *cmd; cmd_t type; int stdInFd; + char *out_dir; struct CMD *next; int status; } CMD; |
