diff --git a/src/env/env_manip.c b/src/env/env_manip.c index 501469e..ce4e82f 100644 --- a/src/env/env_manip.c +++ b/src/env/env_manip.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* env_manip.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: khais +#+ +:+ +#+ */ +/* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/19 17:55/24 by khais #+# #+# */ -/* Updated: 2025/03/19 17:55:24 by khais ### ########.fr */ +/* Created: 2025/03/19 17:55:24 by khais #+# #+# */ +/* Updated: 2025/03/21 18:49:56 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,7 +49,7 @@ void env_rm_entry(t_env **env, char *key) if (env == NULL || (*env) == NULL) return ; - if (strncmp((*env)->key, key, INT_MAX) == 0) + if (ft_strncmp((*env)->key, key, INT_MAX) == 0) { next = (*env)->next; env_destroy_node(*env); @@ -59,7 +59,7 @@ void env_rm_entry(t_env **env, char *key) current = *env; while (current->next) { - if (strncmp(current->next->key, key, INT_MAX) == 0) + if (ft_strncmp(current->next->key, key, INT_MAX) == 0) { next = current->next; current->next = next->next; diff --git a/src/ft_errno.c b/src/ft_errno.c index 69aa835..9adb212 100644 --- a/src/ft_errno.c +++ b/src/ft_errno.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/21 12:40:46 by khais #+# #+# */ -/* Updated: 2025/03/10 16:56:52 by khais ### ########.fr */ +/* Updated: 2025/03/21 16:18:57 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,6 +53,9 @@ char *ft_strerror(t_errno errno) [FT_EUNEXPECTED_PIPE] = "minishell: syntax error near unexpected token `|'", [FT_EMALFORMED_REDIRECTION] = "minishell: malformed redirection (perhaps a \ missing filename)", + [FT_ENOMEM] = "Cannot allocate memory", + [FT_STATFAIL] = "minishell: stat: internal failure", + [FT_ISDIR] = "Is a directory", }; if (errno >= 0 && errno < FT_EMAXERRNO) diff --git a/src/subst/simple_filename_exp.c b/src/subst/simple_filename_exp.c index ffb8d3d..6e4fce2 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/19 16:46:55 by jguelen ### ########.fr */ +/* Updated: 2025/03/21 17:33:50 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,6 +45,17 @@ static char **get_paths_array(t_env *env) return (path_array); } +/* +** Utility function that attempts to find a regular executable file for which +** the execution rights are granted. It disregards non-regular files and so in +** particular directories (note that using stat allows us to follow symlinks to +** their target if encountered). If a file is found here for which the execution +** permission is not granted and no elligible file was found before its path is +** stored inside oldpath so that in case no file is found to be executable it +** is the value stored in oldpath that will be used resulting in a Permission +** denied error. oldpath is to store the first occurrence of a regular file +** corresponding to the filepath but not executable. +*/ static char *select_path(char *filepath, char **oldpath, char **path, struct stat *fstat) { @@ -58,7 +69,7 @@ static char *select_path(char *filepath, char **oldpath, char **path, { if (access(filepath, X_OK) != 0) { - if (!oldpath) + if (!(*oldpath)) *oldpath = filepath; } else @@ -70,6 +81,14 @@ static char *select_path(char *filepath, char **oldpath, char **path, } /* +** This function exists to implement the bash behaviour specific to where +** the PATH variable has been set with a non-empty value. +** It checks the working directory if there is a void inside PATH and tries to +** find the executable command inside the path entry itself otherwise +** disregarding directories and selecting the first entry that both exists and +** is executable. If no such entry exists but one or more regular file(s) +** exist(s) with the correct name in one of the entries (it therefore lacks the +** execution permission) this function will return the first found. ** Returns NULL if an error occurred or nothing corresponds to filename ** in PATH. ft_errno is set in the course of this function to help distinguish ** the nature of the case. @@ -104,6 +123,16 @@ static char *deal_with_filled_path(char *filename, char **path, } /* +** This function searches the environment to resolve a full path for an +** executable file corresponding to filename. It deals with two types of bash +** behaviours: a PATH unset or corresponding to an empty value and a PATH set +** and with a non-empty value. +** In the first case it searches the current working directory for the file +** coorresponding to filename. If no regular file is found it returns NULL and +** distinguishes the case where a directory was found corresponding to filename +** by setting ft_errno to FT_ISDIR. +** The second case is dealt with using deal_with_filled_path (see the function +** itself for details). ** Returns NULL on error or if nothing is found. */ static char *filepath_from_env(char *filename, t_minishell *app) diff --git a/src/subst/subst.h b/src/subst/subst.h index 52f8abe..aeb6ad5 100644 --- a/src/subst/subst.h +++ b/src/subst/subst.h @@ -6,7 +6,7 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/23 15:01:40 by jguelen #+# #+# */ -/* Updated: 2025/03/19 09:20:02 by jguelen ### ########.fr */ +/* Updated: 2025/03/21 18:47:30 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,5 +42,6 @@ char *get_cmdpath(const char *name, t_minishell *app); void destroy_pattern_check(char **pattern_check, size_t len); void build_pattern_checks(char *str, t_worddesc *pattern, char **checker); +void clean_pattern(t_worddesc *file_pattern); #endif diff --git a/src/subst/variable_subst.c b/src/subst/variable_subst.c index 640dcc5..795aea1 100644 --- a/src/subst/variable_subst.c +++ b/src/subst/variable_subst.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/19 17:28/29 by khais #+# #+# */ -/* Updated: 2025/03/19 17:28:29 by khais ### ########.fr */ +/* Updated: 2025/03/21 17:38:16 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -101,9 +101,9 @@ static char *calculate_replacement(t_worddesc *word, t_minishell *app, size_t i, { rep = env_get_val(app->env, id); if (!rep) - rep = strdup(""); + rep = ft_strdup(""); else - rep = strdup(rep); + rep = ft_strdup(rep); if (!rep) return (NULL); } diff --git a/src/subst/wildcard_exp.c b/src/subst/wildcard_exp.c index f812c36..ee62d15 100644 --- a/src/subst/wildcard_exp.c +++ b/src/subst/wildcard_exp.c @@ -6,7 +6,7 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/20 15:01:38 by jguelen #+# #+# */ -/* Updated: 2025/03/20 16:53:31 by jguelen ### ########.fr */ +/* Updated: 2025/03/21 18:42:04 by jguelen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,18 +50,30 @@ static DIR *open_current_dir(void) return (dir); } +/* +** Adds filename to the end of the wordlist *list by creating a worddesc whose +** word is filename and marker makes filename be considered fully single +** quoted. +** NOTE: In case of error, this function destroys *list in a similar fashion +** as worddesc_create destroys its first parameter in case of failure. +*/ static t_wordlist *add_file_to_list(t_wordlist **list, char *filename) { t_worddesc *file_desc; char *copy; + char *marker; copy = ft_strdup(filename); if (!copy) return (wordlist_destroy(*list), NULL); - file_desc = worddesc_create(copy, '\0', NULL); + marker = construct_repeting_char_string('\'', ft_strlen(copy)); + if (!marker) + return (wordlist_destroy(*list), free(copy), NULL); + file_desc = worddesc_create(copy, '\0', marker); if (!file_desc) { wordlist_destroy(*list); + free(marker); return (NULL); } *list = wordlist_push(*list, file_desc); @@ -117,7 +129,10 @@ static t_wordlist *expand_star_core(t_worddesc *file_pattern) ** Takes only into account the * wildcard or ?, those characters ** NOTE: for a pattern to accept '.' as the first character of a filename ** it must be explicitly matched (only for the first character though). -** Similarly, '/' is never to be matched except if given explicitly. +** Similarly, '/' is never to be matched except if given explicitly as per +** bash requirement. This is a note in case of future expansion as in our case +** here we do not have to deal with that since we concern ourselves only with +** the current working directory. */ char fits_pattern(char *str, t_worddesc *pattern) { @@ -156,25 +171,6 @@ char fits_pattern(char *str, t_worddesc *pattern) */ t_wordlist *expand_star(t_worddesc *file_pattern) { - size_t i; - char *tmp; - - i = 0; - while (file_pattern->word[i]) - { - if (file_pattern->marker[i] != '\'' && file_pattern->marker[i] != '"' - && file_pattern->marker[i] != '&' && file_pattern->marker[i] != '$' - && (file_pattern->word[i] == '\'' || file_pattern->word[i] == '"')) - { - tmp = replace_in_str(file_pattern->word, i, i, NULL); - free(file_pattern->word); - file_pattern->word = tmp; - tmp = replace_in_str(file_pattern->marker, i, i, NULL); - free(file_pattern->marker); - file_pattern->marker = tmp; - continue ; - } - i++; - } + clean_pattern(file_pattern); return (expand_star_core(file_pattern)); }