From 35d391a813fdc466a634fa8a2bc6b3566d6d23d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gu=C3=A9len?= Date: Tue, 18 Mar 2025 12:52:07 +0100 Subject: [PATCH] Expansion: Pre dividing of filepath_from_env I still need to implement the cleaning of filename that is passed to expand_star Recheck .h files in case I forgot to declare some of my functions in them. Recheck if the Makefile indeed has all the sources listed. Rework the tests after the evolution of our structures. --- src/ft_errno.h | 5 +-- src/subst/simple_filename_exp.c | 63 ++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/ft_errno.h b/src/ft_errno.h index 1c89f38..6890fa7 100644 --- a/src/ft_errno.h +++ b/src/ft_errno.h @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* ft_errno.h :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: khais +#+ +:+ +#+ */ +/* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/21 12:40:58 by khais #+# #+# */ -/* Updated: 2025/03/10 16:38:28 by khais ### ########.fr */ +/* Updated: 2025/03/21 10:13:38 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,6 +23,7 @@ typedef enum e_errno FT_EBADID, FT_EUNEXPECTED_PIPE, FT_EMALFORMED_REDIRECTION, + FT_STATFAIL, FT_EMAXERRNO, } t_errno; diff --git a/src/subst/simple_filename_exp.c b/src/subst/simple_filename_exp.c index 2a4db7a..8683aa4 100644 --- a/src/subst/simple_filename_exp.c +++ b/src/subst/simple_filename_exp.c @@ -6,7 +6,7 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/02 13:40:10 by jguelen #+# #+# */ -/* Updated: 2025/03/15 11:30:56 by jguelen ### ########.fr */ +/* Updated: 2025/03/18 12:37:03 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,10 @@ #include #include +/* +** TODO REMAKE the getting of path from env regarding the bash behaviors with a +** PATH variable with an empty value. +*/ /* ** Returns a malloc-allocated string corresponding to ** "path_dir/name" @@ -42,25 +46,24 @@ char *alloc_path(char *path_dir, char *name) /* ** The return value of this function is always safe to destroy with ** path_split_destroy. +** Returns a NULL-terminated array containing each possible path contained +** in the PATH environnement variable. ** Returns NULL in case of an allocation error. */ static char **get_paths_array(t_env *env) { char **path_array; - char *path_val; + t_env *path_node; - path_val = env_get_val(env, "PATH"); - if (path_val == NULL) + path_node = env_get_val(env, "PATH"); + if (path_node == NULL || !path_node->value || !path_node->value[0]) { - path_array = ft_calloc(2, sizeof(char *)); + path_array = ft_calloc(1, sizeof(char *)); if (!path_array) return (NULL); - path_array[0] = ft_calloc(1, sizeof(char)); - if (path_array[0] == NULL) - return (free(path_array), NULL); return (path_array); } - path_array = path_split(path_val, ':'); + path_array = path_split(path_node->value, ':'); if (!path_array) return (NULL); return (path_array); @@ -69,38 +72,66 @@ static char **get_paths_array(t_env *env) /* ** TODO Do I need to preserve the entry if found to be a directory in case ** there is no other later? +** Returns NULL on error or if nothing is found. */ char *filepath_from_env(char *filename, t_minishell *app) { char *filepath; + char *oldpath; char **path; size_t i; struct stat file_stat; path = get_paths_array(app->env); if (path == NULL) - return (NULL); + return (ft_errno(FT_ENOMEM), NULL); + i = 0; + oldpath = NULL; + if (!path[0]) + { + ret = stat(filepath, &file_stat); + if (ret == -1) + return (ft_errno(FT_STATFAIL), NULL); + if (access(filepath, F_OK) == 0) + { + if (S_ISDIR(file_stat.st_mode) && !oldpath) + oldpath = filepath; + else if (S_ISREG(file_stat.st_mode)) + return (alloc_path(".", filename)); + } + } while (path[i]) { if (!path[i][0]) filepath = alloc_path(".", filename); else filepath = alloc_path(path[i], filename); - ret = stat(filepath, &file_stat); // Deal with possible failure of stat + ret = stat(filepath, &file_stat); + if (ret == -1) + return (ft_errno(FT_STATFAIL), NULL); if (access(filepath, F_OK) == 0 && ret == 0 && S_ISREG(file_stat.st_mode)) - return (destroy_split_array(path), filepath); - free(filepath); + { + if (access(filepath, X_OK) != 0) + { + if (!oldpath) + oldpath = filepath; + } + else + return (free(oldpath), destroy_split_array(path), filepath); + } + if (oldpath != filepath) + free(filepath); i++; } destroy_split_array(path); - return (NULL); + return (oldpath); } /* ** Returns a malloc-allocated string representing the full path to ** the command or executable corresponding to name or NULL in case of -** failure or . +** failure and sets ft_errno in accordance. ** NOTE: if name contains a '/' character then name is considered to ** be an absolute path. */ @@ -108,7 +139,7 @@ char *get_filepath(const char *name, t_minishell *app) { char *cmd_path; - if (ft_strchr(name, '/')) + if (ft_trchr(name, '/')) { cmd_path = ft_strdup(name); if (!cmd_path)