diff --git a/Makefile b/Makefile index 892938b..fd56e97 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,11 @@ CC = clang CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) -DIR_SRCS = srcs srcs/builtins srcs/lexing \ +DIR_SRCS = srcs srcs/builtins \ + srcs/lexing \ srcs/parsing srcs/parsing/valid_syntax \ - srcs/parsing/expansions srcs/parsing/redirections + srcs/parsing/expansions srcs/parsing/redirections \ + srcs/exec INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) diff --git a/libft b/libft index 56b4037..d58ee38 160000 --- a/libft +++ b/libft @@ -1 +1 @@ -Subproject commit 56b403736934a9ef2552671986afb77223f3cfeb +Subproject commit d58ee38bab0a9e0449d98efc9522b124c71632fd diff --git a/srcs/exec_cmd_line.c b/srcs/exec/exec_cmd_line.c similarity index 62% rename from srcs/exec_cmd_line.c rename to srcs/exec/exec_cmd_line.c index 49c1796..f532117 100644 --- a/srcs/exec_cmd_line.c +++ b/srcs/exec/exec_cmd_line.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ -/* Updated: 2021/11/17 01:08:38 by lperrey ### ########.fr */ +/* Updated: 2021/11/18 12:31:04 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,7 @@ int pipeline(t_all *c); int open_pipes(t_cmd *pipeline[]); -int pipeline_access_cmd(t_cmd *pipeline[], char *path[]); +int pipeline_find_access(t_cmd *pipeline[], char *path[]); 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); @@ -37,18 +37,19 @@ int pipeline(t_all *c) { if (!open_pipes(c->cmd_arr)) return (0); - if (!pipeline_access_cmd(c->cmd_arr, c->path)) + if (!pipeline_find_access(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 - { wait_subshell(pipeline_exec(c->cmd_arr, c), &c->last_exit_status); - free_pipeline(&c->cmd_arr); - } + free_pipeline(&c->cmd_arr); + return (1); +} + +int simple_cmd_builtin(t_cmd *cmd, t_all *c) +{ + // TODO return (1); } @@ -77,19 +78,110 @@ int open_pipes(t_cmd *pipeline[]) return (1); } -int pipeline_access_cmd(t_cmd *pipeline[], char *path[]) +// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 +// faire des test sur la valeur de errno selon les cas (if directory, if pathname invalid, ...) +int handle_access_error(char *file_name) { - // TODO - // Penser à : path = strdup(argv[0]); - // et non : path = argv[0]; - // pour ne pas double free + int tmp; + tmp = errno; + ft_perror_io("minishell: ", file_name); + errno = tmp; + if (errno == EACCES) + return (127); + return (1); + // 126 +} + +static t_builtin_f search_builtin(char *cmd_name) +{ + if (ft_strncmp(cmd_name, "echo", 4 + 1) == 0) + return (&builtin_echo); + else if (ft_strncmp(cmd_name, "cd", 2 + 1) == 0) + return (&builtin_cd); + else if (ft_strncmp(cmd_name, "pwd", 3 + 1) == 0) + return (&builtin_pwd); + else if (ft_strncmp(cmd_name, "export", 6 + 1) == 0) + return (&builtin_export); + else if (ft_strncmp(cmd_name, "unset", 5 + 1) == 0) + return (&builtin_unset); + else if (ft_strncmp(cmd_name, "env", 3 + 1) == 0) + return (&builtin_env); + else if (ft_strncmp(cmd_name, "exit", 4 + 1) == 0) + return (&builtin_exit); + return (NULL); +} + +static int search_cmd_path(char *cmd_name, char **cmd_path, char *path[]) +{ + int i; + + if (!path) + return (1); + cmd_name = ft_strjoin("/", cmd_name); + if (!cmd_name) + return (ft_reti_perror(-1, "search_cmd_path()")); + i = 0; + while (path[i]) + { + *cmd_path = ft_strjoin(path[i], cmd_name); + if (!*cmd_path) + return (ft_reti_perror(-1, "search_cmd_path()")); + if (access(*cmd_path, X_OK) == 0) + break ; + else + { + free(*cmd_path); + *cmd_path = NULL; // TODO : free_null() + } + i++; + } + free(cmd_name); return (1); } -int simple_cmd_builtin(t_cmd *cmd, t_all *c) +int cmd_find_access(t_cmd *cmd, char *path[]) { - // TODO + if (ft_strchr(cmd->argv[0], '/')) + { + if (access(cmd->argv[0], X_OK) == -1) + cmd->error = handle_access_error(cmd->argv[0]); + else + { + cmd->path = ft_strdup(cmd->argv[0]); + if (!cmd->path) + return (0); + } + } + else + { + cmd->builtin_func = search_builtin(cmd->argv[0]); + if (cmd->builtin_func) + return (1); + if (search_cmd_path(cmd->argv[0], &cmd->path, path) == -1) + return (0); + if (!cmd->path) + { + cmd->error = 127; + ft_putstr_fd("minishell: ", 2); + ft_putstr_fd(cmd->argv[0], 2); + ft_putstr_fd(": command not found\n", 2); + } + } + return (1); +} + +int pipeline_find_access(t_cmd *pipeline[], char *path[]) +{ + int i; + + i = 0; + while (pipeline[i]) + { + if (!cmd_find_access(pipeline[i], path)) + return (0); + i++; + } return (1); } @@ -134,7 +226,7 @@ void wait_subshell(pid_t last_cmd_pid, int *last_exit_status) int wstatus; int ret; - //wstatus = 0; + wstatus = 0; if (last_cmd_pid > 0) { if (waitpid(last_cmd_pid, &wstatus, 0) == -1) @@ -174,10 +266,8 @@ int cmd_exec_in_subshell(t_cmd *cmd, t_all *c) 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 + else if (execve(cmd->path, cmd->argv, c->envp) == -1) 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 b933fc4..aec90fa 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/17 01:25:35 by lperrey ### ########.fr */ +/* Updated: 2021/11/18 03:09:46 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ int free_exit(t_all *c, int exit_status) { free(c->prompt_base); free(c->prompt); - ft_lstclear((t_list **)&c->token_list, free); // a voir avec Hugo, il y a un truc qui me semble superflu dans la fonction + ft_lstclear((t_list **)&c->token_list, free); ft_free_2d_arr(c->envp); ft_free_2d_arr(c->path); free_pipeline(&c->cmd_arr); diff --git a/srcs/parsing/expansions/new_token_for_each_field.c b/srcs/parsing/expansions/new_token_for_each_field.c index 38298b9..90db9a9 100644 --- a/srcs/parsing/expansions/new_token_for_each_field.c +++ b/srcs/parsing/expansions/new_token_for_each_field.c @@ -56,7 +56,7 @@ static t_token *insert_tokens(t_token *t, t_token *insert_lst) t->id = 0; free(t->content); - t->content = NULL; + t->content = NULL; // TODO : free_null() if (!insert_lst) return (t); diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index f60c5b0..9aae71c 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -34,6 +34,8 @@ void shell_loop(t_all *c) add_history(line_input); // Lexing c->token_list = input_to_tokens(line_input); + free(line_input); + line_input = NULL; // TODO : free_null() if (!c->token_list) continue ; // Parsing