diff --git a/Makefile b/Makefile index e46605e..cfe2868 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,10 @@ NAME = minishell CC = clang -CFLAGS = -Wall -Wextra -Werror $(INCLUDES) -g +CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) -DIR_SRCS = srcs srcs/builtins srcs/parsing +DIR_SRCS = srcs srcs/builtins srcs/lexing srcs/parsing INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) @@ -22,8 +22,9 @@ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a SRCS = main.c init.c free.c generic.c \ - shell_loop.c \ - lexing.c \ + signals.c terminal.c \ + shell_loop.c shell_script.c \ + lexing.c fill_token.c check_operators.c \ parsing.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ fill_cmd.c \ diff --git a/cat b/cat deleted file mode 100644 index e69de29..0000000 diff --git a/echo b/echo deleted file mode 100644 index c991a69..0000000 --- a/echo +++ /dev/null @@ -1,12 +0,0 @@ -builds -echo -headers -libft -Makefile -minishell -minishell.en.subject.pdf -README.md -ressources -srcs -tests -valgrind_readline.supp diff --git a/file.txt b/file.txt deleted file mode 100755 index 680d3ea..0000000 --- a/file.txt +++ /dev/null @@ -1,15 +0,0 @@ -builds -cat -echo -file.txt -headers -libft -Makefile -minishell -minishell.en.subject.pdf -parsing.txt -README.md -ressources -srcs -tests -valgrind_readline.supp diff --git a/headers/minishell.h b/headers/minishell.h index 47ea867..51eecc0 100644 --- a/headers/minishell.h +++ b/headers/minishell.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/03 19:14:46 by lperrey #+# #+# */ -/* Updated: 2021/10/13 16:09:32 by lperrey ### ########.fr */ +/* Updated: 2021/10/26 14:53:32 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ # include "libft.h" # include # include +# include # include # include # include @@ -26,13 +27,17 @@ # include # include # include -# include // sudo apt install libncurses-dev (OR libncurses5-dev) + +// sudo apt install libncurses-dev (OR libncurses5-dev) +# include # include -# include -# include // sudo apt install libreadline-dev +// sudo apt install libreadline-dev +# include # include +# include + # include "minishell_structs.h" # include "minishell_macro.h" # include "minishell_term_colors.h" @@ -52,8 +57,8 @@ ** : open() ** : read(), write(), close(), fork(), getcwd(), chdir(), ** stat(), lstat(), fstat(), execve(), dup(), dup2(), pipe(), -** isatty(), ttyname(), ttyslot(), ioctl(), -** tcsetattr(), tcgetattr() +** isatty(), ttyname(), ttyslot(), tcsetattr(), tcgetattr() +** : ioctl() ** : malloc(), free(), exit(), getenv() ** : strerror(), define NULL, define size_t ** : define errno diff --git a/headers/minishell_macro.h b/headers/minishell_macro.h index 9fbda6f..7ff7858 100644 --- a/headers/minishell_macro.h +++ b/headers/minishell_macro.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:55 by lperrey #+# #+# */ -/* Updated: 2021/10/08 03:01:43 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 22:32:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,4 +18,10 @@ # define PROMPT_CHEVRON "> " # define PROMPT_EURO "\001€\002 \001\b\002" +enum e_lexer_return +{ + CONTINUE_TOKEN = 1, + DELIMITE_TOKEN +}; + #endif diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 00b7150..e64bf08 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/10/28 20:49:30 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 13:53:08 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,9 +15,15 @@ // Init int init(t_all *c, char *envp[]); +int set_signals_handling(struct sigaction *ori_signal_behaviour, + struct sigaction *signal_behaviour); +int set_terminal_attributes(struct termios *ori_termios, + struct termios *interactive_termios, + int *termios_changed); -// Shell loop +// Shell modes void shell_loop(t_all *c); +void shell_script(t_all *c); // Lexer t_token *input_to_tokens(char *input); @@ -47,6 +53,6 @@ size_t ft_2d_arrlen(void *ptr); // Replace ft_arrlen() char **ft_dup_2d_char_arr(char **ptr); void *ft_resize_2d_arr(void *ptr, size_t add_nbr); void print_matrix(char **matrix, char *sep); -void print_token(t_token *token, char *sep); +t_list *ft_lstbeforelast(t_list *lst); #endif diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 183ffba..84f4fc6 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,23 +6,27 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:18:28 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_STRUCTS_H # define MINISHELL_STRUCTS_H +struct s_all *g_all; + enum e_token_id { T_TOKEN = 0, T_LESS = '<', T_GREAT = '>', T_PIPE = '|', - T_DLESS, //'<<' - T_DGREAT, //'>>' + T_DLESS, + T_DGREAT, T_WORD }; +// T_DLESS == '<<' +// T_DGREAT == '>>' typedef struct s_token { @@ -31,8 +35,7 @@ typedef struct s_token enum e_token_id id; } t_token; -struct s_all; -typedef int (*t_builtin_ptr)(int,char **,struct s_all *); +typedef int (*t_builtin_ptr)(int,char **,struct s_all *); typedef struct s_cmd { @@ -45,12 +48,17 @@ typedef struct s_cmd typedef struct s_all { - t_cmd **cmd_arr; - char **envp; - char *prompt_base; - char *prompt; - t_token *token_list; - int last_exit_status; + t_cmd **cmd_arr; + char **envp; + char *prompt_base; + char *prompt; + t_token *token_list; + int last_exit_status; + struct termios ori_termios; + struct termios interactive_termios; + int termios_changed; + struct sigaction ori_signal_behaviour; + struct sigaction signal_behaviour; } t_all; #endif diff --git a/parsing.txt b/parsing.txt index c53ecb8..1c9627b 100644 --- a/parsing.txt +++ b/parsing.txt @@ -15,8 +15,8 @@ https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18 ------------------------------------------------------- */ %start program %% -pipeline : command - | pipe_sequence '|' command +pipeline : command + | pipeline '|' command ; command : cmd_prefix cmd_name cmd_suffix | cmd_prefix cmd_name diff --git a/srcs/free.c b/srcs/free.c index b2b6468..d02f438 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */ -/* Updated: 2021/10/22 13:35:33 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 14:18:09 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,9 @@ int free_exit(t_all *c, int exit_status) free(c->prompt_base); free(c->prompt); ft_lstclear((t_list **)&c->token_list, free); // a voir avec Hugo, il y a un truc qui me semble superflu dans la fonction - exit(exit_status); ft_free_2d_arr(c->envp); + if (c->termios_changed) + tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); + rl_clear_history(); + exit(exit_status); } diff --git a/srcs/generic.c b/srcs/generic.c index 38806aa..9426b83 100644 --- a/srcs/generic.c +++ b/srcs/generic.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ -/* Updated: 2021/10/28 17:04:03 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 13:52:23 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,7 +85,7 @@ size_t ft_2d_arrlen(void *ptr) // Replace ft_arrlen() return (len); } -char **ft_dup_2d_char_arr(char **ptr) +char **ft_dup_2d_char_arr(char **ptr) { unsigned int i; char **arr; @@ -125,6 +125,7 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr) return (new_arr); } +// pour imprimer une char ** en precisant comment separer les char * void print_matrix(char **matrix, char *sep) { int i; @@ -141,27 +142,11 @@ void print_matrix(char **matrix, char *sep) write(1, "\n", 1); } -void print_token(t_token *token, char *sep) +t_list *ft_lstbeforelast(t_list *lst) { - while(token) - { - printf("%s - ", token->content); - if(token->id == T_TOKEN) - printf("T_TOKEN"); - else if(token->id == T_LESS) - printf("T_LESS"); - else if(token->id == T_GREAT) - printf("T_GREAT"); - else if(token->id == T_PIPE) - printf("T_PIPE"); - else if(token->id == T_DLESS) - printf("T_DLESS"); - else if(token->id == T_DGREAT) - printf("T_DGREAT"); - else if(token->id == T_WORD) - printf("T_WORD"); - printf("%s", sep); - token = token->next; - } + if (!lst || !lst->next) + return (NULL); + while (lst->next->next) + lst = lst->next; + return (lst); } - diff --git a/srcs/init.c b/srcs/init.c index fd42712..f6e6484 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/10/28 11:07:40 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 13:50:33 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,9 +15,10 @@ static char *init_prompt_base(void); static char *init_prompt(char *prompt_base); -int init(t_all *c, char *envp[]) +int init(t_all *c, char *envp[]) { - ft_bzero(c, sizeof *c); + g_all = c; + ft_bzero(c, sizeof (*c)); c->envp = ft_dup_2d_char_arr(envp); if (!c->envp) return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); @@ -27,6 +28,13 @@ int init(t_all *c, char *envp[]) c->prompt = init_prompt(c->prompt_base); if (!c->prompt) return (ft_reti_perror(0, "init_prompt() error")); + set_signals_handling(&c->ori_signal_behaviour, &c->signal_behaviour); + if (isatty(STDIN_FILENO)) + { + if (!set_terminal_attributes(&c->ori_termios, &c->interactive_termios, + &c->termios_changed)) + return (ft_reti_perror(0, "set_terminal_attributes() error")); + } return (1); } diff --git a/srcs/lexing.c b/srcs/lexing.c deleted file mode 100644 index 5aa6b96..0000000 --- a/srcs/lexing.c +++ /dev/null @@ -1,193 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* lexing.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: lperrey +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:53:40 by lperrey ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" -static t_token *alloc_token(size_t content_len); -static int tokenize_input(t_token *t, char *input, size_t input_len); -static int fill_token(t_token *t, char *input, int *i, int *t_i); -static int check_operators(t_token *t, char *input, int *i, int *t_i); - -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; - -enum e_fill_token_return -{ - CONTINUE_TOKEN = 1, - DELIMITE_TOKEN -}; - -t_token *input_to_tokens(char *input) -{ - t_token *t_head; - size_t input_len; - - input_len = ft_strlen(input); - t_head = alloc_token(input_len); - if (!t_head) - return (ft_retp_perror(NULL, "alloc_token() error")); - if (!tokenize_input(t_head, input, input_len)) - return (ft_lstclear((t_list **)&t_head, free)); - return (t_head); -} - -// TODO : Fix final space saved after a pipe like in "cmd | " -// "cmd | " should behave like "cmd |" -static int tokenize_input(t_token *t, char *input, size_t input_len) -{ - int i; - int t_i; - - i = 0; - t_i = 0; - while (input[i]) - { - if (fill_token(t, input, &i, &t_i) == DELIMITE_TOKEN && input[i] && t_i) - { - if (!t->id) - t->id = T_WORD; - t->next = alloc_token(input_len - i); - if (!t->next) - return (ft_reti_perror(0, "alloc_token() error")); - t = t->next; - t_i = 0; - } - } - if (!t->id && t_i) // Fix parser syntax, but last elem must still be free - t->id = T_WORD; -/* if (!t->id) - t->id = T_WORD; */ - return (1); -} - -static int fill_token(t_token *t, char *input, int *i, int *t_i) -{ - static int in_quotes = 0; - - // operators - if (!in_quotes) - { - if (check_operators(t, input, i, t_i) == DELIMITE_TOKEN) - return (DELIMITE_TOKEN); - } - // quoting - if (input[*i] == '\'' && in_quotes != IN_DQUOTES) - { - t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_QUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\'')) // if closed quotes - in_quotes = IN_QUOTES; - return (CONTINUE_TOKEN); - } - else if (input[*i] == '\"' && in_quotes != IN_QUOTES) - { - t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_DQUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\"')) // if closed dquotes - in_quotes = IN_DQUOTES; - return (CONTINUE_TOKEN); - } - // blanks - if (!in_quotes && (input[*i] == ' ' || input[*i] == '\t')) - { - while (input[*i] == ' ' || input[*i] == '\t') - (*i)++; - return (DELIMITE_TOKEN); - } - else - t->content[(*t_i)++] = input[(*i)++]; - return (CONTINUE_TOKEN); -} - -static int check_operators(t_token *t, char *input, int *i, int *t_i) -{ - if (*t_i != 0 && (input[*i] == '|' || input[*i] == '<' || input[*i] == '>')) - return (DELIMITE_TOKEN); - if (input[*i] == '|') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_PIPE; - return (DELIMITE_TOKEN); - } - else if (input[*i] == '<') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_LESS; - if (input[*i] == '<') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_DLESS; - } - return (DELIMITE_TOKEN); - } - else if (input[*i] == '>') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_GREAT; - if (input[*i] == '>') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_DGREAT; - } - return (DELIMITE_TOKEN); - } - return (CONTINUE_TOKEN); -} - -static t_token *alloc_token(size_t content_len) -{ - t_token *token; - - token = ft_calloc(1, sizeof *token); - if (!token) - return (NULL); - token->content = ft_calloc(content_len + 1, 1); - if (!token->content) - return (ft_retp_free(NULL, token, free)); - return (token); -} - -/* -https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 -1 - OK -2 - OK -3 - OK -4 - OK -5 - OK / SEMI-OSEF -6 - OK -7 - OK -8 - OK -9 - OSEF -10 - OK - -*/ - -// Doublon avec ft_lstclear() -/* void *free_tokens(t_token *t) -{ - void *tmp; - - while (t) - { - if (t->content) - free (t->content); - tmp = t; - t = t->next; - free(tmp); - } - return (NULL); -} */ diff --git a/srcs/lexing/check_operators.c b/srcs/lexing/check_operators.c new file mode 100644 index 0000000..1a73014 --- /dev/null +++ b/srcs/lexing/check_operators.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* check_operators.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:37:08 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int check_redirection(t_token *t, char *input, int *i, int *t_i); +static int check_pipe(t_token *t, char *input, int *i, int *t_i); + +int check_operators(t_token *t, char *input, int *i, int *t_i) +{ + if (*t_i != 0 && (input[*i] == '|' || input[*i] == '<' || input[*i] == '>')) + return (DELIMITE_TOKEN); + else if (check_pipe(t, input, i, t_i)) + return (DELIMITE_TOKEN); + else if (check_redirection(t, input, i, t_i)) + return (DELIMITE_TOKEN); + return (CONTINUE_TOKEN); +} + +static int check_pipe(t_token *t, char *input, int *i, int *t_i) +{ + if (input[*i] == '|') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_PIPE; + return (1); + } + return (0); +} + +static int check_redirection(t_token *t, char *input, int *i, int *t_i) +{ + if (input[*i] == '<') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_LESS; + if (input[*i] == '<') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_DLESS; + } + return (1); + } + else if (input[*i] == '>') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_GREAT; + if (input[*i] == '>') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_DGREAT; + } + return (1); + } + return (0); +} diff --git a/srcs/lexing/fill_token.c b/srcs/lexing/fill_token.c new file mode 100644 index 0000000..4367689 --- /dev/null +++ b/srcs/lexing/fill_token.c @@ -0,0 +1,78 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fill_token.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:35:01 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int check_operators(t_token *t, char *input, int *i, int *t_i); + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + +int fill_token(t_token *t, char *input, int *i, int *t_i) +{ + static int in_quotes = 0; + + // operators + if (!in_quotes) + { + if (check_operators(t, input, i, t_i) == DELIMITE_TOKEN) + return (DELIMITE_TOKEN); + } + // quoting + if (input[*i] == '\'' && in_quotes != IN_DQUOTES) + { + t->content[(*t_i)++] = input[(*i)++]; + if (in_quotes == IN_QUOTES) + in_quotes = 0; + else if (ft_strchr(&input[*i], '\'')) // if closed quotes + in_quotes = IN_QUOTES; + return (CONTINUE_TOKEN); + } + else if (input[*i] == '\"' && in_quotes != IN_QUOTES) + { + t->content[(*t_i)++] = input[(*i)++]; + if (in_quotes == IN_DQUOTES) + in_quotes = 0; + else if (ft_strchr(&input[*i], '\"')) // if closed dquotes + in_quotes = IN_DQUOTES; + return (CONTINUE_TOKEN); + } + // blanks + if (!in_quotes && (input[*i] == ' ' || input[*i] == '\t')) + { + while (input[*i] == ' ' || input[*i] == '\t') + (*i)++; + return (DELIMITE_TOKEN); + } + else + t->content[(*t_i)++] = input[(*i)++]; + return (CONTINUE_TOKEN); +} + +/* +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 +1 - OK +2 - OK +3 - OK +4 - OK +5 - OK / SEMI-OSEF +6 - OK +7 - OK +8 - OK +9 - OSEF +10 - OK + +*/ diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c new file mode 100644 index 0000000..33ebd56 --- /dev/null +++ b/srcs/lexing/lexing.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:37:48 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int fill_token(t_token *t, char *input, int *i, int *t_i); + +static t_token *alloc_token(size_t content_len); +static int tokenize_input(t_token *t, char *input, size_t input_len); + +t_token *input_to_tokens(char *input) +{ + t_token *t_head; + t_token *t_tmp; + size_t input_len; + + input_len = ft_strlen(input); + t_head = alloc_token(input_len); + if (!t_head) + return (ft_retp_perror(NULL, "alloc_token() error")); + if (!tokenize_input(t_head, input, input_len)) + return (ft_lstclear((t_list **)&t_head, free)); + t_tmp = (t_token *)ft_lstbeforelast((t_list *)t_head); + if (t_tmp && !t_tmp->next->id) + { + ft_lstdelone((t_list *)t_tmp->next, free); + t_tmp->next = NULL; + } + return (t_head); +} + +static t_token *alloc_token(size_t content_len) +{ + t_token *token; + + token = ft_calloc(1, sizeof (*token)); + if (!token) + return (NULL); + token->content = ft_calloc(content_len + 1, 1); + if (!token->content) + return (ft_retp_free(NULL, token, free)); + return (token); +} + +static int tokenize_input(t_token *t, char *input, size_t input_len) +{ + int i; + int t_i; + + i = 0; + t_i = 0; + while (input[i]) + { + if (fill_token(t, input, &i, &t_i) == DELIMITE_TOKEN && input[i] && t_i) + { + if (!t->id) + t->id = T_WORD; + t->next = alloc_token(input_len - i); + if (!t->next) + return (ft_reti_perror(0, "alloc_token() error")); + t = t->next; + t_i = 0; + } + } + if (!t->id && t_i) + t->id = T_WORD; + return (1); +} diff --git a/srcs/main.c b/srcs/main.c index eb745a5..75de22b 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/10/28 15:12:04 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 13:49:26 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,8 +19,11 @@ int main(int argc, char *argv[], char *envp[]) (void)argc; (void)argv; if (!init(&c, envp)) - exit(EXIT_FAILURE); - shell_loop(&c); + free_exit(&c, EXIT_FAILURE); + if (isatty(STDIN_FILENO)) + shell_loop(&c); + else + shell_script(&c); return (0); } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 96fc2fa..f1d34e4 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -1,3 +1,14 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ +/* Updated: 2021/11/02 13:49:06 by hulamy ### ########.fr */ +/* */ +/* ************************************************************************** */ #include "minishell.h" @@ -54,7 +65,7 @@ t_cmd **parsing(t_token *token_list, char **envp) %start program %% pipeline : command - | pipe_sequence '|' command + | pipeline '|' command ; command : cmd_prefix cmd_name cmd_suffix | cmd_prefix cmd_name diff --git a/srcs/parsing/valid_command.c b/srcs/parsing/valid_command.c index 4c30f2e..eafb625 100644 --- a/srcs/parsing/valid_command.c +++ b/srcs/parsing/valid_command.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_io_redirect(t_token **token_list); static int valid_command_rule1(t_token **token_list); diff --git a/srcs/parsing/valid_pipeline.c b/srcs/parsing/valid_pipeline.c index cda0454..e003d29 100644 --- a/srcs/parsing/valid_pipeline.c +++ b/srcs/parsing/valid_pipeline.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_command(t_token **token_list); int valid_pipeline(t_token **token_list) diff --git a/srcs/parsing/valid_syntax.c b/srcs/parsing/valid_syntax.c index 0fd9f2f..0254712 100644 --- a/srcs/parsing/valid_syntax.c +++ b/srcs/parsing/valid_syntax.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_pipeline(t_token **token_list); int valid_syntax(t_token *token_list) @@ -18,7 +19,7 @@ int valid_syntax(t_token *token_list) if (valid_pipeline(&token_list)) return (1); else - { // WIP ERROR + { ft_putstr_fd("minishell: syntax error near unexpected token \'", 2); ft_putstr_fd(token_list->content, 2); ft_putstr_fd("\'\n", 2); diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 188e909..9d3adb6 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,13 +6,15 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/10/28 20:45:09 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 13:48:36 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static char **tokens_list_to_argv(t_token *t); // temp test +//static char **tokens_list_to_argv(t_token *t); // temp test +void sigint_handler(int signum); //tmp +void sigquit_aka_eof_handler(int signum); //tmp void close_fd(t_cmd *cmd) { @@ -64,11 +66,43 @@ void shell_loop(t_all *c) { add_history(line_input); c->token_list = input_to_tokens(line_input); + + // TEMP + // A faire aprés être sortie du mode interactif + // - Ignorer tout les signaux + // - Remettre ori_termios + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &c->signal_behaviour, NULL); + sigaction(SIGQUIT, &c->signal_behaviour, NULL); + tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); + if (!fork()) + { + char *arg_test[3]; + + arg_test[0] = ft_strdup("sleep"); + arg_test[1] = ft_strdup("3"); + arg_test[2] = NULL; + sigaction(SIGQUIT, &c->ori_signal_behaviour, NULL); + sigaction(SIGINT, &c->ori_signal_behaviour, NULL); + execve("/bin/sleep", arg_test, c->envp); + } + else + { + int wait_test; + wait(&wait_test); + c->signal_behaviour.sa_handler = sigint_handler; + sigaction(SIGINT, &c->signal_behaviour, NULL); + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &c->signal_behaviour, NULL); + tcsetattr(STDIN_FILENO, TCSANOW, &c->interactive_termios); + } + + // EXEC_PIPES_AND_CO() // temp placeholder - if (ft_strncmp(c->token_list->content, "env", 4) == 0) +/* if (ft_strncmp(c->token_list->content, "env", 4) == 0) builtin_env(0, NULL, c); else if (ft_strncmp(c->token_list->content, "exit", 5) == 0) builtin_exit(0, NULL, c); @@ -85,12 +119,14 @@ void shell_loop(t_all *c) // ft_lstprint((t_list *)c->token_list, 1); execute_cmd(c->envp, c->cmd_arr); ft_lstclear((t_list **)&c->token_list, free); - } + } */ } + else if (!line_input) + write(1, "\n", 1); } } -static char **tokens_list_to_argv(t_token *t) // temp test +/* static char **tokens_list_to_argv(t_token *t) // temp test { size_t i; char **argv; @@ -105,29 +141,4 @@ static char **tokens_list_to_argv(t_token *t) // temp test t = t->next; } return (argv); -} - -void wip_test() -{ - char term_desc[2048]; - char *term_type; - int term_width; - int term_height; - int ret; - - term_type = getenv("TERM"); - if (term_type == 0) - ft_putstr_fd("Specify a terminal type with `setenv TERM '.\n", 2); - ret = tgetent(term_desc, term_type); - if (ret < 0) - ft_putstr_fd("Could not access the termcap data base.\n", 2); - if (ret == 0) - ft_putstr_fd("Terminal type `%s' is not defined.\n", 2); - term_height = tgetnum ("li"); - term_width = tgetnum ("co"); - /* Extract information that termcap functions use. */ -/* temp = tgetstr ("pc", BUFFADDR); - PC = temp ? *temp : 0; - BC = tgetstr ("le", BUFFADDR); - UP = tgetstr ("up", BUFFADDR); */ -} +} */ diff --git a/srcs/shell_script.c b/srcs/shell_script.c new file mode 100644 index 0000000..017d4aa --- /dev/null +++ b/srcs/shell_script.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_script.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/26 23:47:44 by lperrey #+# #+# */ +/* Updated: 2021/10/30 15:01:13 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_script(t_all *c) // WIP +{ + ft_putstr_fd("Shell Script Placeholder\n", 1); + free_exit(c, EXIT_SUCCESS); +} diff --git a/srcs/signals.c b/srcs/signals.c new file mode 100644 index 0000000..f715783 --- /dev/null +++ b/srcs/signals.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ +/* Updated: 2021/10/30 14:28:08 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigint_handler(int signum) +{ + // Comment virer LE ^D De l'affichage ? Il ne fait pas partie de "rl_line_buffer". + if (rl_line_buffer && *rl_line_buffer) + { + return ; + } + else + { + free_exit(g_all, g_all->last_exit_status); + } + return ; +} + +/* void sigquit_aka_eof_handler(int signum) +{ + //ft_putstr_fd("TESTS\n", 1); + ft_putstr_fd("\n", 1); + rl_replace_line("", 1); + rl_on_new_line(); + rl_redisplay(); + return ; +} */ + +int set_signals_handling(struct sigaction *ori_signal_behaviour, + struct sigaction *signal_behaviour) +{ + ori_signal_behaviour->sa_handler = SIG_DFL; + + /* ctrl-D exit the shell. + eof = ^D; */ + signal_behaviour->sa_handler = sigint_handler; + sigaction(SIGINT, signal_behaviour, NULL); + + /* ctrl-\ do nothing. + quit = ^\; */ + signal_behaviour->sa_handler = SIG_IGN; + //signal_behaviour->sa_handler = sigquit_aka_eof_handler; + sigaction(SIGQUIT, signal_behaviour, NULL); + + /* + ** remap (^D to ^C) and (^C to ^D) in terminal + ** ^D is now "SIGINT" (handle here) + ** ^C is now EOF (handle in shell_loop()) + */ + return (1); +} + +/* +ctrl-C print a new prompt on a newline. +intr = ^C; +ctrl-D exit the shell. +eof = ^D; +ctrl-\ do nothing. +quit = ^\; +*/ + +/* +speed 38400 baud; rows 22; columns 90; line = 0; +erase = ^?; kill = ^U; +eol = M-^?; eol2 = M-^?; +swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; +discard = ^O; min = 1; time = 0; +-parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts +-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany +imaxbel iutf8 +opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 +isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke +-flusho -extproc +*/ diff --git a/srcs/terminal.c b/srcs/terminal.c new file mode 100644 index 0000000..b33f969 --- /dev/null +++ b/srcs/terminal.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* terminal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/27 00:10:04 by lperrey #+# #+# */ +/* Updated: 2021/10/30 14:17:16 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define CTRL_C 03 +#define CTRL_D 04 +#define CTRL_BACKSLASH 034 + +int set_terminal_attributes(struct termios *ori_termios, + struct termios *interactive_termios, + int *termios_changed) +{ + tcgetattr(STDIN_FILENO, ori_termios); + *interactive_termios = *ori_termios; + + interactive_termios->c_cc[VINTR] = CTRL_D; + interactive_termios->c_cc[VEOF] = CTRL_C; + + //interactive_termios->c_cc[VQUIT] = CTRL_C; + //interactive_termios->c_cc[VEOF] = CTRL_BACKSLASH; + + //interactive_termios->c_cc[VEOL] = CTRL_C; + + *termios_changed = 1; + tcsetattr(STDIN_FILENO, TCSANOW, interactive_termios); + + return (1); +} + + //printf("STDIN_FILENO = %s\n ", ttyname(STDIN_FILENO)); + //printf("STDOUT_FILENO = %s\n ", ttyname(STDOUT_FILENO)); + //printf("STDERR_FILENO = %s\n ", ttyname(STDERR_FILENO)); + //ft_putendl_fd(ttyname(STDIN_FILENO), 1); + //ft_putendl_fd(ttyname(STDOUT_FILENO), 1); + //ft_putendl_fd(ttyname(STDERR_FILENO), 1); + // ft_printf("BEFORE\n"); + // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); + // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); + // ft_printf("AFTER\n"); + // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); + // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); + +void wip_test() +{ + char term_desc[2048]; + char *term_type; + int term_width; + int term_height; + int ret; + + term_type = getenv("TERM"); + if (term_type == 0) + ft_putstr_fd("Specify a terminal type with `setenv TERM '.\n", 2); + ret = tgetent(term_desc, term_type); + if (ret < 0) + ft_putstr_fd("Could not access the termcap data base.\n", 2); + if (ret == 0) + ft_putstr_fd("Terminal type `%s' is not defined.\n", 2); + term_height = tgetnum ("li"); + term_width = tgetnum ("co"); + /* Extract information that termcap functions use. */ +/* temp = tgetstr ("pc", BUFFADDR); + PC = temp ? *temp : 0; + BC = tgetstr ("le", BUFFADDR); + UP = tgetstr ("up", BUFFADDR); */ +} diff --git a/valgrind_readline.supp b/valgrind_readline.supp index b632bcc..f1f3bc4 100644 --- a/valgrind_readline.supp +++ b/valgrind_readline.supp @@ -4,3 +4,10 @@ ... fun:readline } + +{ + + Memcheck:Leak + ... + fun:add_history +}