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); }