From 0a5c7545c1c042933335b0fe36620536da120cd2 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 7 Nov 2021 04:41:17 +0100 Subject: [PATCH 01/10] WIP parsing expansions --- Makefile | 6 +- headers/minishell_prototypes.h | 10 +- libft | 2 +- srcs/{execute.c => HUGO_WIP_execute.c} | 63 ++--- srcs/generic.c | 26 +- srcs/lexing/lexing.c | 6 +- srcs/parsing/HUGO_WIP.c | 189 +++++++++++++ srcs/parsing/alloc_cmd_array.c | 49 ++++ srcs/parsing/expansions/expand_token.c | 113 ++++++++ .../expansions/new_token_for_each_field.c | 61 +++++ srcs/parsing/expansions/rejoin_after_expand.c | 39 +++ srcs/parsing/expansions/words_expansions.c | 69 +++++ srcs/parsing/parsing.c | 251 ++---------------- .../{ => valid_syntax}/valid_command.c | 0 .../{ => valid_syntax}/valid_io_redirect.c | 0 .../{ => valid_syntax}/valid_pipeline.c | 0 .../parsing/{ => valid_syntax}/valid_syntax.c | 0 srcs/shell_loop.c | 102 +++---- 18 files changed, 631 insertions(+), 355 deletions(-) rename srcs/{execute.c => HUGO_WIP_execute.c} (55%) create mode 100644 srcs/parsing/HUGO_WIP.c create mode 100644 srcs/parsing/alloc_cmd_array.c create mode 100644 srcs/parsing/expansions/expand_token.c create mode 100644 srcs/parsing/expansions/new_token_for_each_field.c create mode 100644 srcs/parsing/expansions/rejoin_after_expand.c create mode 100644 srcs/parsing/expansions/words_expansions.c rename srcs/parsing/{ => valid_syntax}/valid_command.c (100%) rename srcs/parsing/{ => valid_syntax}/valid_io_redirect.c (100%) rename srcs/parsing/{ => valid_syntax}/valid_pipeline.c (100%) rename srcs/parsing/{ => valid_syntax}/valid_syntax.c (100%) diff --git a/Makefile b/Makefile index 0f7d936..389f2be 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ CC = clang CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) -DIR_SRCS = srcs srcs/builtins srcs/lexing srcs/parsing +DIR_SRCS = srcs srcs/builtins srcs/lexing \ + srcs/parsing srcs/parsing/valid_syntax srcs/parsing/expansions INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) @@ -25,8 +26,9 @@ SRCS = main.c init.c free.c generic.c \ signals.c terminal.c \ shell_loop.c shell_script.c \ lexing.c fill_token.c check_operators.c \ - parsing.c \ + parsing.c alloc_cmd_array.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ + words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ env.c exit.c echo.c DIR_OBJS = builds diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index d1724d2..10c4cd9 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/11/02 14:03:51 by hulamy ### ########.fr */ +/* Updated: 2021/11/07 04:13:53 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,12 +29,13 @@ void shell_script(t_all *c); t_token *input_to_tokens(char *input); // Parser -t_cmd **parsing(t_token *token_list, char **envp); +t_cmd **parsing(t_token *token_list); int valid_syntax(t_token *token_list); int valid_token(t_token **token_list, enum e_token_id token_id); int valid_command_separator(const t_token *token_list); -t_cmd **fill_cmd(t_token *token, char **envp); -void cmd_expansion(t_cmd **cmd_arr, char **envp); +size_t count_pipes(t_token *token); +t_cmd **alloc_cmd_array(size_t cmd_nbr); +int words_expansions(t_token *t); // Builtins int builtin_env(int argc, char *argv[], t_all *c); @@ -55,5 +56,6 @@ 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); t_list *ft_lstbeforelast(t_list *lst); +t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); #endif diff --git a/libft b/libft index 1401fdd..1e8aaa7 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 1401fddfcd177d8794d41a8c7dd3b806bbb5057f +Subproject commit 1e8aaa7154cbae5f7a200ca20323ece66c99fdd3 diff --git a/srcs/execute.c b/srcs/HUGO_WIP_execute.c similarity index 55% rename from srcs/execute.c rename to srcs/HUGO_WIP_execute.c index 2933074..307d8ae 100644 --- a/srcs/execute.c +++ b/srcs/HUGO_WIP_execute.c @@ -8,47 +8,36 @@ void close_fd(t_cmd *cmd) close(cmd->fd_out); } -void exec_cmd(char **envp, t_list *cmd_list) +void execute_cmd(char **envp, t_cmd **cmd_arr) { - t_cmd *cmd; pid_t pid; pid_t wpid; int status; + int i; - while(cmd_list) + i = 0; + while(cmd_arr[i]) { - cmd = cmd_list->content; pid = fork(); if (pid == 0) { - if (cmd->fd_in != 0) - dup2(cmd->fd_in, STDIN_FILENO); - if (cmd->fd_out != 1) - dup2(cmd->fd_out, STDOUT_FILENO); - close_fd(cmd); - execve(cmd->argv[0], cmd->argv, envp); + if (cmd_arr[i]->fd_in != 0) + dup2(cmd_arr[i]->fd_in, STDIN_FILENO); + if (cmd_arr[i]->fd_out != 1) + dup2(cmd_arr[i]->fd_out, STDOUT_FILENO); + //close_fd(cmd_arr[i]); + //Must close all fds, not just the two cmd_arr[i] fd + execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); } else - close_fd(cmd); - cmd_list = cmd_list->next; + close_fd(cmd_arr[i]); // Close here or after all execve() for simplicity ? + i++; } // waitpid pour la derniere commande (pour '$?') while ((wpid = wait(&status)) > 0); } -int nbr_pipes(char *input) -{ - int i; - int count; - - i = -1; - count = 0; - while (input[++i]) - if (input[i] == '|') - count++; - return (count); -} - +/* int handle_fdd(char *input, int fdin, t_cmd *cmd) { int *pipes_fd; @@ -85,26 +74,4 @@ int handle_fdd(char *input, int fdin, t_cmd *cmd) } printf(" handle_fd: %s\n", input); return (next_in); -} - -t_cmd *fill_cmd(char *input, char **envp) -{ - t_cmd *cmd; - char **input_split; - int i; - int tmp_fd; - - cmd = calloc(nbr_pipes(input), sizeof(t_cmd)); - input_split = ft_split(input, '|'); - tmp_fd = 0; - i = 0; - while (input_split[i]) - { - tmp_fd = handle_fdd(input_split[i], tmp_fd, &cmd[i]); - cmd[i].argv = ft_split(input_split[i], ' '); - cmd[i].builtin = cmd_path(cmd[i].argv, envp); - i++; - } - return (cmd); -} - +} */ diff --git a/srcs/generic.c b/srcs/generic.c index 9426b83..2d56cc4 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/11/02 13:52:23 by hulamy ### ########.fr */ +/* Updated: 2021/11/07 04:07:10 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -150,3 +150,27 @@ t_list *ft_lstbeforelast(t_list *lst) lst = lst->next; return (lst); } + +t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size) +{ + t_list *elem; + void *content; + + if (content_size == 0) + content = NULL; + else + { + content = ft_calloc(content_size, 1); + if (!content) + return (NULL); + } + elem = ft_calloc(1, lst_sizse); + if (!elem) + { + free(content); + return (NULL); + } + elem->content = content; + elem->next = NULL; + return (elem); +} diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c index 33ebd56..920e277 100644 --- a/srcs/lexing/lexing.c +++ b/srcs/lexing/lexing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/30 22:37:48 by lperrey ### ########.fr */ +/* Updated: 2021/11/07 03:18:38 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ int fill_token(t_token *t, char *input, int *i, int *t_i); -static t_token *alloc_token(size_t content_len); +static t_token *alloc_token(size_t content_len); // TODO, a remplacer par ft_lstnew_generic() static int tokenize_input(t_token *t, char *input, size_t input_len); t_token *input_to_tokens(char *input) @@ -30,7 +30,7 @@ t_token *input_to_tokens(char *input) 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) + if (t_tmp && t_tmp->next && !t_tmp->next->id) { ft_lstdelone((t_list *)t_tmp->next, free); t_tmp->next = NULL; diff --git a/srcs/parsing/HUGO_WIP.c b/srcs/parsing/HUGO_WIP.c new file mode 100644 index 0000000..d37fdb5 --- /dev/null +++ b/srcs/parsing/HUGO_WIP.c @@ -0,0 +1,189 @@ + +#include "minishell.h" + +int is_redirection(enum e_token_id id) +{ + if (id == T_LESS) // < + return (1); + else if (id == T_GREAT) // > + return (1); + else if (id == T_DLESS) // << + return (1); + else if (id == T_DGREAT) // >> + return (1); + else + return (0); +} + +// count nbr word in cmd, minus redirection and heredoc +int next_cmd(t_token *token) +{ + int i; + + i = 0; + while (token && token->id != T_PIPE) + { + if (is_redirection(token->id)) + i--; + else + i++; + token = token->next; + } + if (token && token->id == T_PIPE) + token = token->next; + return (i); +} + +void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr) +{ + int argc; + int j; + int i; + int redirection; + + i = 0; + while (cmd_nbr) + { + argc = next_cmd(token); + cmd[i]->argv = calloc(argc + 1, sizeof(char *)); + cmd[i]->argv[argc] = NULL; + j = 0; + redirection = is_redirection(token->id); + while (token && token->id != T_PIPE) + { + if (!redirection && token->id == T_WORD) + { + cmd[i]->argv[j] = ft_strdup(token->content); + j++; + } + redirection = is_redirection(token->id); + token = token->next; + } + if (token && token->id == T_PIPE) + token = token->next; + cmd_nbr--; + i++; + } +} + +int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) +{ + cmd->builtin_command = &builtin; + return (1); +} + +int handle_builtin(t_cmd *cmd) +{ + if (!ft_strncmp(cmd->argv[0], "echo", 4)) + return (fill_builtin(cmd, &builtin_echo)); +// else if (!ft_strncmp(cmd->argv[0], "cd", 2)) +// return (fill_builtin(cmd, &builtin_cd)); +// else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) +// return (fill_builtin(cmd, &builtin_pwd)); +// else if (!ft_strncmp(cmd->argv[0], "export", 6)) +// return (fill_builtin(cmd, &builtin_export)); +// else if (!ft_strncmp(cmd->argv[0], "unset", 5)) +// return (fill_builtin(cmd, &builtin_unset)); + else if (!ft_strncmp(cmd->argv[0], "env", 3)) + return (fill_builtin(cmd, &builtin_env)); + else if (!ft_strncmp(cmd->argv[0], "exit", 4)) + return (fill_builtin(cmd, &builtin_exit)); + return (0); +} + +void find_path(char **argv, char **envp) +{ + int i; + char **path; + char *cmd; + + i = 0; + while (envp[i] && ft_strncmp(envp[i], "PATH=", 5)) + i++; + path = ft_split(envp[i] + 5, ':'); // 5 = lentgh of "PATH=" + i = -1; + while (*path && i != 0) + { + cmd = ft_strjoin(path[0], "/"); + cmd = ft_strjoin(cmd, argv[0]); + i = access(cmd, X_OK); + path++; + } + if (!(*path)) + exit(0); // gerer erreur + argv[0] = cmd; +} + +void handle_path(t_cmd **cmd_arr, char **envp) +{ + int i; + + i = 0; + while (cmd_arr[i]) + { + if (!handle_builtin(cmd_arr[i])) + find_path(cmd_arr[i]->argv, envp); + i++; + } +} + +void fd_redirection(t_token *token, t_cmd *cmd) +{ + int flag; + + if (token->id == T_LESS) // '<' + { + flag = O_RDONLY | O_CREAT; + if (cmd->fd_in != 0) + close(cmd->fd_in); + cmd->fd_in = open(token->next->content, flag); + } + else if (token->id == T_GREAT) // '>' + { + flag = O_WRONLY | O_CREAT | O_TRUNC; + cmd->fd_out = open(token->next->content, flag, S_IRWXU); + } + else if (token->id == T_DGREAT) // '>>' + { + flag = O_WRONLY | O_CREAT | O_APPEND; + cmd->fd_out = open(token->next->content, flag, S_IRWXU); + } +} + +void fd_heredoc(t_token *token, t_cmd *cmd) +{ + (void)token; + (void)cmd; +} + +void handle_fd(t_token *token, t_cmd **cmd_arr) +{ + int *pipes_fd; + int i; + + i = 0; + while (cmd_arr[i]) + { + cmd_arr[i]->fd_out = 1; + while (token && token->id != T_PIPE) + { + if (token->id == T_DGREAT) // '<<' + fd_heredoc(token, cmd_arr[i]); + else + fd_redirection(token, cmd_arr[i]); + token = token->next; + } + if (token && token->id == T_PIPE) + { + token = token->next; + pipes_fd = calloc(2, sizeof(int)); + pipe(pipes_fd); + if (cmd_arr[i]->fd_out == 1) + cmd_arr[i]->fd_out = pipes_fd[1]; + else + close(pipes_fd[1]); + cmd_arr[i + 1]->fd_in = pipes_fd[0]; + } + i++; + } +} diff --git a/srcs/parsing/alloc_cmd_array.c b/srcs/parsing/alloc_cmd_array.c new file mode 100644 index 0000000..edd67c3 --- /dev/null +++ b/srcs/parsing/alloc_cmd_array.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* alloc_cmd_array.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/02 22:46:23 by lperrey #+# #+# */ +/* Updated: 2021/11/07 04:29:54 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +size_t count_pipes(t_token *token) +{ + size_t count; + + count = 0; + while (token) + { + if (token->id == T_PIPE) + count++; + token = token->next; + } + return (count); +} + +t_cmd **alloc_cmd_array(size_t cmd_nbr) +{ + t_cmd **cmd_arr; + size_t i; + + cmd_arr = ft_calloc(cmd_nbr + 1, sizeof (void *)); + if (!cmd_arr) + return (ft_retp_perror(NULL, "alloc_cmd()")); + i = 0; + while (i < cmd_nbr) + { + cmd_arr[i] = ft_calloc(1, sizeof (*cmd_arr[i])); + if (!cmd_arr[i]) + { + ft_free_2d_arr(cmd_arr); + return (ft_retp_perror(NULL, "alloc_cmd()")); + } + i++; + } + return (cmd_arr); +} diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c new file mode 100644 index 0000000..da78916 --- /dev/null +++ b/srcs/parsing/expansions/expand_token.c @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_token.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ +/* Updated: 2021/11/07 04:36:12 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + +static t_list *ret_parameter_expansion(t_token *t, int *i); + +t_list *expand_token(t_token *t) +{ + int in_quotes; + int i; + t_list head; + t_list *expand; + + in_quotes = 0; + i = 0; + head.next = NULL; + expand = &head; + while (t->content[i]) + { + if (t->content[i] == '$') + { + expand->next = ret_parameter_expansion(t, &i); + if (!expand->next) + {//todo wrap + perror("expand_token() error"); + return (ft_lstclear(&head.next, free)); + } + } + else + { + expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&t->content[i]) + 1); + if (!expand->next) + {//todo wrap + perror("expand_token() error"); + return (ft_lstclear(&head.next, free)); + } + while (t->content[i] && (t->content[i] != '$' && in_quotes != IN_QUOTES)) + { + // quoting + if (t->content[i] == '\'' && in_quotes != IN_DQUOTES) + { + if (in_quotes == IN_QUOTES) + in_quotes = 0; + else + in_quotes = IN_QUOTES; + } + i++; + } + } + } + return (head.next); +} + +// a voir si je retourne pas plutot un "char *". +// Malloc la lst dans la fonction est peut-être un peu superflu et pas super clair. +// et aussi changer "t_token *t" en "char *content", inutile d'avoir le token entier. +static t_list *ret_parameter_expansion(t_token *t, int *i) +{ + t_list *expand; + char *tmp; + int i_tmp; + + tmp = ft_calloc(ft_strlen(&t->content[*i]) + 1, 1); + if (!tmp) + return (NULL); + expand = ft_lstnew(NULL); + if (!expand) + return (ft_retp_free(NULL, tmp, free)); + (*i)++; // skip '$' + if (t->content[*i] == '?') + { + i++; + expand->content = ft_itoa(g_all->last_exit_status); + return (ft_retp_free(expand, tmp, free)); + } + else if (t->content[*i] != '_' && !ft_isalpha(t->content[*i])) + { + tmp[0] = '$'; + expand->content = tmp; + return (expand); + } + i_tmp = 0; + while (t->content[*i] == '_' || ft_isalnum(t->content[*i])) + tmp[i_tmp++] = t->content[*i++]; + expand->content = getenv(tmp); + free(tmp); + if (expand->content) + expand->content = ft_strdup(expand->content); + else + expand->content = ft_calloc(1, 1); + if (!expand->content) + return (ft_retp_free(NULL, expand, free)); + return (expand); +} diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c new file mode 100644 index 0000000..10236bd --- /dev/null +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -0,0 +1,61 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* new_token_for_each_field.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ +/* Updated: 2021/11/07 04:33:04 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); + +static t_token *insert_tokens(t_token *t, t_token *insert_lst); + +int new_token_for_each_field(char **fields, t_token **t) +{ + t_token head; + t_token *insert_lst; + int i; + + head.next = NULL; + insert_lst = &head; + i = 0; + while (fields[i]) + { + insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(*insert_lst), 0); + if (!insert_lst->next) + {//todo wrap + perror("insert_token_for_each_field() error"); + ft_free_2d_arr(fields); + return ((int)ft_lstclear((t_list **)&head.next, NULL)); + } + insert_lst = insert_lst->next; + insert_lst->content = fields[i]; + insert_lst->id = T_WORD; + } + free(fields); + *t = insert_tokens(*t, insert_lst); + return (1); +} + +static t_token *insert_tokens(t_token *t, t_token *insert_lst) +{ + t_token *tmp; + t_token *insert_lst_last; + + t->id = 0; + free(t->content); + t->content = NULL; + + tmp = t->next; + t->next = insert_lst; + insert_lst_last = (t_token *)ft_lstlast((t_list *)insert_lst); + insert_lst_last->next = tmp; + + return (insert_lst_last); +} diff --git a/srcs/parsing/expansions/rejoin_after_expand.c b/srcs/parsing/expansions/rejoin_after_expand.c new file mode 100644 index 0000000..c56c98b --- /dev/null +++ b/srcs/parsing/expansions/rejoin_after_expand.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rejoin_after_expand.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ +/* Updated: 2021/11/07 04:03:02 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *rejoin_after_expand(t_list *expand_lst) +{ + t_list *head; + char *result; + + head = expand_lst; + result = ft_calloc(1, 1); + if (!result) + {//todo wrap + perror("rejoin_after_expand() error"); + return (ft_lstclear(&head, free)); + } + while (expand_lst) + { + result = ft_strjoinfree_s1(result, expand_lst->content); + if (!result) + {//todo wrap + perror("rejoin_after_expand() error"); + return (ft_lstclear(&head, free)); + } + expand_lst = expand_lst->next; + } + ft_lstclear(&head, free); + return (result); +} diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c new file mode 100644 index 0000000..b878ead --- /dev/null +++ b/srcs/parsing/expansions/words_expansions.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* words_expansions.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ +/* Updated: 2021/11/07 04:36:52 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + +t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); +t_list *expand_token(t_token *t); +char *rejoin_after_expand(t_list *expand_lst); +int new_token_for_each_field(char **fields, t_token **t); + +// 1 - chaque bout dans un element d'une t_list +// (telle quelle si non expand, ou VARIABLE de env) +// 2 - strjoin() le tout +// 3 - split avec un ft_strplit() modifié (ne splitant pas dans les quotes) +// 4 - creer un token T_WORD pour chaque *string du **split_arr +// (ft_lstadd_front() sur le token original, puis set le token orignal à : +// t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing) + +int words_expansions(t_token *t) +{ + void *tmp_expand; + char **tmp_split; + + while (t) + { + if (t->id == T_WORD) + { + // 1 + tmp_expand = expand_token(t); + if (!tmp_expand) + return (0); + if (((t_list*)tmp_expand)->next) + { + // 2 + tmp_expand = rejoin_after_expand(tmp_expand); + if (!tmp_expand) + return (0); + // 3 WIP PLACEHOLDER, MUST WRITE A ft_split_quoted() FOR NO SPLIT IN QUOTES + tmp_split = ft_split(tmp_expand, ' '); + free(tmp_expand); + if (!tmp_split) + return (0); + // 4 + if (!new_token_for_each_field(tmp_split, &t)) + return (0); + } + else + ft_lstclear((t_list **)&tmp_expand, free); + } + t = t->next; + } + return (1); +} diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 9c01d48..b96df90 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,14 +6,13 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/02 13:49:06 by hulamy ### ########.fr */ +/* Updated: 2021/11/07 04:37:30 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -size_t count_pipes(t_token *token); -t_cmd **create_cmd(t_token *token_list, size_t cmd_nbr); +// HUGO WIP void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr); void handle_path(t_cmd **cmd_arr, char **envp); void handle_fd(t_token *token, t_cmd **cmd_arr); @@ -24,243 +23,35 @@ int handle_builtin(t_cmd *cmd); int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)); int next_cmd(t_token *token); int is_redirection(enum e_token_id id); +// HUGO WIP -t_cmd **parsing(t_token *token_list, char **envp) +t_cmd **parsing(t_token *token_list) { t_cmd **cmd_arr; - size_t cmd_nbr; if (!valid_syntax(token_list)) return (NULL); - cmd_nbr = count_pipes(token_list); - cmd_arr = create_cmd(token_list, cmd_nbr); + // Struct CMD alloc + cmd_arr = alloc_cmd_array(count_pipes(token_list) + 1); + if (!cmd_arr) + return (NULL); + + // 2.9.1 - 2) Expansion + words_expansions(token_list); + + // 2.9.1 - 3) Redirection + + // Struct CMD fill + + + // HUGO WIP // cmd_expansion(cmd_arr, envp); - handle_argv(token_list, cmd_arr, cmd_nbr); - handle_path(cmd_arr, envp); - handle_fd(token_list, cmd_arr); +// handle_argv(token_list, cmd_arr, cmd_nbr); +// handle_path(cmd_arr, envp); +// handle_fd(token_list, cmd_arr); return (cmd_arr); } -size_t count_pipes(t_token *token) -{ - size_t nb; - - nb = 0; - while (token) - { - if (token->id == T_PIPE) - nb++; - token = token->next; - } - return (nb + 1); -} - -t_cmd **create_cmd(t_token *token_list, size_t cmd_nbr) -{ - t_cmd **cmd_arr; - size_t i; - - (void)token_list; - cmd_arr = ft_calloc(cmd_nbr + 1, sizeof(t_cmd *)); - cmd_arr[cmd_nbr] = NULL; - i = 0; - while (i < cmd_nbr) - { - cmd_arr[i] = ft_calloc(1, sizeof(t_cmd)); - ft_bzero(cmd_arr[i], sizeof(t_cmd)); - i++; - } - return (cmd_arr); -} - -int is_redirection(enum e_token_id id) -{ - if (id == T_LESS) // < - return (1); - else if (id == T_GREAT) // > - return (1); - else if (id == T_DLESS) // << - return (1); - else if (id == T_DGREAT) // >> - return (1); - else - return (0); -} - -// count nbr word in cmd, minus redirection and heredoc -int next_cmd(t_token *token) -{ - int i; - - i = 0; - while (token && token->id != T_PIPE) - { - if (is_redirection(token->id)) - i--; - else - i++; - token = token->next; - } - if (token && token->id == T_PIPE) - token = token->next; - return (i); -} - -void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr) -{ - int argc; - int j; - int i; - int redirection; - - i = 0; - while (cmd_nbr) - { - argc = next_cmd(token); - cmd[i]->argv = calloc(argc + 1, sizeof(char *)); - cmd[i]->argv[argc] = NULL; - j = 0; - redirection = is_redirection(token->id); - while (token && token->id != T_PIPE) - { - if (!redirection && token->id == T_WORD) - { - cmd[i]->argv[j] = ft_strdup(token->content); - j++; - } - redirection = is_redirection(token->id); - token = token->next; - } - if (token && token->id == T_PIPE) - token = token->next; - cmd_nbr--; - i++; - } -} - -int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) -{ - cmd->builtin_command = &builtin; - return (1); -} - -int handle_builtin(t_cmd *cmd) -{ - if (!ft_strncmp(cmd->argv[0], "echo", 4)) - return (fill_builtin(cmd, &builtin_echo)); -// else if (!ft_strncmp(cmd->argv[0], "cd", 2)) -// return (fill_builtin(cmd, &builtin_cd)); -// else if (!ft_strncmp(cmd->argv[0], "pwd", 3)) -// return (fill_builtin(cmd, &builtin_pwd)); -// else if (!ft_strncmp(cmd->argv[0], "export", 6)) -// return (fill_builtin(cmd, &builtin_export)); -// else if (!ft_strncmp(cmd->argv[0], "unset", 5)) -// return (fill_builtin(cmd, &builtin_unset)); - else if (!ft_strncmp(cmd->argv[0], "env", 3)) - return (fill_builtin(cmd, &builtin_env)); - else if (!ft_strncmp(cmd->argv[0], "exit", 4)) - return (fill_builtin(cmd, &builtin_exit)); - return (0); -} - -void find_path(char **argv, char **envp) -{ - int i; - char **path; - char *cmd; - - i = 0; - while (envp[i] && ft_strncmp(envp[i], "PATH=", 5)) - i++; - path = ft_split(envp[i] + 5, ':'); // 5 = lentgh of "PATH=" - i = -1; - while (*path && i != 0) - { - cmd = ft_strjoin(path[0], "/"); - cmd = ft_strjoin(cmd, argv[0]); - i = access(cmd, X_OK); - path++; - } - if (!(*path)) - exit(0); // gerer erreur - argv[0] = cmd; -} - -void handle_path(t_cmd **cmd_arr, char **envp) -{ - int i; - - i = 0; - while (cmd_arr[i]) - { - if (!handle_builtin(cmd_arr[i])) - find_path(cmd_arr[i]->argv, envp); - i++; - } -} - -void fd_redirection(t_token *token, t_cmd *cmd) -{ - int flag; - - if (token->id == T_LESS) // '<' - { - flag = O_RDONLY | O_CREAT; - if (cmd->fd_in != 0) - close(cmd->fd_in); - cmd->fd_in = open(token->next->content, flag); - } - else if (token->id == T_GREAT) // '>' - { - flag = O_WRONLY | O_CREAT | O_TRUNC; - cmd->fd_out = open(token->next->content, flag, S_IRWXU); - } - else if (token->id == T_DGREAT) // '>>' - { - flag = O_WRONLY | O_CREAT | O_APPEND; - cmd->fd_out = open(token->next->content, flag, S_IRWXU); - } -} - -void fd_heredoc(t_token *token, t_cmd *cmd) -{ - (void)token; - (void)cmd; -} - -void handle_fd(t_token *token, t_cmd **cmd_arr) -{ - int *pipes_fd; - int i; - - i = 0; - while (cmd_arr[i]) - { - cmd_arr[i]->fd_out = 1; - while (token && token->id != T_PIPE) - { - if (token->id == T_DGREAT) // '<<' - fd_heredoc(token, cmd_arr[i]); - else - fd_redirection(token, cmd_arr[i]); - token = token->next; - } - if (token && token->id == T_PIPE) - { - token = token->next; - pipes_fd = calloc(2, sizeof(int)); - pipe(pipes_fd); - if (cmd_arr[i]->fd_out == 1) - cmd_arr[i]->fd_out = pipes_fd[1]; - else - close(pipes_fd[1]); - cmd_arr[i + 1]->fd_in = pipes_fd[0]; - } - i++; - } -} - - /* ------------------------------------------------------- The grammar symbols ------------------------------------------------------- */ diff --git a/srcs/parsing/valid_command.c b/srcs/parsing/valid_syntax/valid_command.c similarity index 100% rename from srcs/parsing/valid_command.c rename to srcs/parsing/valid_syntax/valid_command.c diff --git a/srcs/parsing/valid_io_redirect.c b/srcs/parsing/valid_syntax/valid_io_redirect.c similarity index 100% rename from srcs/parsing/valid_io_redirect.c rename to srcs/parsing/valid_syntax/valid_io_redirect.c diff --git a/srcs/parsing/valid_pipeline.c b/srcs/parsing/valid_syntax/valid_pipeline.c similarity index 100% rename from srcs/parsing/valid_pipeline.c rename to srcs/parsing/valid_syntax/valid_pipeline.c diff --git a/srcs/parsing/valid_syntax.c b/srcs/parsing/valid_syntax/valid_syntax.c similarity index 100% rename from srcs/parsing/valid_syntax.c rename to srcs/parsing/valid_syntax/valid_syntax.c diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 878be8a..0e7349e 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/02 14:15:04 by hulamy ### ########.fr */ +/* Updated: 2021/11/02 22:38:35 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,80 +32,50 @@ void shell_loop(t_all *c) if (line_input && *line_input) { add_history(line_input); + //test_signal(c); + // Lexing 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 - c->cmd_arr = parsing(c->token_list, c->envp); - execute_cmd(c->envp, c->cmd_arr); + // Parsing + c->cmd_arr = parsing(c->token_list); ft_lstclear((t_list **)&c->token_list, free); + // Search Path/builtins + // Exec + //execute_cmd(c->envp, c->cmd_arr); } else if (!line_input) write(1, "\n", 1); } } -void close_fd(t_cmd *cmd) +void test_signal(t_all *c) { - if (cmd->fd_in != 0) - close(cmd->fd_in); - if (cmd->fd_out != 1) - close(cmd->fd_out); -} - -void execute_cmd(char **envp, t_cmd **cmd_arr) -{ - pid_t pid; - pid_t wpid; - int status; - int i; - - i = 0; - while(cmd_arr[i]) + // 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()) { - pid = fork(); - if (pid == 0) - { - if (cmd_arr[i]->fd_in != 0) - dup2(cmd_arr[i]->fd_in, STDIN_FILENO); - if (cmd_arr[i]->fd_out != 1) - dup2(cmd_arr[i]->fd_out, STDOUT_FILENO); - close_fd(cmd_arr[i]); - execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); - } - else - close_fd(cmd_arr[i]); - i++; + 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); } - // waitpid pour la derniere commande (pour '$?') - while ((wpid = wait(&status)) > 0); } From 0ae84abb14d8be98ed052f9c96b4084271bdf1d6 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Mon, 8 Nov 2021 04:02:43 +0100 Subject: [PATCH 02/10] bugfix expansions --- srcs/parsing/expansions/expand_token.c | 16 ++++++---- .../expansions/new_token_for_each_field.c | 9 ++++-- srcs/parsing/expansions/words_expansions.c | 31 ++++++++----------- srcs/parsing/parsing.c | 10 ++++-- 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c index da78916..1b46df2 100644 --- a/srcs/parsing/expansions/expand_token.c +++ b/srcs/parsing/expansions/expand_token.c @@ -27,6 +27,7 @@ t_list *expand_token(t_token *t) { int in_quotes; int i; + int i_exp; t_list head; t_list *expand; @@ -39,7 +40,8 @@ t_list *expand_token(t_token *t) if (t->content[i] == '$') { expand->next = ret_parameter_expansion(t, &i); - if (!expand->next) + expand = expand->next; + if (!expand) {//todo wrap perror("expand_token() error"); return (ft_lstclear(&head.next, free)); @@ -48,12 +50,14 @@ t_list *expand_token(t_token *t) else { expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&t->content[i]) + 1); - if (!expand->next) + expand = expand->next; + i_exp = 0; + if (!expand) {//todo wrap perror("expand_token() error"); return (ft_lstclear(&head.next, free)); } - while (t->content[i] && (t->content[i] != '$' && in_quotes != IN_QUOTES)) + while (t->content[i] && (t->content[i] != '$' || in_quotes == IN_QUOTES)) { // quoting if (t->content[i] == '\'' && in_quotes != IN_DQUOTES) @@ -63,7 +67,7 @@ t_list *expand_token(t_token *t) else in_quotes = IN_QUOTES; } - i++; + ((char *)expand->content)[i_exp++] = t->content[i++]; } } } @@ -88,7 +92,7 @@ static t_list *ret_parameter_expansion(t_token *t, int *i) (*i)++; // skip '$' if (t->content[*i] == '?') { - i++; + (*i)++; expand->content = ft_itoa(g_all->last_exit_status); return (ft_retp_free(expand, tmp, free)); } @@ -100,7 +104,7 @@ static t_list *ret_parameter_expansion(t_token *t, int *i) } i_tmp = 0; while (t->content[*i] == '_' || ft_isalnum(t->content[*i])) - tmp[i_tmp++] = t->content[*i++]; + tmp[i_tmp++] = t->content[(*i)++]; expand->content = getenv(tmp); free(tmp); if (expand->content) diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index 10236bd..c3ee91c 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -28,18 +28,19 @@ int new_token_for_each_field(char **fields, t_token **t) while (fields[i]) { insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(*insert_lst), 0); - if (!insert_lst->next) + insert_lst = insert_lst->next; + if (!insert_lst) {//todo wrap perror("insert_token_for_each_field() error"); ft_free_2d_arr(fields); return ((int)ft_lstclear((t_list **)&head.next, NULL)); } - insert_lst = insert_lst->next; insert_lst->content = fields[i]; insert_lst->id = T_WORD; + i++; } free(fields); - *t = insert_tokens(*t, insert_lst); + *t = insert_tokens(*t, head.next); return (1); } @@ -51,6 +52,8 @@ static t_token *insert_tokens(t_token *t, t_token *insert_lst) t->id = 0; free(t->content); t->content = NULL; + if (!insert_lst) + return (t); tmp = t->next; t->next = insert_lst; diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index b878ead..36f5288 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/07 04:36:52 by lperrey ### ########.fr */ +/* Updated: 2021/11/08 03:59:02 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,23 +45,18 @@ int words_expansions(t_token *t) tmp_expand = expand_token(t); if (!tmp_expand) return (0); - if (((t_list*)tmp_expand)->next) - { - // 2 - tmp_expand = rejoin_after_expand(tmp_expand); - if (!tmp_expand) - return (0); - // 3 WIP PLACEHOLDER, MUST WRITE A ft_split_quoted() FOR NO SPLIT IN QUOTES - tmp_split = ft_split(tmp_expand, ' '); - free(tmp_expand); - if (!tmp_split) - return (0); - // 4 - if (!new_token_for_each_field(tmp_split, &t)) - return (0); - } - else - ft_lstclear((t_list **)&tmp_expand, free); + // 2 + tmp_expand = rejoin_after_expand(tmp_expand); + if (!tmp_expand) + return (0); + // 3 WIP PLACEHOLDER, MUST WRITE A ft_split_quoted() FOR NO SPLIT IN QUOTES + tmp_split = ft_split(tmp_expand, ' '); + free(tmp_expand); + if (!tmp_split) + return (0); + // 4 + if (!new_token_for_each_field(tmp_split, &t)) + return (0); } t = t->next; } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index b96df90..d55ad04 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/07 04:37:30 by lperrey ### ########.fr */ +/* Updated: 2021/11/08 01:03:29 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,13 +37,19 @@ t_cmd **parsing(t_token *token_list) return (NULL); // 2.9.1 - 2) Expansion + // TEST TOKENS PRINT + ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); + ft_lstprint((t_list *)token_list, 1); + // words_expansions(token_list); + // + ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1); + ft_lstprint((t_list *)token_list, 1); // 2.9.1 - 3) Redirection // Struct CMD fill - // HUGO WIP // cmd_expansion(cmd_arr, envp); // handle_argv(token_list, cmd_arr, cmd_nbr); From 86707f9fc636fd7066a4c3cb960430231bbf0494 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 13 Nov 2021 23:45:10 +0100 Subject: [PATCH 03/10] libft small change --- libft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libft b/libft index 1e8aaa7..56b4037 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 1e8aaa7154cbae5f7a200ca20323ece66c99fdd3 +Subproject commit 56b403736934a9ef2552671986afb77223f3cfeb From 106af37b58f04259ffdb296d8946cb6b03544c08 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 14 Nov 2021 00:09:42 +0100 Subject: [PATCH 04/10] words_expansions() complete + TODO : need refactoring and fix to valgrind invalid read size + redirections() WIP + Generic ft_dup_2d_arr(), ft_split_quotes(), ft_strdup_quotes() + shell_loop() continue on error + various small fix --- Makefile | 1 + headers/minishell_prototypes.h | 4 +- headers/minishell_structs.h | 5 +- srcs/generic.c | 31 ++- srcs/init.c | 5 +- srcs/parsing/alloc_cmd_array.c | 4 +- srcs/parsing/expansions/expand_token.c | 33 ++-- srcs/parsing/expansions/ft_split_quotes.c | 186 ++++++++++++++++++ srcs/parsing/expansions/ft_strdup_quotes.c | 68 +++++++ .../expansions/new_token_for_each_field.c | 23 ++- srcs/parsing/expansions/words_expansions.c | 21 +- srcs/parsing/parsing.c | 56 +++++- srcs/parsing/redirections.c | 100 ++++++++++ srcs/shell_loop.c | 10 +- valgrind_invalid_read_to_fix.txt | 157 +++++++++++++++ 15 files changed, 653 insertions(+), 51 deletions(-) create mode 100644 srcs/parsing/expansions/ft_split_quotes.c create mode 100644 srcs/parsing/expansions/ft_strdup_quotes.c create mode 100644 srcs/parsing/redirections.c create mode 100644 valgrind_invalid_read_to_fix.txt diff --git a/Makefile b/Makefile index 389f2be..084b2ac 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ SRCS = main.c init.c free.c generic.c \ parsing.c alloc_cmd_array.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ + ft_split_quotes.c ft_strdup_quotes.c \ env.c exit.c echo.c DIR_OBJS = builds diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 10c4cd9..088460a 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/11/07 04:13:53 by lperrey ### ########.fr */ +/* Updated: 2021/11/13 04:20:43 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -57,5 +57,7 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr); void print_matrix(char **matrix, char *sep); t_list *ft_lstbeforelast(t_list *lst); t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); +typedef void *(*t_dup_func)(void *); +void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)); #endif diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 84f4fc6..742272b 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */ +/* Updated: 2021/11/11 07:21:47 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,7 +23,8 @@ enum e_token_id T_PIPE = '|', T_DLESS, T_DGREAT, - T_WORD + T_WORD, + T_REDIRECTION_WORD }; // T_DLESS == '<<' // T_DGREAT == '>>' diff --git a/srcs/generic.c b/srcs/generic.c index 2d56cc4..f9d1839 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/11/07 04:07:10 by lperrey ### ########.fr */ +/* Updated: 2021/11/13 04:23:54 by lperrey ### ########.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) // Superflu si ft_dup_2d_arr() fonctionne { unsigned int i; char **arr; @@ -107,6 +107,29 @@ char **ft_dup_2d_char_arr(char **ptr) return (new_arr); } +// Test generic. Pas certain que ça fonctionne bien avec le pointeur sur fonction +void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)) +{ + unsigned int i; + char **arr; + char **new_arr; + + new_arr = malloc((ft_2d_arrlen(ptr) + 1) * sizeof (void *)); + if (!new_arr) + return (NULL); + arr = (char **)ptr; + i = 0; + while (arr[i]) + { + new_arr[i] = dup_func(arr[i]); + if (!new_arr[i]) + return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); + i++; + } + new_arr[i] = NULL; + return (new_arr); +} + void *ft_resize_2d_arr(void *ptr, size_t add_nbr) { unsigned int i; @@ -151,7 +174,7 @@ t_list *ft_lstbeforelast(t_list *lst) return (lst); } -t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size) +t_list *ft_lstnew_generic(size_t lst_size, size_t content_size) { t_list *elem; void *content; @@ -164,7 +187,7 @@ t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size) if (!content) return (NULL); } - elem = ft_calloc(1, lst_sizse); + elem = ft_calloc(1, lst_size); if (!elem) { free(content); diff --git a/srcs/init.c b/srcs/init.c index f6e6484..5052a64 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/11/02 13:50:33 by hulamy ### ########.fr */ +/* Updated: 2021/11/13 05:31:47 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,9 +19,10 @@ int init(t_all *c, char *envp[]) { g_all = c; ft_bzero(c, sizeof (*c)); - c->envp = ft_dup_2d_char_arr(envp); + c->envp = ft_dup_2d_arr(envp, (t_dup_func)ft_strdup); // TEST WIP if (!c->envp) return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); + //print_matrix(c->envp, "\n --- \n"); // TEST WIP c->prompt_base = init_prompt_base(); if (!c->prompt_base) return (ft_reti_perror(0, "init_prompt_base() error")); diff --git a/srcs/parsing/alloc_cmd_array.c b/srcs/parsing/alloc_cmd_array.c index edd67c3..b5b3c45 100644 --- a/srcs/parsing/alloc_cmd_array.c +++ b/srcs/parsing/alloc_cmd_array.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/02 22:46:23 by lperrey #+# #+# */ -/* Updated: 2021/11/07 04:29:54 by lperrey ### ########.fr */ +/* Updated: 2021/11/11 08:47:46 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,6 +43,8 @@ t_cmd **alloc_cmd_array(size_t cmd_nbr) ft_free_2d_arr(cmd_arr); return (ft_retp_perror(NULL, "alloc_cmd()")); } + cmd_arr[i]->fd_in = STDIN_FILENO; + cmd_arr[i]->fd_out = STDOUT_FILENO; i++; } return (cmd_arr); diff --git a/srcs/parsing/expansions/expand_token.c b/srcs/parsing/expansions/expand_token.c index 1b46df2..7885052 100644 --- a/srcs/parsing/expansions/expand_token.c +++ b/srcs/parsing/expansions/expand_token.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/07 04:36:12 by lperrey ### ########.fr */ +/* Updated: 2021/11/11 21:04:41 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,9 +21,9 @@ enum e_in_quote_state IN_DQUOTES = '\"' }; -static t_list *ret_parameter_expansion(t_token *t, int *i); +static t_list *ret_parameter_expansion(char *content, int *i); -t_list *expand_token(t_token *t) +t_list *expand_token(char *content) { int in_quotes; int i; @@ -35,11 +35,11 @@ t_list *expand_token(t_token *t) i = 0; head.next = NULL; expand = &head; - while (t->content[i]) + while (content[i]) { - if (t->content[i] == '$') + if (content[i] == '$') { - expand->next = ret_parameter_expansion(t, &i); + expand->next = ret_parameter_expansion(content, &i); expand = expand->next; if (!expand) {//todo wrap @@ -49,7 +49,7 @@ t_list *expand_token(t_token *t) } else { - expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&t->content[i]) + 1); + expand->next = ft_lstnew_generic(sizeof(t_list), ft_strlen(&content[i]) + 1); expand = expand->next; i_exp = 0; if (!expand) @@ -57,17 +57,17 @@ t_list *expand_token(t_token *t) perror("expand_token() error"); return (ft_lstclear(&head.next, free)); } - while (t->content[i] && (t->content[i] != '$' || in_quotes == IN_QUOTES)) + while (content[i] && (content[i] != '$' || in_quotes == IN_QUOTES)) { // quoting - if (t->content[i] == '\'' && in_quotes != IN_DQUOTES) + if (content[i] == '\'' && in_quotes != IN_DQUOTES) { if (in_quotes == IN_QUOTES) in_quotes = 0; else in_quotes = IN_QUOTES; } - ((char *)expand->content)[i_exp++] = t->content[i++]; + ((char *)expand->content)[i_exp++] = content[i++]; } } } @@ -76,35 +76,34 @@ t_list *expand_token(t_token *t) // a voir si je retourne pas plutot un "char *". // Malloc la lst dans la fonction est peut-être un peu superflu et pas super clair. -// et aussi changer "t_token *t" en "char *content", inutile d'avoir le token entier. -static t_list *ret_parameter_expansion(t_token *t, int *i) +static t_list *ret_parameter_expansion(char *content, int *i) { t_list *expand; char *tmp; int i_tmp; - tmp = ft_calloc(ft_strlen(&t->content[*i]) + 1, 1); + tmp = ft_calloc(ft_strlen(&content[*i]) + 1, 1); if (!tmp) return (NULL); expand = ft_lstnew(NULL); if (!expand) return (ft_retp_free(NULL, tmp, free)); (*i)++; // skip '$' - if (t->content[*i] == '?') + if (content[*i] == '?') { (*i)++; expand->content = ft_itoa(g_all->last_exit_status); return (ft_retp_free(expand, tmp, free)); } - else if (t->content[*i] != '_' && !ft_isalpha(t->content[*i])) + else if (content[*i] != '_' && !ft_isalpha(content[*i])) { tmp[0] = '$'; expand->content = tmp; return (expand); } i_tmp = 0; - while (t->content[*i] == '_' || ft_isalnum(t->content[*i])) - tmp[i_tmp++] = t->content[(*i)++]; + while (content[*i] == '_' || ft_isalnum(content[*i])) + tmp[i_tmp++] = content[(*i)++]; expand->content = getenv(tmp); free(tmp); if (expand->content) diff --git a/srcs/parsing/expansions/ft_split_quotes.c b/srcs/parsing/expansions/ft_split_quotes.c new file mode 100644 index 0000000..d235c96 --- /dev/null +++ b/srcs/parsing/expansions/ft_split_quotes.c @@ -0,0 +1,186 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split_quotes.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/13 07:08:40 by lperrey #+# #+# */ +/* Updated: 2021/11/13 22:35:34 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + +static size_t count_word(char const *s, char c); +static char **alloc_words(char const *s, char c, char **str_arr, + size_t words_count); +static void fill_arr(char const *s, char c, char **str_arr); +static int quote_state_change(int *quote_state, const char *s); + +char **ft_split_quotes(char const *s, char c) +{ + char **str_arr; + size_t words_count; + + if (s == NULL) + return (NULL); + words_count = count_word(s, c); + str_arr = ft_calloc(words_count + 1, sizeof(char *)); + if (!str_arr) + return (NULL); + if (!(alloc_words(s, c, str_arr, words_count))) + { + ft_free_2d_arr(str_arr); + return (NULL); + } + fill_arr(s, c, str_arr); + return (str_arr); +} + +static size_t count_word(char const *s, char c) +{ + unsigned int i; + size_t count; + int quote_state; + + i = 0; + count = 0; + quote_state = 0; + while (s[i]) + { + while (s[i] == c) + i++; + if (s[i]) + count++; + while (s[i] && (s[i] != c || quote_state)) + { + while (quote_state_change("e_state, &s[i])) + i++; + if (s[i] != c || quote_state) + i++; + } + } + return (count); +} + +static char **alloc_words(char const *s, char c, char **str_arr, + size_t words_count) +{ + unsigned int i; + size_t len; + unsigned int arr_i; + int quote_state; + + i = 0; + arr_i = 0; + quote_state = 0; + while (arr_i < words_count) + { + len = 0; + while (s[i] == c) + i++; + while (s[i + len] + && (quote_state_change("e_state, &s[i + len]) + || (s[i + len] != c || quote_state))) + len++; + i = i + len; + str_arr[arr_i] = ft_calloc(len + 1, 1); + if (!str_arr[arr_i]) + return (NULL); + arr_i++; + } + return (str_arr); +} + +// Plus clair, plus de 25 lignes :( +/* static char **alloc_words(char const *s, char c, char **str_arr, + size_t words_count) +{ + unsigned int i; + size_t len; + unsigned int arr_i; + int quote_state; + + i = 0; + arr_i = 0; + quote_state = 0; + while (arr_i < words_count) + { + len = 0; + while (s[i] == c) + i++; + while (s[i + len] && (s[i + len] != c || quote_state)) + { + while (quote_state_change("e_state, &s[i + len])) + len++; + if (s[i + len] != c || quote_state) + len++; + } + i = i + len; + str_arr[arr_i] = ft_calloc(len + 1, 1); + if (!str_arr[arr_i]) + return (NULL); + arr_i++; + } + return (str_arr); +} */ + +static void fill_arr(char const *s, char c, char **str_arr) +{ + unsigned int i; + unsigned int arr_i; + unsigned int char_i; + int quote_state; + + i = 0; + arr_i = 0; + quote_state = 0; + while (str_arr[arr_i]) + { + while (s[i] == c) + i++; + char_i = 0; + while (s[i] && (s[i] != c || quote_state)) + { + while (quote_state_change("e_state, &s[i])) + str_arr[arr_i][char_i++] = s[i++]; + if (s[i] != c || quote_state) + str_arr[arr_i][char_i++] = s[i++]; + } + str_arr[arr_i][char_i] = '\0'; //superflu si ft_calloc + arr_i++; + } +} + +static int quote_state_change(int *quote_state, const char *s) +{ + if (s[0] == '\'' && *quote_state != IN_DQUOTES) + { + if (*quote_state == IN_QUOTES) + *quote_state = 0; + else if (ft_strchr(&s[1], '\'')) // if closed quotes + *quote_state = IN_QUOTES; + else + return (0); + return (1); + } + else if (s[0] == '\"' && *quote_state != IN_QUOTES) + { + if (*quote_state == IN_DQUOTES) + *quote_state = 0; + else if (ft_strchr(&s[1], '\"')) // if closed quotes + *quote_state = IN_DQUOTES; + else + return (0); + return (1); + } + return (0); +} diff --git a/srcs/parsing/expansions/ft_strdup_quotes.c b/srcs/parsing/expansions/ft_strdup_quotes.c new file mode 100644 index 0000000..9990472 --- /dev/null +++ b/srcs/parsing/expansions/ft_strdup_quotes.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_strdup_quotes.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/13 04:35:06 by lperrey #+# #+# */ +/* Updated: 2021/11/13 10:18:51 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; +static int quote_state_change(int *quote_state, const char *s); + +char *ft_strdup_quotes(const char *s) +{ + unsigned int i; + unsigned int i_dup; + char *dup; + int quote_state; + + dup = ft_calloc(ft_strlen(s) + 1, 1); + if (!dup) + return (NULL); + i = 0; + i_dup = 0; + quote_state = 0; + while (s[i]) + { + while (quote_state_change("e_state, &s[i])) + i++; + dup[i_dup++] = s[i++]; + } + return (dup); +} + +static int quote_state_change(int *quote_state, const char *s) +{ + if (s[0] == '\'' && *quote_state != IN_DQUOTES) + { + if (*quote_state == IN_QUOTES) + *quote_state = 0; + else if (ft_strchr(&s[1], '\'')) // if closed quotes + *quote_state = IN_QUOTES; + else + return (0); + return (1); + } + else if (s[0] == '\"' && *quote_state != IN_QUOTES) + { + if (*quote_state == IN_DQUOTES) + *quote_state = 0; + else if (ft_strchr(&s[1], '\"')) // if closed quotes + *quote_state = IN_DQUOTES; + else + return (0); + return (1); + } + return (0); +} diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index c3ee91c..38298b9 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -27,16 +27,21 @@ int new_token_for_each_field(char **fields, t_token **t) i = 0; while (fields[i]) { - insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(*insert_lst), 0); - insert_lst = insert_lst->next; - if (!insert_lst) - {//todo wrap - perror("insert_token_for_each_field() error"); - ft_free_2d_arr(fields); - return ((int)ft_lstclear((t_list **)&head.next, NULL)); + if (fields[i][0]) + { + insert_lst->next = (t_token *)ft_lstnew_generic(sizeof(t_token), 0); + insert_lst = insert_lst->next; + if (!insert_lst) + {//todo wrap + perror("insert_token_for_each_field() error"); + ft_free_2d_arr(fields); + return ((int)ft_lstclear((t_list **)&head.next, NULL)); + } + insert_lst->content = fields[i]; + insert_lst->id = T_WORD; } - insert_lst->content = fields[i]; - insert_lst->id = T_WORD; + else + free(fields[i]); i++; } free(fields); diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index 36f5288..8c7e356 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/08 03:59:02 by lperrey ### ########.fr */ +/* Updated: 2021/11/13 21:27:20 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,15 +20,18 @@ enum e_in_quote_state }; t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); -t_list *expand_token(t_token *t); +t_list *expand_token(char *content); char *rejoin_after_expand(t_list *expand_lst); +char **ft_split_quotes(char const *s, char c); // Generic +char *ft_strdup_quotes(const char *s); // Generic int new_token_for_each_field(char **fields, t_token **t); // 1 - chaque bout dans un element d'une t_list // (telle quelle si non expand, ou VARIABLE de env) // 2 - strjoin() le tout // 3 - split avec un ft_strplit() modifié (ne splitant pas dans les quotes) -// 4 - creer un token T_WORD pour chaque *string du **split_arr +// 4 - quotes removal, ft_strdup_quotes() le tableau split +// 5 - creer un token T_WORD pour chaque *string du **split_arr // (ft_lstadd_front() sur le token original, puis set le token orignal à : // t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing) @@ -42,19 +45,25 @@ int words_expansions(t_token *t) if (t->id == T_WORD) { // 1 - tmp_expand = expand_token(t); + tmp_expand = expand_token(t->content); if (!tmp_expand) return (0); // 2 tmp_expand = rejoin_after_expand(tmp_expand); if (!tmp_expand) return (0); - // 3 WIP PLACEHOLDER, MUST WRITE A ft_split_quoted() FOR NO SPLIT IN QUOTES - tmp_split = ft_split(tmp_expand, ' '); + // 3 + tmp_split = ft_split_quotes(tmp_expand, ' '); free(tmp_expand); if (!tmp_split) return (0); // 4 + tmp_expand = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes); + ft_free_2d_arr(tmp_split); + tmp_split = tmp_expand; + if (!tmp_split) + return (0); + // 5 if (!new_token_for_each_field(tmp_split, &t)) return (0); } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index d55ad04..b314dc0 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/08 01:03:29 by lperrey ### ########.fr */ +/* Updated: 2021/11/13 05:13:40 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,28 +25,72 @@ int next_cmd(t_token *token); int is_redirection(enum e_token_id id); // HUGO WIP +void save_redirections_words(t_token *t) +{ + while (t) + { + if (t->id == '>' || t->id == T_DGREAT + || t->id == '<' || t->id == T_DLESS) + { + t = t->next; + t->id = T_REDIRECTION_WORD; + } + t = t->next; + } +} + +void ft_free_cmd_arr(t_cmd **cmd_arr) +{ + int i; + + i = 0; + while (cmd_arr[i]) + { + if (cmd_arr[i]->argv) + ft_free_2d_arr(cmd_arr[i]->argv); + if (cmd_arr[i]->fd_in != STDIN_FILENO && cmd_arr[i]->fd_in > 0) + if (close(cmd_arr[i]->fd_in) == -1) + perror("close()"); + if (cmd_arr[i]->fd_out != STDOUT_FILENO && cmd_arr[i]->fd_out > 0) + if (close(cmd_arr[i]->fd_out) == -1) + perror("close()"); + i++; + } + ft_free_2d_arr(cmd_arr); +} + t_cmd **parsing(t_token *token_list) { t_cmd **cmd_arr; if (!valid_syntax(token_list)) return (NULL); - // Struct CMD alloc - cmd_arr = alloc_cmd_array(count_pipes(token_list) + 1); - if (!cmd_arr) - return (NULL); + + // 2.9.1 - 1) Save Words + save_redirections_words(token_list); // 2.9.1 - 2) Expansion // TEST TOKENS PRINT ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); ft_lstprint((t_list *)token_list, 1); // - words_expansions(token_list); + // getenv() ne va pas fonctionner avec le changement d'environnement prévu jusqu'ici. + // TODO : Revoir le changement d'environnement (avec extern char **environ ?) + // OU Integrer un equivalent perso comme dans pipex + if (!words_expansions(token_list)) + return (NULL); // ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1); ft_lstprint((t_list *)token_list, 1); + // Struct CMD alloc + cmd_arr = alloc_cmd_array(1 + count_pipes(token_list)); + if (!cmd_arr) + return (NULL); + // 2.9.1 - 3) Redirection +/* if (!redirections(token_list, cmd_arr)) + return (ft_retp_free(NULL, cmd_arr, ft_free_cmd_arr)); */ // Struct CMD fill diff --git a/srcs/parsing/redirections.c b/srcs/parsing/redirections.c new file mode 100644 index 0000000..b9fa650 --- /dev/null +++ b/srcs/parsing/redirections.c @@ -0,0 +1,100 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirections.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ +/* Updated: 2021/11/12 20:17:09 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_reti_perror_io(int ret, char *err_str, char *io_file) // generic +{ + ft_putstr_fd(err_str, 2); + perror(io_file); + return (ret); +} + +int here_doc_handle_PLACEHOLDER(char *delimiter) +{ + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02 + /* If any part of word is quoted, + the delimiter shall be formed by performing quote removal on word, + and the here-document lines shall not be expanded. + Otherwise, the delimiter shall be the word itself. */ + // Pas d'expansion sur le delimiter, mais quote removal tout de même. + // TODO : quote removal sur le delimiter. + QUOTE_REMOVAL_PLACEHOLDER(); +} + +int redirect_cmd_input(t_token *t, t_cmd *cmd) +{ + if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0) + if (close(cmd->fd_in) == -1) + perror("close()"); + if (t->id == '<') + { + // TODO : Expansion + quote removal sur le word t->next->content. + // si plus d'un champ ou aucun champ aprés expansion, + // message d'erreur comme bash "bash: $VAR: ambiguous redirect" + // OU prise en compte seulement du premier champ. + EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + cmd->fd_in = open(t->next->content, O_RDONLY); + if (cmd->fd_in == -1) + ft_reti_perror_io(0, "open() ", t->next->content); + } + else if (t->id == T_DLESS) + cmd->fd_in = here_doc_handle_PLACEHOLDER(t->next->content); // TODO + return (1); +} + +int redirect_cmd_output(t_token *t, t_cmd *cmd) +{ + int flags; + + if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0) + if (close(cmd->fd_out) == -1) + perror("close()"); + // TODO : Expansion + quote removal sur le word t->next->content. + // si plus d'un champ ou aucun champ aprés expansion, + // message d'erreur comme bash "bash: $VAR: ambiguous redirect" + // OU prise en compte seulement du premier champ. + EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + if (t->id == '>') + flags = O_WRONLY | O_CREAT | O_TRUNC; + else if (t->id == T_DGREAT) + flags = O_WRONLY | O_CREAT | O_APPEND; + cmd->fd_out = open(t->next->content, flags, S_IRWXU); + if (cmd->fd_out == -1) + return (ft_reti_perror_io(0, "open() ", t->next->content)); + return (1); +} + +int redirections(t_token *t, t_cmd **cmd_arr) +{ + int i; + + i = 0; + while (t) + { + if (t->id == '<' || t->id == T_DLESS) + { + if (!redirect_cmd_input(t, cmd_arr[i])) + return (0); + } + else if (t->id == '>' || t->id == T_DGREAT) + { + if (!redirect_cmd_output(t, cmd_arr[i])) + return (0); + } + else if (t->id == '|') + i++; + t = t->next; + } + return (1); +} diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 0e7349e..905d080 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/02 22:38:35 by lperrey ### ########.fr */ +/* Updated: 2021/11/08 05:16:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,14 +32,18 @@ void shell_loop(t_all *c) if (line_input && *line_input) { add_history(line_input); - //test_signal(c); // Lexing c->token_list = input_to_tokens(line_input); + if (!c->token_list) + continue ; // Parsing c->cmd_arr = parsing(c->token_list); ft_lstclear((t_list **)&c->token_list, free); + if (!c->cmd_arr) + continue ; // Search Path/builtins - // Exec + // Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit()) + // Exec Pipeline //execute_cmd(c->envp, c->cmd_arr); } else if (!line_input) diff --git a/valgrind_invalid_read_to_fix.txt b/valgrind_invalid_read_to_fix.txt new file mode 100644 index 0000000..a9ee338 --- /dev/null +++ b/valgrind_invalid_read_to_fix.txt @@ -0,0 +1,157 @@ +lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> 3[5;6;35 +TOKENS LIST : +----------- +3[5;6;35 +TOKENS LIST EXPANDED : +----------- +3[5;6;35 +lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> [6;34'.6' +TOKENS LIST : +----------- +[6;34'.6' +==2095== Invalid read of size 1 +==2095== at 0x403938: count_word (ft_split_quotes.c:63) +==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) +==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) +==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) +==2095== by 0x402F97: words_expansions (words_expansions.c:52) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== Invalid read of size 1 +==2095== at 0x4038D1: count_word (ft_split_quotes.c:57) +==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) +==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) +==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) +==2095== by 0x402F97: words_expansions (words_expansions.c:52) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== Invalid read of size 1 +==2095== at 0x403C0F: fill_arr (ft_split_quotes.c:151) +==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) +==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) +==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) +==2095== by 0x402F97: words_expansions (words_expansions.c:52) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== Invalid write of size 1 +==2095== at 0x403D30: fill_arr (ft_split_quotes.c:158) +==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95) +==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== Invalid read of size 1 +==2095== at 0x403EE2: ft_strdup_quotes (ft_strdup_quotes.c:36) +==2095== by 0x40149A: ft_dup_2d_arr (generic.c:124) +==2095== by 0x402FFA: words_expansions (words_expansions.c:61) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95) +==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39) +==2095== by 0x402FC0: words_expansions (words_expansions.c:56) +==2095== by 0x40275E: parsing (parsing.c:80) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +TOKENS LIST EXPANDED : +----------- +[6;34.6 +lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> ^D==2095== +==2095== FILE DESCRIPTORS: 3 open at exit. +==2095== Open file descriptor 2: /dev/tty1 +==2095== +==2095== +==2095== Open file descriptor 1: /dev/tty1 +==2095== +==2095== +==2095== Open file descriptor 0: /dev/tty1 +==2095== +==2095== +==2095== +==2095== HEAP SUMMARY: +==2095== in use at exit: 134,842 bytes in 208 blocks +==2095== total heap usage: 557 allocs, 349 frees, 165,633 bytes allocated +==2095== +==2095== 16 bytes in 1 blocks are still reachable in loss record 7 of 46 +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34) +==2095== by 0x4027AB: parsing (parsing.c:87) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== 32 bytes in 1 blocks are still reachable in loss record 10 of 46 +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40) +==2095== by 0x4027AB: parsing (parsing.c:87) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== 224 bytes in 7 blocks are indirectly lost in loss record 19 of 46 +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40) +==2095== by 0x4027AB: parsing (parsing.c:87) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== 336 (112 direct, 224 indirect) bytes in 7 blocks are definitely lost in loss record 21 of 46 +==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) +==2095== by 0x404760: ft_calloc (ft_calloc.c:19) +==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34) +==2095== by 0x4027AB: parsing (parsing.c:87) +==2095== by 0x401A6E: shell_loop (shell_loop.c:40) +==2095== by 0x400DA0: main (main.c:25) +==2095== +==2095== LEAK SUMMARY: +==2095== definitely lost: 112 bytes in 7 blocks +==2095== indirectly lost: 224 bytes in 7 blocks +==2095== possibly lost: 0 bytes in 0 blocks +==2095== still reachable: 48 bytes in 2 blocks +==2095== suppressed: 134,458 bytes in 192 blocks +==2095== +==2095== For counts of detected and suppressed errors, rerun with: -v +==2095== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) +➜ minishell git:(master) ✗ From 1e682f796dff8265090463d779741fb775cc3f3b Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 14 Nov 2021 04:59:38 +0100 Subject: [PATCH 05/10] fix invalid read with quotes functions + ft_free_cmd_arr() --- headers/minishell_prototypes.h | 3 ++- srcs/free.c | 24 +++++++++++++++++++++- srcs/parsing/expansions/ft_split_quotes.c | 4 ++-- srcs/parsing/expansions/ft_strdup_quotes.c | 3 ++- srcs/parsing/parsing.c | 22 +------------------- srcs/shell_loop.c | 4 +++- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 088460a..7cf8fb4 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/11/13 04:20:43 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 00:35:59 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,6 +44,7 @@ int builtin_echo(int argc, char *argv[], t_all *c); // Free int free_exit(t_all *c, int exit_status); +void ft_free_cmd_arr(t_cmd **cmd_arr); // Generic char *ft_strjoinfree(char *s1, char *s2); diff --git a/srcs/free.c b/srcs/free.c index d02f438..7cbfeba 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/30 14:18:09 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 04:48:49 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,8 +18,30 @@ int free_exit(t_all *c, int exit_status) 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 ft_free_2d_arr(c->envp); + ft_free_cmd_arr(c->cmd_arr); if (c->termios_changed) tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); rl_clear_history(); exit(exit_status); } + +void ft_free_cmd_arr(t_cmd **cmd_arr) +{ + int i; + + if (!cmd_arr) + return ; + i = 0; + while (cmd_arr[i]) + { + ft_free_2d_arr(cmd_arr[i]->argv); + if (cmd_arr[i]->fd_in != STDIN_FILENO && cmd_arr[i]->fd_in > 0) + if (close(cmd_arr[i]->fd_in) == -1) + perror("close()"); + if (cmd_arr[i]->fd_out != STDOUT_FILENO && cmd_arr[i]->fd_out > 0) + if (close(cmd_arr[i]->fd_out) == -1) + perror("close()"); + i++; + } + ft_free_2d_arr(cmd_arr); +} diff --git a/srcs/parsing/expansions/ft_split_quotes.c b/srcs/parsing/expansions/ft_split_quotes.c index d235c96..83ccb22 100644 --- a/srcs/parsing/expansions/ft_split_quotes.c +++ b/srcs/parsing/expansions/ft_split_quotes.c @@ -64,7 +64,7 @@ static size_t count_word(char const *s, char c) { while (quote_state_change("e_state, &s[i])) i++; - if (s[i] != c || quote_state) + if (s[i] && (s[i] != c || quote_state)) i++; } } @@ -152,7 +152,7 @@ static void fill_arr(char const *s, char c, char **str_arr) { while (quote_state_change("e_state, &s[i])) str_arr[arr_i][char_i++] = s[i++]; - if (s[i] != c || quote_state) + if (s[i] && (s[i] != c || quote_state)) str_arr[arr_i][char_i++] = s[i++]; } str_arr[arr_i][char_i] = '\0'; //superflu si ft_calloc diff --git a/srcs/parsing/expansions/ft_strdup_quotes.c b/srcs/parsing/expansions/ft_strdup_quotes.c index 9990472..465bf1d 100644 --- a/srcs/parsing/expansions/ft_strdup_quotes.c +++ b/srcs/parsing/expansions/ft_strdup_quotes.c @@ -37,7 +37,8 @@ char *ft_strdup_quotes(const char *s) { while (quote_state_change("e_state, &s[i])) i++; - dup[i_dup++] = s[i++]; + if (s[i]) + dup[i_dup++] = s[i++]; } return (dup); } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index b314dc0..975b973 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/13 05:13:40 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 00:35:42 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -39,26 +39,6 @@ void save_redirections_words(t_token *t) } } -void ft_free_cmd_arr(t_cmd **cmd_arr) -{ - int i; - - i = 0; - while (cmd_arr[i]) - { - if (cmd_arr[i]->argv) - ft_free_2d_arr(cmd_arr[i]->argv); - if (cmd_arr[i]->fd_in != STDIN_FILENO && cmd_arr[i]->fd_in > 0) - if (close(cmd_arr[i]->fd_in) == -1) - perror("close()"); - if (cmd_arr[i]->fd_out != STDOUT_FILENO && cmd_arr[i]->fd_out > 0) - if (close(cmd_arr[i]->fd_out) == -1) - perror("close()"); - i++; - } - ft_free_2d_arr(cmd_arr); -} - t_cmd **parsing(t_token *token_list) { t_cmd **cmd_arr; diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 905d080..683aa32 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/08 05:16:48 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 03:59:01 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,6 +45,8 @@ void shell_loop(t_all *c) // Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit()) // Exec Pipeline //execute_cmd(c->envp, c->cmd_arr); + ft_free_cmd_arr(c->cmd_arr); + c->cmd_arr = NULL; } else if (!line_input) write(1, "\n", 1); From 66b48dc99dcdb10b1f1e92030e8c952af0fbc759 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 14 Nov 2021 11:05:58 +0100 Subject: [PATCH 06/10] redirections WIP --- Makefile | 4 +- headers/minishell_prototypes.h | 11 +- srcs/free.c | 3 +- srcs/generic.c | 15 +- srcs/parsing/expansions/ft_strdup_quotes.c | 3 +- srcs/parsing/expansions/words_expansions.c | 70 ++++---- srcs/parsing/parsing.c | 6 +- srcs/parsing/redirections/here_doc.c | 102 ++++++++++++ .../parsing/{ => redirections}/redirections.c | 114 ++++++------- valgrind_invalid_read_to_fix.txt | 157 ------------------ 10 files changed, 223 insertions(+), 262 deletions(-) create mode 100644 srcs/parsing/redirections/here_doc.c rename srcs/parsing/{ => redirections}/redirections.c (66%) delete mode 100644 valgrind_invalid_read_to_fix.txt diff --git a/Makefile b/Makefile index 084b2ac..c43bc18 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) DIR_SRCS = srcs srcs/builtins srcs/lexing \ - srcs/parsing srcs/parsing/valid_syntax srcs/parsing/expansions + srcs/parsing srcs/parsing/valid_syntax \ + srcs/parsing/expansions srcs/parsing/redirections INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) @@ -30,6 +31,7 @@ SRCS = main.c init.c free.c generic.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ ft_split_quotes.c ft_strdup_quotes.c \ + redirections.c here_doc.c \ env.c exit.c echo.c DIR_OBJS = builds diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 7cf8fb4..04f2b62 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/11/14 00:35:59 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 10:12:30 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,9 @@ int valid_token(t_token **token_list, enum e_token_id token_id); int valid_command_separator(const t_token *token_list); size_t count_pipes(t_token *token); t_cmd **alloc_cmd_array(size_t cmd_nbr); -int words_expansions(t_token *t); +int words_expansions(t_token *token_list); +int token_expansions(t_token **t); +int redirections(t_token *t, t_cmd **cmd_arr); // Builtins int builtin_env(int argc, char *argv[], t_all *c); @@ -60,5 +62,10 @@ t_list *ft_lstbeforelast(t_list *lst); t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); typedef void *(*t_dup_func)(void *); void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)); +void ft_perror_io(char *err_str, char *io_file); +int ft_reti_perror_io(int ret, char *err_str, char *io_file); + +char **ft_split_quotes(char const *s, char c); +char *ft_strdup_quotes(const char *s); #endif diff --git a/srcs/free.c b/srcs/free.c index 7cbfeba..2e299fd 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/11/14 04:48:49 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 08:26:32 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,7 @@ int free_exit(t_all *c, int exit_status) ft_free_cmd_arr(c->cmd_arr); if (c->termios_changed) tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); + gnl(STDIN_FILENO, NULL, 1); rl_clear_history(); exit(exit_status); } diff --git a/srcs/generic.c b/srcs/generic.c index f9d1839..002eec3 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/11/13 04:23:54 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 08:27:40 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -197,3 +197,16 @@ t_list *ft_lstnew_generic(size_t lst_size, size_t content_size) elem->next = NULL; return (elem); } + +void ft_perror_io(char *err_str, char *io_file) +{ + ft_putstr_fd(err_str, 2); + perror(io_file); +} + +int ft_reti_perror_io(int ret, char *err_str, char *io_file) +{ + ft_putstr_fd(err_str, 2); + perror(io_file); + return (ret); +} diff --git a/srcs/parsing/expansions/ft_strdup_quotes.c b/srcs/parsing/expansions/ft_strdup_quotes.c index 465bf1d..1b4525f 100644 --- a/srcs/parsing/expansions/ft_strdup_quotes.c +++ b/srcs/parsing/expansions/ft_strdup_quotes.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/13 04:35:06 by lperrey #+# #+# */ -/* Updated: 2021/11/13 10:18:51 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 06:01:45 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,6 +20,7 @@ enum e_in_quote_state }; static int quote_state_change(int *quote_state, const char *s); +/* Duplicate a string minus the quoting characters ['] and ["]*/ char *ft_strdup_quotes(const char *s) { unsigned int i; diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index 8c7e356..400e286 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/13 21:27:20 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 10:13:38 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,8 +22,6 @@ enum e_in_quote_state t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); t_list *expand_token(char *content); char *rejoin_after_expand(t_list *expand_lst); -char **ft_split_quotes(char const *s, char c); // Generic -char *ft_strdup_quotes(const char *s); // Generic int new_token_for_each_field(char **fields, t_token **t); // 1 - chaque bout dans un element d'une t_list @@ -35,39 +33,43 @@ int new_token_for_each_field(char **fields, t_token **t); // (ft_lstadd_front() sur le token original, puis set le token orignal à : // t->id = 0 ; free(t->content) ; t->content = NULL ; pour qu'il soit ignoré sur la suite du parsing) -int words_expansions(t_token *t) +int words_expansions(t_token *token_list) { - void *tmp_expand; - char **tmp_split; - - while (t) + while (token_list) { - if (t->id == T_WORD) - { - // 1 - tmp_expand = expand_token(t->content); - if (!tmp_expand) - return (0); - // 2 - tmp_expand = rejoin_after_expand(tmp_expand); - if (!tmp_expand) - return (0); - // 3 - tmp_split = ft_split_quotes(tmp_expand, ' '); - free(tmp_expand); - if (!tmp_split) - return (0); - // 4 - tmp_expand = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes); - ft_free_2d_arr(tmp_split); - tmp_split = tmp_expand; - if (!tmp_split) - return (0); - // 5 - if (!new_token_for_each_field(tmp_split, &t)) - return (0); - } - t = t->next; + if (token_list->id == T_WORD) + token_expansions(&token_list); + token_list = token_list->next; } return (1); } + +int token_expansions(t_token **t) +{ + void *tmp; + char **tmp_split; + + // 1 + tmp = expand_token((*t)->content); + if (!tmp) + return (0); + // 2 + tmp = rejoin_after_expand(tmp); + if (!tmp) + return (0); + // 3 + tmp_split = ft_split_quotes(tmp, ' '); + free(tmp); + if (!tmp_split) + return (0); + // 4 + tmp = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes); + ft_free_2d_arr(tmp_split); + tmp_split = tmp; + if (!tmp_split) + return (0); + // 5 + if (!new_token_for_each_field(tmp_split, t)) + return (0); + return (1); +} diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 975b973..0b3da2d 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/14 00:35:42 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 11:00:39 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -69,8 +69,8 @@ t_cmd **parsing(t_token *token_list) return (NULL); // 2.9.1 - 3) Redirection -/* if (!redirections(token_list, cmd_arr)) - return (ft_retp_free(NULL, cmd_arr, ft_free_cmd_arr)); */ + if (!redirections(token_list, cmd_arr)) + return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr)); // Struct CMD fill diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c new file mode 100644 index 0000000..2662e92 --- /dev/null +++ b/srcs/parsing/redirections/here_doc.c @@ -0,0 +1,102 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* here_doc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ +/* Updated: 2021/11/14 10:58:37 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define TMP_HERE_DOC "/tmp/minishell_here_doc" + +static int here_doc_write(char *delimiter, int doc_fd); + +int here_doc(char *delimiter) +{ + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 + // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02 + /* If any part of word is quoted, + the delimiter shall be formed by performing quote removal on word, + and the here-document lines shall not be expanded. + Otherwise, the delimiter shall be the word itself. */ + // TODO : A voir si on fait les expansions de variables dans le here_doc. + // implementer une gestion des signaux pour here_doc (actuellement ça leaks). + // Peut-être remplacer gnl() par readline() pour avoir une gestion correct + // du terminal (actuellement l'affichage lors du changement de ligne est foireux). + int here_doc; + + delimiter = ft_strdup_quotes(delimiter); + if (!delimiter) + return (ft_reti_perror(-1, "ft_strdup_quotes()")); + here_doc = open(TMP_HERE_DOC, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (here_doc == -1) + return (ft_reti_perror_io(-1, "open() ", TMP_HERE_DOC)); + if (!here_doc_write(delimiter, here_doc)) + { + gnl(STDIN_FILENO, NULL, 1); + return (0); + } + if (close(here_doc) == -1) + ft_perror_io("close() ", TMP_HERE_DOC); + here_doc = open(TMP_HERE_DOC, O_RDONLY); + if (here_doc == -1) + ft_perror_io("open() ", TMP_HERE_DOC); + if (unlink(TMP_HERE_DOC) == -1) + return (ft_reti_perror_io(-1, "unlink() ", TMP_HERE_DOC)); + return (here_doc); +} + +static int here_doc_write(char *delimiter, int doc_fd) +{ + char *line; + + while (1) + { + line = NULL; + if (gnl(STDIN_FILENO, &line, 0) == -1) + return (ft_reti_perror_free(0, line, free, "gnl() STDIN")); + if (ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0) // Ou ft_strlen(delimiter) + 1 ? Ça devrais être identique et ça peux se calculer une seul fois. + break ; + if (write(doc_fd, line, ft_strlen(line)) == -1) + return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + if (write(doc_fd, "\n", 1) == -1) + return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + free(line); + } + free(line); + gnl(STDIN_FILENO, NULL, 1); + return (1); +} + +/* +static int here_doc_write(char *delimiter, int doc_fd) +{ + char *line; + int ret; + + line = NULL; + ret = 1; + while (ret) + { + ret = gnl(STDIN_FILENO, &line, 0); + if (ret == -1) + return (ft_reti_perror_free(0, line, free, "gnl() STDIN")); + if (ft_strncmp(line, delimiter, ft_strlen(line) + 1) == 0) // Ou ft_strlen(delimiter) + 1 ? Ça devrais être identique et ça peux se calculer une seul fois. + break ; + if (write(doc_fd, line, ft_strlen(line)) == -1) + return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + if (write(doc_fd, "\n", 1) == -1) + return (ft_reti_perror_free(0, line, free, "write() "TMP_HERE_DOC)); + free(line); + line = NULL; + } + free(line); + gnl(STDIN_FILENO, NULL, 1); + return (1); +} + */ diff --git a/srcs/parsing/redirections.c b/srcs/parsing/redirections/redirections.c similarity index 66% rename from srcs/parsing/redirections.c rename to srcs/parsing/redirections/redirections.c index b9fa650..0870bcd 100644 --- a/srcs/parsing/redirections.c +++ b/srcs/parsing/redirections/redirections.c @@ -6,74 +6,16 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ -/* Updated: 2021/11/12 20:17:09 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 10:04:21 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int ft_reti_perror_io(int ret, char *err_str, char *io_file) // generic -{ - ft_putstr_fd(err_str, 2); - perror(io_file); - return (ret); -} +int here_doc(char *delimiter); -int here_doc_handle_PLACEHOLDER(char *delimiter) -{ - // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 - // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02 - /* If any part of word is quoted, - the delimiter shall be formed by performing quote removal on word, - and the here-document lines shall not be expanded. - Otherwise, the delimiter shall be the word itself. */ - // Pas d'expansion sur le delimiter, mais quote removal tout de même. - // TODO : quote removal sur le delimiter. - QUOTE_REMOVAL_PLACEHOLDER(); -} - -int redirect_cmd_input(t_token *t, t_cmd *cmd) -{ - if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0) - if (close(cmd->fd_in) == -1) - perror("close()"); - if (t->id == '<') - { - // TODO : Expansion + quote removal sur le word t->next->content. - // si plus d'un champ ou aucun champ aprés expansion, - // message d'erreur comme bash "bash: $VAR: ambiguous redirect" - // OU prise en compte seulement du premier champ. - EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); - cmd->fd_in = open(t->next->content, O_RDONLY); - if (cmd->fd_in == -1) - ft_reti_perror_io(0, "open() ", t->next->content); - } - else if (t->id == T_DLESS) - cmd->fd_in = here_doc_handle_PLACEHOLDER(t->next->content); // TODO - return (1); -} - -int redirect_cmd_output(t_token *t, t_cmd *cmd) -{ - int flags; - - if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0) - if (close(cmd->fd_out) == -1) - perror("close()"); - // TODO : Expansion + quote removal sur le word t->next->content. - // si plus d'un champ ou aucun champ aprés expansion, - // message d'erreur comme bash "bash: $VAR: ambiguous redirect" - // OU prise en compte seulement du premier champ. - EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); - if (t->id == '>') - flags = O_WRONLY | O_CREAT | O_TRUNC; - else if (t->id == T_DGREAT) - flags = O_WRONLY | O_CREAT | O_APPEND; - cmd->fd_out = open(t->next->content, flags, S_IRWXU); - if (cmd->fd_out == -1) - return (ft_reti_perror_io(0, "open() ", t->next->content)); - return (1); -} +static int redirect_cmd_input(t_token *t, t_cmd *cmd); +static int redirect_cmd_output(t_token *t, t_cmd *cmd); int redirections(t_token *t, t_cmd **cmd_arr) { @@ -98,3 +40,51 @@ int redirections(t_token *t, t_cmd **cmd_arr) } return (1); } + +static int redirect_cmd_input(t_token *t, t_cmd *cmd) +{ + if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0) + if (close(cmd->fd_in) == -1) + perror("close()"); + if (t->id == '<') + { + // TODO : Expansion + quote removal sur le word t->next->content. + // si plus d'un champ ou aucun champ aprés expansion, + // message d'erreur comme bash "bash: $VAR: ambiguous redirect" + // OU prise en compte seulement du premier champ. + //EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + cmd->fd_in = open(t->next->content, O_RDONLY); + if (cmd->fd_in == -1) + ft_perror_io("open() ", t->next->content); + } + else if (t->id == T_DLESS) + { + cmd->fd_in = here_doc(t->next->content); + if (cmd->fd_in == -1) + return (ft_reti_print(0, "minishell: heredoc error\n", 2)); + } + return (1); +} + +static int redirect_cmd_output(t_token *t, t_cmd *cmd) +{ + int flags; + + if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0) + if (close(cmd->fd_out) == -1) + perror("close()"); + // TODO : Expansion + quote removal sur le word t->next->content. + // si plus d'un champ ou aucun champ aprés expansion, + // message d'erreur comme bash "bash: $VAR: ambiguous redirect" + // OU prise en compte seulement du premier champ. + //EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); + flags = O_WRONLY | O_CREAT; + if (t->id == '>') + flags = flags | O_TRUNC; + else if (t->id == T_DGREAT) + flags = flags | O_APPEND; + cmd->fd_out = open(t->next->content, flags, S_IRWXU); + if (cmd->fd_out == -1) + return (ft_reti_perror_io(0, "open() ", t->next->content)); + return (1); +} diff --git a/valgrind_invalid_read_to_fix.txt b/valgrind_invalid_read_to_fix.txt deleted file mode 100644 index a9ee338..0000000 --- a/valgrind_invalid_read_to_fix.txt +++ /dev/null @@ -1,157 +0,0 @@ -lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> 3[5;6;35 -TOKENS LIST : ------------ -3[5;6;35 -TOKENS LIST EXPANDED : ------------ -3[5;6;35 -lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> [6;34'.6' -TOKENS LIST : ------------ -[6;34'.6' -==2095== Invalid read of size 1 -==2095== at 0x403938: count_word (ft_split_quotes.c:63) -==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) -==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) -==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) -==2095== by 0x402F97: words_expansions (words_expansions.c:52) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== Invalid read of size 1 -==2095== at 0x4038D1: count_word (ft_split_quotes.c:57) -==2095== by 0x403806: ft_split_quotes (ft_split_quotes.c:35) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) -==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) -==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) -==2095== by 0x402F97: words_expansions (words_expansions.c:52) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== Invalid read of size 1 -==2095== at 0x403C0F: fill_arr (ft_split_quotes.c:151) -==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== Address 0x56d265a is 0 bytes after a block of size 10 alloc'd -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x4048A8: ft_strjoin (ft_strjoin.c:23) -==2095== by 0x40115C: ft_strjoinfree_s1 (generic.c:29) -==2095== by 0x40358F: rejoin_after_expand (rejoin_after_expand.c:29) -==2095== by 0x402F97: words_expansions (words_expansions.c:52) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== Invalid write of size 1 -==2095== at 0x403D30: fill_arr (ft_split_quotes.c:158) -==2095== by 0x403888: ft_split_quotes (ft_split_quotes.c:44) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95) -==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== Invalid read of size 1 -==2095== at 0x403EE2: ft_strdup_quotes (ft_strdup_quotes.c:36) -==2095== by 0x40149A: ft_dup_2d_arr (generic.c:124) -==2095== by 0x402FFA: words_expansions (words_expansions.c:61) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== Address 0x56d26fa is 0 bytes after a block of size 10 alloc'd -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x403B3C: alloc_words (ft_split_quotes.c:95) -==2095== by 0x403852: ft_split_quotes (ft_split_quotes.c:39) -==2095== by 0x402FC0: words_expansions (words_expansions.c:56) -==2095== by 0x40275E: parsing (parsing.c:80) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -TOKENS LIST EXPANDED : ------------ -[6;34.6 -lucky@Tour-Lemdows10:/mnt/c/Users/Lucky/Desktop/code/minishell> ^D==2095== -==2095== FILE DESCRIPTORS: 3 open at exit. -==2095== Open file descriptor 2: /dev/tty1 -==2095== -==2095== -==2095== Open file descriptor 1: /dev/tty1 -==2095== -==2095== -==2095== Open file descriptor 0: /dev/tty1 -==2095== -==2095== -==2095== -==2095== HEAP SUMMARY: -==2095== in use at exit: 134,842 bytes in 208 blocks -==2095== total heap usage: 557 allocs, 349 frees, 165,633 bytes allocated -==2095== -==2095== 16 bytes in 1 blocks are still reachable in loss record 7 of 46 -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34) -==2095== by 0x4027AB: parsing (parsing.c:87) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== 32 bytes in 1 blocks are still reachable in loss record 10 of 46 -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40) -==2095== by 0x4027AB: parsing (parsing.c:87) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== 224 bytes in 7 blocks are indirectly lost in loss record 19 of 46 -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x4028A3: alloc_cmd_array (alloc_cmd_array.c:40) -==2095== by 0x4027AB: parsing (parsing.c:87) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== 336 (112 direct, 224 indirect) bytes in 7 blocks are definitely lost in loss record 21 of 46 -==2095== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) -==2095== by 0x404760: ft_calloc (ft_calloc.c:19) -==2095== by 0x40284F: alloc_cmd_array (alloc_cmd_array.c:34) -==2095== by 0x4027AB: parsing (parsing.c:87) -==2095== by 0x401A6E: shell_loop (shell_loop.c:40) -==2095== by 0x400DA0: main (main.c:25) -==2095== -==2095== LEAK SUMMARY: -==2095== definitely lost: 112 bytes in 7 blocks -==2095== indirectly lost: 224 bytes in 7 blocks -==2095== possibly lost: 0 bytes in 0 blocks -==2095== still reachable: 48 bytes in 2 blocks -==2095== suppressed: 134,458 bytes in 192 blocks -==2095== -==2095== For counts of detected and suppressed errors, rerun with: -v -==2095== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) -➜ minishell git:(master) ✗ From 402196b9a96cb4b1aeb5d8a641e784542424b843 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 14 Nov 2021 11:15:30 +0100 Subject: [PATCH 07/10] fix here_doc leak --- srcs/parsing/redirections/here_doc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/srcs/parsing/redirections/here_doc.c b/srcs/parsing/redirections/here_doc.c index 2662e92..a678915 100644 --- a/srcs/parsing/redirections/here_doc.c +++ b/srcs/parsing/redirections/here_doc.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ -/* Updated: 2021/11/14 10:58:37 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 11:12:44 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,22 +25,24 @@ int here_doc(char *delimiter) and the here-document lines shall not be expanded. Otherwise, the delimiter shall be the word itself. */ // TODO : A voir si on fait les expansions de variables dans le here_doc. - // implementer une gestion des signaux pour here_doc (actuellement ça leaks). + // implementer une gestion des signaux pour here_doc (verifier comportement bash et doc POSIX). // Peut-être remplacer gnl() par readline() pour avoir une gestion correct // du terminal (actuellement l'affichage lors du changement de ligne est foireux). int here_doc; - delimiter = ft_strdup_quotes(delimiter); - if (!delimiter) - return (ft_reti_perror(-1, "ft_strdup_quotes()")); here_doc = open(TMP_HERE_DOC, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); if (here_doc == -1) return (ft_reti_perror_io(-1, "open() ", TMP_HERE_DOC)); + delimiter = ft_strdup_quotes(delimiter); + if (!delimiter) + return (ft_reti_perror(-1, "ft_strdup_quotes()")); if (!here_doc_write(delimiter, here_doc)) { + free(delimiter); gnl(STDIN_FILENO, NULL, 1); return (0); } + free(delimiter); if (close(here_doc) == -1) ft_perror_io("close() ", TMP_HERE_DOC); here_doc = open(TMP_HERE_DOC, O_RDONLY); From bb77de0588c62727d934116e73a8dae9c30a1999 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 14 Nov 2021 12:57:18 +0100 Subject: [PATCH 08/10] cmd_array_fill_argv() --- Makefile | 2 +- headers/minishell_prototypes.h | 9 +-- .../{alloc_cmd_array.c => cmd_array.c} | 62 ++++++++++++++++--- srcs/parsing/parsing.c | 41 +++++++----- 4 files changed, 84 insertions(+), 30 deletions(-) rename srcs/parsing/{alloc_cmd_array.c => cmd_array.c} (52%) diff --git a/Makefile b/Makefile index c43bc18..56750a8 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ SRCS = main.c init.c free.c generic.c \ signals.c terminal.c \ shell_loop.c shell_script.c \ lexing.c fill_token.c check_operators.c \ - parsing.c alloc_cmd_array.c \ + parsing.c cmd_array.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ ft_split_quotes.c ft_strdup_quotes.c \ diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 04f2b62..667b29e 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/11/14 10:12:30 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 12:23:38 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,11 +33,12 @@ t_cmd **parsing(t_token *token_list); int valid_syntax(t_token *token_list); int valid_token(t_token **token_list, enum e_token_id token_id); int valid_command_separator(const t_token *token_list); -size_t count_pipes(t_token *token); -t_cmd **alloc_cmd_array(size_t cmd_nbr); +size_t count_pipes(t_token *token_list); +t_cmd **cmd_array_alloc(size_t cmd_nbr); +int cmd_array_fill_argv(t_token *token_list, t_cmd **cmd_arr); int words_expansions(t_token *token_list); int token_expansions(t_token **t); -int redirections(t_token *t, t_cmd **cmd_arr); +int redirections(t_token *token_list, t_cmd **cmd_arr); // Builtins int builtin_env(int argc, char *argv[], t_all *c); diff --git a/srcs/parsing/alloc_cmd_array.c b/srcs/parsing/cmd_array.c similarity index 52% rename from srcs/parsing/alloc_cmd_array.c rename to srcs/parsing/cmd_array.c index b5b3c45..b57386c 100644 --- a/srcs/parsing/alloc_cmd_array.c +++ b/srcs/parsing/cmd_array.c @@ -1,39 +1,41 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* alloc_cmd_array.c :+: :+: :+: */ +/* cmd_array.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/02 22:46:23 by lperrey #+# #+# */ -/* Updated: 2021/11/11 08:47:46 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 12:24:39 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -size_t count_pipes(t_token *token) +static size_t cmd_words_count(t_token *t); + +size_t count_pipes(t_token *t) { size_t count; count = 0; - while (token) + while (t) { - if (token->id == T_PIPE) + if (t->id == T_PIPE) count++; - token = token->next; + t = t->next; } return (count); } -t_cmd **alloc_cmd_array(size_t cmd_nbr) +t_cmd **cmd_array_alloc(size_t cmd_nbr) { t_cmd **cmd_arr; size_t i; cmd_arr = ft_calloc(cmd_nbr + 1, sizeof (void *)); if (!cmd_arr) - return (ft_retp_perror(NULL, "alloc_cmd()")); + return (ft_retp_perror(NULL, "cmd_array_alloc()")); i = 0; while (i < cmd_nbr) { @@ -41,7 +43,7 @@ t_cmd **alloc_cmd_array(size_t cmd_nbr) if (!cmd_arr[i]) { ft_free_2d_arr(cmd_arr); - return (ft_retp_perror(NULL, "alloc_cmd()")); + return (ft_retp_perror(NULL, "cmd_array_alloc()")); } cmd_arr[i]->fd_in = STDIN_FILENO; cmd_arr[i]->fd_out = STDOUT_FILENO; @@ -49,3 +51,45 @@ t_cmd **alloc_cmd_array(size_t cmd_nbr) } return (cmd_arr); } + +int cmd_array_fill_argv(t_token *t, t_cmd **cmd_arr) +{ + size_t i; + size_t arg_i; + + i = 0; + while (cmd_arr[i]) + { + cmd_arr[i]->argv = ft_calloc(cmd_words_count(t) + 1, sizeof (char *)); + if (!cmd_arr[i]->argv) + return (ft_reti_perror(0, "cmd_array_fill_argv()")); + arg_i = 0; + while (t && t->id != '|') + { + if (t->id == T_WORD) + { + cmd_arr[i]->argv[arg_i++] = t->content; + t->content = NULL; + } + t = t->next; + } + if (t && t->id == '|') + t = t->next; + i++; + } + return (1); +} + +static size_t cmd_words_count(t_token *t) +{ + size_t count; + + count = 0; + while (t && t->id != '|') + { + if (t->id == T_WORD) + count++; + t = t->next; + } + return (count); +} diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 0b3da2d..d97c3ce 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,23 +6,17 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/14 11:00:39 by lperrey ### ########.fr */ +/* Updated: 2021/11/14 12:53:40 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" // HUGO WIP -void handle_argv(t_token *token, t_cmd **cmd, size_t cmd_nbr); void handle_path(t_cmd **cmd_arr, char **envp); -void handle_fd(t_token *token, t_cmd **cmd_arr); -void fd_heredoc(t_token *token, t_cmd *cmd); -void fd_redirection(t_token *token, t_cmd *cmd); void find_path(char **argv, char **envp); int handle_builtin(t_cmd *cmd); int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)); -int next_cmd(t_token *token); -int is_redirection(enum e_token_id id); // HUGO WIP void save_redirections_words(t_token *t) @@ -38,6 +32,21 @@ void save_redirections_words(t_token *t) t = t->next; } } +void print_cmd_array(t_cmd **cmd_arr) +{ + int i; + + i = 0; + while (cmd_arr[i]) + { + printf("CMD %i, fd_in=%i, fd_out=%i\n", i, cmd_arr[i]->fd_in, cmd_arr[i]->fd_out); + ft_putstr_fd(" |", 1); + print_matrix(cmd_arr[i]->argv, "|\n |"); + i++; + if (cmd_arr[i]) + ft_putstr_fd("----------------\n", 1); + } +} t_cmd **parsing(t_token *token_list) { @@ -51,8 +60,8 @@ t_cmd **parsing(t_token *token_list) // 2.9.1 - 2) Expansion // TEST TOKENS PRINT - ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); - ft_lstprint((t_list *)token_list, 1); + //ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); + //ft_lstprint((t_list *)token_list, 1); // // getenv() ne va pas fonctionner avec le changement d'environnement prévu jusqu'ici. // TODO : Revoir le changement d'environnement (avec extern char **environ ?) @@ -60,11 +69,11 @@ t_cmd **parsing(t_token *token_list) if (!words_expansions(token_list)) return (NULL); // - ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1); - ft_lstprint((t_list *)token_list, 1); + //ft_putstr_fd("TOKENS LIST EXPANDED :\n-----------\n", 1); + //ft_lstprint((t_list *)token_list, 1); // Struct CMD alloc - cmd_arr = alloc_cmd_array(1 + count_pipes(token_list)); + cmd_arr = cmd_array_alloc(1 + count_pipes(token_list)); if (!cmd_arr) return (NULL); @@ -73,12 +82,12 @@ t_cmd **parsing(t_token *token_list) return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr)); // Struct CMD fill - + if (!cmd_array_fill_argv(token_list, cmd_arr)) + return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr)); + print_cmd_array(cmd_arr); + // HUGO WIP -// cmd_expansion(cmd_arr, envp); -// handle_argv(token_list, cmd_arr, cmd_nbr); // handle_path(cmd_arr, envp); -// handle_fd(token_list, cmd_arr); return (cmd_arr); } From 140549db00e99351012b8a10f3285c016a768c59 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Tue, 16 Nov 2021 08:49:57 +0100 Subject: [PATCH 09/10] WIP exec_cmd_line() + fix error handle in redirections() + rename ft_free_cmd_arr() to free_pipeline() + "char **path" added to "struct t_all" + misc --- Makefile | 1 + headers/minishell_prototypes.h | 12 +- headers/minishell_structs.h | 16 +-- srcs/builtins/exit.c | 2 +- srcs/exec_cmd_line.c | 138 +++++++++++++++++++++ srcs/free.c | 42 +++++-- srcs/init.c | 26 +++- srcs/parsing/expansions/words_expansions.c | 4 +- srcs/parsing/parsing.c | 6 +- srcs/parsing/redirections/redirections.c | 35 ++++-- srcs/shell_loop.c | 8 +- 11 files changed, 239 insertions(+), 51 deletions(-) create mode 100644 srcs/exec_cmd_line.c diff --git a/Makefile b/Makefile index 56750a8..9d3fe83 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,7 @@ SRCS = main.c init.c free.c generic.c \ words_expansions.c expand_token.c rejoin_after_expand.c new_token_for_each_field.c \ ft_split_quotes.c ft_strdup_quotes.c \ redirections.c here_doc.c \ + exec_cmd_line.c \ env.c exit.c echo.c DIR_OBJS = builds diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 667b29e..6e5aed9 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/11/14 12:23:38 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 08:04:08 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ // Init int init(t_all *c, char *envp[]); +char **retrieve_path(char *envp[]); int set_signals_handling(struct sigaction *ori_signal_behaviour, struct sigaction *signal_behaviour); int set_terminal_attributes(struct termios *ori_termios, @@ -40,6 +41,9 @@ int words_expansions(t_token *token_list); int token_expansions(t_token **t); int redirections(t_token *token_list, t_cmd **cmd_arr); +// Exec +int exec_cmd_line(t_all *c); + // Builtins int builtin_env(int argc, char *argv[], t_all *c); int builtin_exit(int argc, char *argv[], t_all *c); @@ -47,7 +51,9 @@ int builtin_echo(int argc, char *argv[], t_all *c); // Free int free_exit(t_all *c, int exit_status); -void ft_free_cmd_arr(t_cmd **cmd_arr); +void free_pipeline(t_cmd **pipeline_ptr[]); +void close_pipeline_fd(t_cmd *pipeline[]); +typedef void (*t_free_f)(void *); // generic // Generic char *ft_strjoinfree(char *s1, char *s2); @@ -61,7 +67,7 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr); void print_matrix(char **matrix, char *sep); t_list *ft_lstbeforelast(t_list *lst); t_list *ft_lstnew_generic(size_t lst_sizse, size_t content_size); -typedef void *(*t_dup_func)(void *); +typedef void *(*t_dup_f)(void *); void *ft_dup_2d_arr(void *ptr, void *(*dup_func)(void *)); void ft_perror_io(char *err_str, char *io_file); int ft_reti_perror_io(int ret, char *err_str, char *io_file); diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 742272b..1fca47b 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/11/11 07:21:47 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 08:45:10 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,21 +36,23 @@ typedef struct s_token enum e_token_id id; } t_token; -typedef int (*t_builtin_ptr)(int,char **,struct s_all *); +typedef int (*t_builtin_f)(int,char **,struct s_all *); typedef struct s_cmd { - char **argv; - pid_t pid; - t_builtin_ptr *builtin_command; - int fd_in; - int fd_out; + char **argv; + char *path; + t_builtin_f builtin_func; + int fd_in; + int fd_out; + pid_t pid; } t_cmd; typedef struct s_all { t_cmd **cmd_arr; char **envp; + char **path; char *prompt_base; char *prompt; t_token *token_list; diff --git a/srcs/builtins/exit.c b/srcs/builtins/exit.c index 71e09f7..e6f6ca5 100644 --- a/srcs/builtins/exit.c +++ b/srcs/builtins/exit.c @@ -36,7 +36,7 @@ int builtin_exit(int argc, char *argv[], t_all *c) // WIP return (ft_reti_print(2, " numeric argument required\n", 2)); } } - status = ft_atoi(argv[1]); + status = ft_atoi(argv[1]); } return (free_exit(c, status)); } diff --git a/srcs/exec_cmd_line.c b/srcs/exec_cmd_line.c new file mode 100644 index 0000000..b690dd5 --- /dev/null +++ b/srcs/exec_cmd_line.c @@ -0,0 +1,138 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* exec_cmd_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ +/* Updated: 2021/11/16 08:42:01 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01 +// Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit()) + +int pipeline(t_all *c); +int open_pipes(t_cmd *pipeline[]); +int pipeline_access_cmd(t_cmd *pipeline[], char *path[]); +void pipeline_exec(t_cmd *pipeline[], t_all *c); +int cmd_exec_in_subshell(t_cmd *cmd, t_all *c); +int simple_cmd_builtin(t_cmd *cmd, t_all *c); + +int exec_cmd_line(t_all *c) +{ + if (!pipeline(c)) + { + free_pipeline(&c->cmd_arr); + return (0); + } + return (1); +} + +int pipeline(t_all *c) +{ + if (!open_pipes(c->cmd_arr)) + return (0); + if (!pipeline_access_cmd(c->cmd_arr, c->path)) + return (0); + if (ft_2d_arrlen(pipeline) == 1 && c->cmd_arr[0]->builtin_func) + { + simple_cmd_builtin(c->cmd_arr[0], c); + free_pipeline(&c->cmd_arr); + } + else + { + pipeline_exec(c->cmd_arr, c); + free_pipeline(&c->cmd_arr); + // TODO wait process here + } + return (1); +} + +int open_pipes(t_cmd *pipeline[]) +{ + int i; + int pipes[2]; + + i = 0; + while (pipeline[i] && pipeline[i + 1]) + { + if (pipe(pipes) == -1) + return (ft_reti_perror(0, "pipe()")); + if (pipeline[i]->fd_out == STDOUT_FILENO) + pipeline[i]->fd_out = pipes[STDOUT_FILENO]; + else + if (close(pipes[STDOUT_FILENO]) == -1) + perror("close()"); + if (pipeline[i]->fd_in == STDIN_FILENO) + pipeline[i + 1]->fd_in = pipes[STDIN_FILENO]; + else + if (close(pipes[STDIN_FILENO]) == -1) + perror("close()"); + i++; + } + return (1); +} + +int pipeline_access_cmd(t_cmd *pipeline[], char *path[]) +{ + // TODO + // Penser à : path = strdup(argv[0]); + // et non : path = argv[0]; + // pour ne pas double free + + return (1); +} + +int simple_cmd_builtin(t_cmd *cmd, t_all *c) +{ + // TODO + return (1); +} + +// TODO : Change exit status as in documentation : +// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 +void pipeline_exec(t_cmd *pipeline[], t_all *c) +{ + int i; + int ret; + + i = 0; + while (pipeline[i]) + { + if (pipeline[i]->pid == 0) // Pid var as error mark, WIP + { + ret = cmd_exec_in_subshell(pipeline[i], c); + if (ret != EXIT_SUCCESS) + free_exit(c, ret); + } + i++; + } +} + +int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) +{ + cmd->pid = fork(); + if (cmd->pid == -1) + perror("fork()"); + if (cmd->pid == 0) + { + if (cmd->fd_in != STDIN_FILENO) + if (dup2(cmd->fd_in, STDIN_FILENO) == -1) + return (ft_reti_perror(EXIT_FAILURE, "dup2()")); + if (cmd->fd_out != STDOUT_FILENO) + if (dup2(cmd->fd_out, STDOUT_FILENO) == -1) + return (ft_reti_perror(EXIT_FAILURE, "dup2()")); + close_pipeline_fd(c->cmd_arr); + if (cmd->builtin_func) + free_exit(c, cmd->builtin_func(ft_2d_arrlen(cmd->argv), cmd->argv,c)); + else if (execve("/bin/echo", cmd->argv, c->envp) == -1) // WIP, TEST + return (ft_reti_perror_io(EXIT_FAILURE, "execve() ", cmd->argv[0])); + //else if (execve(cmd->path, cmd->argv, c->envp) == -1) + // return (ft_reti_perror_io(EXIT_FAILURE, "execve() ", cmd->argv[0])); + } + return (EXIT_SUCCESS); +} diff --git a/srcs/free.c b/srcs/free.c index 2e299fd..4dfd055 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/11/14 08:26:32 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 08:03:30 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ int free_exit(t_all *c, int exit_status) 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 ft_free_2d_arr(c->envp); - ft_free_cmd_arr(c->cmd_arr); + free_pipeline(&c->cmd_arr); if (c->termios_changed) tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); gnl(STDIN_FILENO, NULL, 1); @@ -26,23 +26,41 @@ int free_exit(t_all *c, int exit_status) exit(exit_status); } -void ft_free_cmd_arr(t_cmd **cmd_arr) +void free_pipeline(t_cmd **pipeline_ptr[]) { - int i; + int i; + t_cmd **pipeline; - if (!cmd_arr) + pipeline = *pipeline_ptr; + if (!pipeline) + return ; + close_pipeline_fd(pipeline); + i = 0; + while (pipeline[i]) + { + ft_free_2d_arr(pipeline[i]->argv); + free(pipeline[i]->path); + i++; + } + ft_free_2d_arr(pipeline); + *pipeline_ptr = NULL; +} + +void close_pipeline_fd(t_cmd *pipeline[]) +{ + int i; + + if (!pipeline) return ; i = 0; - while (cmd_arr[i]) + while (pipeline[i]) { - ft_free_2d_arr(cmd_arr[i]->argv); - if (cmd_arr[i]->fd_in != STDIN_FILENO && cmd_arr[i]->fd_in > 0) - if (close(cmd_arr[i]->fd_in) == -1) + if (pipeline[i]->fd_in != STDIN_FILENO && pipeline[i]->fd_in > 0) + if (close(pipeline[i]->fd_in) == -1) perror("close()"); - if (cmd_arr[i]->fd_out != STDOUT_FILENO && cmd_arr[i]->fd_out > 0) - if (close(cmd_arr[i]->fd_out) == -1) + if (pipeline[i]->fd_out != STDOUT_FILENO && pipeline[i]->fd_out > 0) + if (close(pipeline[i]->fd_out) == -1) perror("close()"); i++; } - ft_free_2d_arr(cmd_arr); } diff --git a/srcs/init.c b/srcs/init.c index 5052a64..75b2484 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/11/13 05:31:47 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 03:45:10 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,10 +19,11 @@ int init(t_all *c, char *envp[]) { g_all = c; ft_bzero(c, sizeof (*c)); - c->envp = ft_dup_2d_arr(envp, (t_dup_func)ft_strdup); // TEST WIP + c->envp = ft_dup_2d_arr(envp, (t_dup_f)ft_strdup); // TEST WIP if (!c->envp) return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); //print_matrix(c->envp, "\n --- \n"); // TEST WIP + c->path = retrieve_path(c->envp); // No return check. Its intended. PATH is optional c->prompt_base = init_prompt_base(); if (!c->prompt_base) return (ft_reti_perror(0, "init_prompt_base() error")); @@ -39,7 +40,24 @@ int init(t_all *c, char *envp[]) return (1); } -static char *init_prompt_base(void) +// TODO : Un appel à builtin_export() modifiant $PATH doit aussi entrainer un appel à "c->path = retrieve_path()" +char **retrieve_path(char *envp[]) +{ + char *path; + char **path_split; + + (void)envp; + //path = search_env_var(envp, "PATH"); // A reprendre du projet pipex si besoin de remplacer getenv() + path = getenv("PATH"); + if (!path) + return (ft_retp_print(NULL, "minishell: Warning, $PATH not set\n", 2)); + path_split = ft_split(path, ':'); + if (!path_split) + return (ft_retp_perror(NULL, "retrieve_path()")); + return (path_split); +} + +static char *init_prompt_base(void) // WIP, error return TODO { char *prompt_base; char *tmp; @@ -59,7 +77,7 @@ static char *init_prompt_base(void) return (prompt_base); } -static char *init_prompt(char *prompt_base) +static char *init_prompt(char *prompt_base) // WIP, error return TODO { char *prompt; diff --git a/srcs/parsing/expansions/words_expansions.c b/srcs/parsing/expansions/words_expansions.c index 400e286..a802bee 100644 --- a/srcs/parsing/expansions/words_expansions.c +++ b/srcs/parsing/expansions/words_expansions.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/07 02:01:33 by lperrey #+# #+# */ -/* Updated: 2021/11/14 10:13:38 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 03:45:15 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -63,7 +63,7 @@ int token_expansions(t_token **t) if (!tmp_split) return (0); // 4 - tmp = ft_dup_2d_arr(tmp_split, (t_dup_func)ft_strdup_quotes); + tmp = ft_dup_2d_arr(tmp_split, (t_dup_f)ft_strdup_quotes); ft_free_2d_arr(tmp_split); tmp_split = tmp; if (!tmp_split) diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index d97c3ce..4025472 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/11/14 12:53:40 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 08:02:56 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -79,11 +79,11 @@ t_cmd **parsing(t_token *token_list) // 2.9.1 - 3) Redirection if (!redirections(token_list, cmd_arr)) - return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr)); + return (ft_retp_free(NULL, &cmd_arr, (t_free_f)free_pipeline)); // Struct CMD fill if (!cmd_array_fill_argv(token_list, cmd_arr)) - return (ft_retp_free(NULL, cmd_arr, (void(*)(void *))ft_free_cmd_arr)); + return (ft_retp_free(NULL, &cmd_arr, (t_free_f)free_pipeline)); print_cmd_array(cmd_arr); // HUGO WIP diff --git a/srcs/parsing/redirections/redirections.c b/srcs/parsing/redirections/redirections.c index 0870bcd..0363e0b 100644 --- a/srcs/parsing/redirections/redirections.c +++ b/srcs/parsing/redirections/redirections.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/11 18:46:43 by lperrey #+# #+# */ -/* Updated: 2021/11/14 10:04:21 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 08:08:18 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,15 +24,18 @@ int redirections(t_token *t, t_cmd **cmd_arr) i = 0; while (t) { - if (t->id == '<' || t->id == T_DLESS) + if (cmd_arr[i]->pid == 0) // Pid var as error mark, WIP { - if (!redirect_cmd_input(t, cmd_arr[i])) - return (0); - } - else if (t->id == '>' || t->id == T_DGREAT) - { - if (!redirect_cmd_output(t, cmd_arr[i])) - return (0); + if (t->id == '<' || t->id == T_DLESS) + { + if (!redirect_cmd_input(t, cmd_arr[i])) + return (0); + } + else if (t->id == '>' || t->id == T_DGREAT) + { + if (!redirect_cmd_output(t, cmd_arr[i])) + return (0); + } } else if (t->id == '|') i++; @@ -43,7 +46,7 @@ int redirections(t_token *t, t_cmd **cmd_arr) static int redirect_cmd_input(t_token *t, t_cmd *cmd) { - if (cmd->fd_in != STDIN_FILENO && cmd->fd_in > 0) + if (cmd->fd_in != STDIN_FILENO) if (close(cmd->fd_in) == -1) perror("close()"); if (t->id == '<') @@ -55,7 +58,10 @@ static int redirect_cmd_input(t_token *t, t_cmd *cmd) //EXPAND_AND_QUOTE_REMOVAL_PLACEHOLDER(); cmd->fd_in = open(t->next->content, O_RDONLY); if (cmd->fd_in == -1) - ft_perror_io("open() ", t->next->content); + { + ft_perror_io("open() ", t->next->content); // todo error + cmd->pid = -1; // Pid var as error mark, WIP + } } else if (t->id == T_DLESS) { @@ -70,7 +76,7 @@ static int redirect_cmd_output(t_token *t, t_cmd *cmd) { int flags; - if (cmd->fd_out != STDOUT_FILENO && cmd->fd_out > 0) + if (cmd->fd_out != STDOUT_FILENO) if (close(cmd->fd_out) == -1) perror("close()"); // TODO : Expansion + quote removal sur le word t->next->content. @@ -85,6 +91,9 @@ static int redirect_cmd_output(t_token *t, t_cmd *cmd) flags = flags | O_APPEND; cmd->fd_out = open(t->next->content, flags, S_IRWXU); if (cmd->fd_out == -1) - return (ft_reti_perror_io(0, "open() ", t->next->content)); + { + ft_perror_io("open() ", t->next->content); + cmd->pid = -1; // Pid var as error mark, WIP + } return (1); } diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 683aa32..f202194 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/14 03:59:01 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 03:52:37 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -41,12 +41,8 @@ void shell_loop(t_all *c) ft_lstclear((t_list **)&c->token_list, free); if (!c->cmd_arr) continue ; - // Search Path/builtins - // Bien penser à mettre les ptr à NULL aprés free en cas d'erreur (pour ne pas double free si appel à free_exit()) // Exec Pipeline - //execute_cmd(c->envp, c->cmd_arr); - ft_free_cmd_arr(c->cmd_arr); - c->cmd_arr = NULL; + exec_cmd_line(c); } else if (!line_input) write(1, "\n", 1); From 26993144ccf8badd1378cf46a7e4f8c6886a09b6 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Wed, 17 Nov 2021 01:35:06 +0100 Subject: [PATCH 10/10] CO-CODE Hugo-Luke + signals handling adjusted + wait_subshell() with last_exit_status + miscs --- headers/minishell_prototypes.h | 5 +- srcs/exec_cmd_line.c | 57 ++++++++++-- srcs/free.c | 9 +- srcs/main.c | 11 +-- srcs/parsing/HUGO_WIP.c | 4 +- srcs/parsing/expansions/ft_split_MODIF.c | 106 +++++++++++++++++++++++ srcs/shell_loop.c | 106 ++--------------------- srcs/signals.c | 15 +--- 8 files changed, 185 insertions(+), 128 deletions(-) create mode 100644 srcs/parsing/expansions/ft_split_MODIF.c diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 8186d56..064ffce 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/11/16 21:06:00 by lperrey ### ########.fr */ +/* Updated: 2021/11/16 22:58:35 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -80,7 +80,6 @@ char **ft_split_quotes(char const *s, char c); char *ft_strdup_quotes(const char *s); // signals.c -void sigint_handler_interactiv(int signum); -void sigint_handler_execution(int signum); +void sigint_handler_interactive(int signum); #endif diff --git a/srcs/exec_cmd_line.c b/srcs/exec_cmd_line.c index b690dd5..49c1796 100644 --- a/srcs/exec_cmd_line.c +++ b/srcs/exec_cmd_line.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/16 08:42:01 by lperrey ### ########.fr */ +/* Updated: 2021/11/17 01:08:38 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,9 +18,10 @@ int pipeline(t_all *c); int open_pipes(t_cmd *pipeline[]); int pipeline_access_cmd(t_cmd *pipeline[], char *path[]); -void pipeline_exec(t_cmd *pipeline[], t_all *c); +pid_t pipeline_exec(t_cmd *pipeline[], t_all *c); int cmd_exec_in_subshell(t_cmd *cmd, t_all *c); int simple_cmd_builtin(t_cmd *cmd, t_all *c); +void wait_subshell(pid_t last_cmd_pid, int *last_exit_status); int exec_cmd_line(t_all *c) { @@ -45,9 +46,8 @@ int pipeline(t_all *c) } else { - pipeline_exec(c->cmd_arr, c); + wait_subshell(pipeline_exec(c->cmd_arr, c), &c->last_exit_status); free_pipeline(&c->cmd_arr); - // TODO wait process here } return (1); } @@ -95,7 +95,7 @@ int simple_cmd_builtin(t_cmd *cmd, t_all *c) // TODO : Change exit status as in documentation : // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 -void pipeline_exec(t_cmd *pipeline[], t_all *c) +pid_t pipeline_exec(t_cmd *pipeline[], t_all *c) { int i; int ret; @@ -103,7 +103,7 @@ void pipeline_exec(t_cmd *pipeline[], t_all *c) i = 0; while (pipeline[i]) { - if (pipeline[i]->pid == 0) // Pid var as error mark, WIP + if (!pipeline[i]->error) { ret = cmd_exec_in_subshell(pipeline[i], c); if (ret != EXIT_SUCCESS) @@ -111,6 +111,49 @@ void pipeline_exec(t_cmd *pipeline[], t_all *c) } i++; } + close_pipeline_fd(c->cmd_arr); + i -= 1; + if (pipeline[i]->error) + c->last_exit_status = pipeline[i]->error; + return (pipeline[i]->pid); +} + +int handle_wait_error(void) +{ + if (errno == ECHILD) + return (-1); + else if (errno == EINTR) + return (0); + else + perror("wait()"); + return (-1); +} + +void wait_subshell(pid_t last_cmd_pid, int *last_exit_status) +{ + int wstatus; + int ret; + + //wstatus = 0; + if (last_cmd_pid > 0) + { + if (waitpid(last_cmd_pid, &wstatus, 0) == -1) + perror("waitpid()"); + if (WIFEXITED(wstatus)) + *last_exit_status = WEXITSTATUS(wstatus); + } + ret = 0; + while (ret != -1) + { + ret = wait(&wstatus); + if (ret == -1) + ret = handle_wait_error(); + } + if (WIFSIGNALED(wstatus)) + { + write(STDIN_FILENO, "\n", 1); + *last_exit_status = 128 + WTERMSIG(wstatus); + } } int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) @@ -120,6 +163,8 @@ int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) perror("fork()"); if (cmd->pid == 0) { + c->signal_behaviour.sa_handler = SIG_DFL; + sigaction(SIGINT, &c->signal_behaviour, NULL); if (cmd->fd_in != STDIN_FILENO) if (dup2(cmd->fd_in, STDIN_FILENO) == -1) return (ft_reti_perror(EXIT_FAILURE, "dup2()")); diff --git a/srcs/free.c b/srcs/free.c index 54c37c6..b933fc4 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/11/16 22:24:36 by lperrey ### ########.fr */ +/* Updated: 2021/11/17 01:25:35 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,6 +18,7 @@ int free_exit(t_all *c, int exit_status) 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 ft_free_2d_arr(c->envp); + ft_free_2d_arr(c->path); free_pipeline(&c->cmd_arr); //if (c->termios_changed) // tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); @@ -55,11 +56,17 @@ void close_pipeline_fd(t_cmd *pipeline[]) while (pipeline[i]) { if (pipeline[i]->fd_in != STDIN_FILENO && pipeline[i]->fd_in > 0) + { if (close(pipeline[i]->fd_in) == -1) perror("close()"); + pipeline[i]->fd_in = 0; + } if (pipeline[i]->fd_out != STDOUT_FILENO && pipeline[i]->fd_out > 0) + { if (close(pipeline[i]->fd_out) == -1) perror("close()"); + pipeline[i]->fd_out = 0; + } i++; } } diff --git a/srcs/main.c b/srcs/main.c index 6227695..b423b02 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/11/02 14:03:31 by hulamy ### ########.fr */ +/* Updated: 2021/11/08 04:05:41 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,9 +20,10 @@ int main(int argc, char *argv[], char *envp[]) (void)argv; if (!init(&c, envp)) free_exit(&c, EXIT_FAILURE); - if (isatty(STDIN_FILENO)) - shell_loop(&c); - else - shell_script(&c); + putenv("VAR=W1 W2 W3"); // TEMP TEST + //if (isatty(STDIN_FILENO)) + shell_loop(&c); + //else + // shell_script(&c); return (0); } diff --git a/srcs/parsing/HUGO_WIP.c b/srcs/parsing/HUGO_WIP.c index d37fdb5..9865c25 100644 --- a/srcs/parsing/HUGO_WIP.c +++ b/srcs/parsing/HUGO_WIP.c @@ -73,7 +73,7 @@ int fill_builtin(t_cmd *cmd, int (*builtin)(int, char **, t_all *)) } int handle_builtin(t_cmd *cmd) -{ +{ // Il faut penser à comparer un char de plus (\0 inclus) if (!ft_strncmp(cmd->argv[0], "echo", 4)) return (fill_builtin(cmd, &builtin_echo)); // else if (!ft_strncmp(cmd->argv[0], "cd", 2)) @@ -133,7 +133,7 @@ void fd_redirection(t_token *token, t_cmd *cmd) if (token->id == T_LESS) // '<' { - flag = O_RDONLY | O_CREAT; + flag = O_RDONLY | O_CREAT; // O_CREAT ? Pourquoi donc ? if (cmd->fd_in != 0) close(cmd->fd_in); cmd->fd_in = open(token->next->content, flag); diff --git a/srcs/parsing/expansions/ft_split_MODIF.c b/srcs/parsing/expansions/ft_split_MODIF.c new file mode 100644 index 0000000..e60f6e4 --- /dev/null +++ b/srcs/parsing/expansions/ft_split_MODIF.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_split_MODIF.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/11/13 07:08:40 by lperrey #+# #+# */ +/* Updated: 2021/11/13 20:24:33 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +// FT_SPLIT LEGEREMENT REMANIER. +// A REMPLACER DANS LA LIBFT +#include "libft.h" + +static size_t count_word(char const *s, char c); +static char **alloc_words(char const *s, char c, char **str_arr, + size_t words_count); +static void fill_arr(char const *s, char c, char **str_arr); + +char **ft_split(char const *s, char c) +{ + char **str_arr; + size_t words_count; + + if (s == NULL) + return (NULL); + words_count = count_word(s, c); + str_arr = ft_calloc(words_count + 1, sizeof(char *)); + if (!str_arr) + return (NULL); + if (!(alloc_words(s, c, str_arr, words_count))) + { + ft_free_2d_arr(str_arr); + return (NULL); + } + fill_arr(s, c, str_arr); + return (str_arr); +} + +static size_t count_word(char const *s, char c) +{ + unsigned int i; + size_t count; + + count = 0; + i = 0; + while (s[i]) + { + while (s[i] == c) + i++; + if (s[i]) + count++; + while (s[i] && s[i] != c) + i++; + } + return (count); +} + +static char **alloc_words(char const *s, char c, char **str_arr, + size_t words_count) +{ + unsigned int i; + size_t len; + unsigned int arr_i; + + i = 0; + arr_i = 0; + while (arr_i < words_count) + { + len = 0; + while (s[i] == c) + i++; + while (s[i] && s[i] != c) + { + len++; + i++; + } + str_arr[arr_i] = malloc(len + 1); + if (!str_arr[arr_i]) + return (NULL); + arr_i++; + } + return (str_arr); +} + +static void fill_arr(char const *s, char c, char **str_arr) +{ + unsigned int i; + unsigned int arr_i; + unsigned int char_i; + + i = 0; + arr_i = 0; + while (str_arr[arr_i]) + { + while (s[i] == c) + i++; + char_i = 0; + while (s[i] && s[i] != c) + str_arr[arr_i][char_i++] = s[i++]; + str_arr[arr_i][char_i] = '\0'; + arr_i++; + } +} diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 38913b2..f60c5b0 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/16 21:22:32 by lperrey ### ########.fr */ +/* Updated: 2021/11/17 01:30:27 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,9 +24,13 @@ void shell_loop(t_all *c) { if (line_input) free(line_input); + c->signal_behaviour.sa_handler = sigint_handler_interactive; + sigaction(SIGINT, &c->signal_behaviour, NULL); line_input = readline(c->prompt); if (line_input && *line_input) { + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &c->signal_behaviour, NULL); add_history(line_input); // Lexing c->token_list = input_to_tokens(line_input); @@ -43,105 +47,7 @@ void shell_loop(t_all *c) else if (!line_input) { write(1, "exit\n", 5); - exit(0); + free_exit(c, c->last_exit_status); } } } - -// WIP HUGO -void close_fd(t_cmd *cmd) -{ - if (cmd->fd_in != 0) - close(cmd->fd_in); - if (cmd->fd_out != 1) - close(cmd->fd_out); -} - -// WIP HUGO -void execute_cmd(char **envp, t_cmd **cmd_arr, t_all *c) -{ - pid_t pid; - pid_t wpid; - int wstatus; - int i; - int argc; - - // put signal handling for SIGINT to ignore so parent process will not activate signal_handling_executiv while childs are in process - c->signal_behaviour.sa_handler = SIG_IGN; - sigaction(SIGINT, &c->signal_behaviour, NULL); - i = 0; - while(cmd_arr[i]) - { - pid = fork(); - if (pid == 0) - { - // activate singal handling for execution mode - c->signal_behaviour.sa_handler = sigint_handler_execution; - sigaction(SIGINT, &c->signal_behaviour, NULL); - if (cmd_arr[i]->fd_in != 0) - dup2(cmd_arr[i]->fd_in, STDIN_FILENO); - if (cmd_arr[i]->fd_out != 1) - dup2(cmd_arr[i]->fd_out, STDOUT_FILENO); - close_fd(cmd_arr[i]); - if (cmd_arr[i]->builtin_func) - { - argc = 0; - while (cmd_arr[i]->argv[argc]) - argc++; - cmd_arr[i]->builtin_func(argc, cmd_arr[i]->argv, c); - exit(0); - } - else - { - write(1, "1", 1); - execve(cmd_arr[i]->argv[0], cmd_arr[i]->argv, envp); - } - } - else - close_fd(cmd_arr[i]); - i++; - } - // waitpid pour la derniere commande (pour '$?') - wpid = 1; - while (wpid > 0) - wpid = wait(&wstatus); - // to print a \n after execve was terminated by a signal - if (WIFSIGNALED(wstatus)) - write(1, "\n", 1); - // put signal handling for sigint back to the signal handler for interactiv mode - c->signal_behaviour.sa_handler = sigint_handler_interactiv; - sigaction(SIGINT, &c->signal_behaviour, NULL); -} - -/* void test_signal(t_all *c) -{ - // 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); - } -} */ diff --git a/srcs/signals.c b/srcs/signals.c index 35b7d43..b04dfc0 100644 --- a/srcs/signals.c +++ b/srcs/signals.c @@ -6,31 +6,24 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ -/* Updated: 2021/11/15 20:08:26 by hulamy ### ########.fr */ +/* Updated: 2021/11/16 22:58:29 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void sigint_handler_interactiv(int signum) +void sigint_handler_interactive(int signum) { (void)signum; write(1, "\n", 1); - rl_replace_line("", 1); rl_on_new_line(); + rl_replace_line("", 1); rl_redisplay(); } -void sigint_handler_execution(int signum) -{ - (void)signum; - write(1, "\n", 1); -// exit(0); -} - int set_signals_handling(struct sigaction *signal_behaviour) { - signal_behaviour->sa_handler = sigint_handler_interactiv; + signal_behaviour->sa_handler = sigint_handler_interactive; sigaction(SIGINT, signal_behaviour, NULL); signal_behaviour->sa_handler = SIG_IGN; sigaction(SIGQUIT, signal_behaviour, NULL);