diff options
Diffstat (limited to 'src/get_cmd_path.c')
| -rw-r--r-- | src/get_cmd_path.c | 148 |
1 files changed, 114 insertions, 34 deletions
diff --git a/src/get_cmd_path.c b/src/get_cmd_path.c index 8a27584..713c397 100644 --- a/src/get_cmd_path.c +++ b/src/get_cmd_path.c @@ -6,28 +6,35 @@ /* By: chuhlig <chuhlig@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/12/17 19:19:59 by chuhlig #+# #+# */ -/* Updated: 2024/12/17 19:20:08 by chuhlig ### ########.fr */ +/* Updated: 2025/01/22 00:01:48 by chuhlig ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" #include "minishell.h" +#include <errno.h> +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/unistd.h> +#include <unistd.h> -static char *get_absolute_cmd_path(char *cmd, t_env *env); -static char *find_in_path(char *cmd, t_env *env); +static char *get_simple_cmd_path(char *cmd, int *return_code); +static char *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code); +static char *find_in_path(char *cmd, t_env *env, int *return_code); char **get_split_path(t_env *env); +static int is_directory(char *path); -char *get_cmd_path(char *cmd, t_env *env) +char *get_cmd_path(char *cmd, t_env *env, int *return_code) { if (cmd[0] == '/') - return (ft_strdup(cmd)); + return (get_simple_cmd_path(cmd, return_code)); else if (ft_strchr(cmd, '/')) - return (get_absolute_cmd_path(cmd, env)); + return (get_absolute_cmd_path(cmd, env, return_code)); else - return (find_in_path(cmd, env)); + return (find_in_path(cmd, env, return_code)); } -static char *get_absolute_cmd_path(char *cmd, t_env *env) +static char *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code) { char *cur_dir; char *result; @@ -38,45 +45,118 @@ static char *get_absolute_cmd_path(char *cmd, t_env *env) result = ft_strjoin(cur_dir, cmd); free(cur_dir); if (!result) - return (NULL); + return (error(ENOENT, cmd, 127, return_code)); + if (access(result, F_OK) == -1) + { + free(result); + return (error(ENOENT, cmd, 127, return_code)); + } if (access(result, X_OK) == -1) { free(result); - return (NULL); + return (error(EACCES, cmd, 126, return_code)); } + if (is_directory(cmd)) + return (error(EISDIR, cmd, 126, return_code)); return (result); } -static char *find_in_path(char *cmd, t_env *env) +void free_split_path(char **path) +{ + char **tmp = path; + while (*tmp) + { + free(*tmp); + tmp++; + } + free(path); +} + +char **get_split_path(t_env *env) { - char *cur_path; - char *cmd_path; - char **path; + char *path_env; + char **split_path; - path = get_split_path(env); - cmd_path = NULL; - while (*path) + path_env = env_get(env, "PATH"); + if (!path_env) + return (NULL); + split_path = ft_split(path_env, ':'); + free(path_env); + return (split_path); +} + +static char *find_in_path(char *cmd, t_env *env, int *return_code) +{ + char *cur_path; + char *cmd_path; + char **path; + char **path_start; // To keep track of the start of the path array + + path = get_split_path(env); + path_start = path; // Save the start of the path array + cmd_path = NULL; + while (*path) + { + if (cmd_path) + free(cmd_path); + cur_path = ft_strjoin(*path, "/"); + if (!cur_path) + { + free_split_path(path_start); // Free the entire path array + return (NULL); + } + cmd_path = ft_strjoin(cur_path, cmd); + free(cur_path); + if (!cmd_path) + { + free_split_path(path_start); // Free the entire path array + return (NULL); + } + if (access(cmd_path, X_OK) != -1) + { + free_split_path(path_start); // Free the entire path array + return (cmd_path); + } + path++; + } + free_split_path(path_start); // Free the entire path array + *return_code = 127; + command_not_found_error(cmd); + return (NULL); +} + +static char *get_simple_cmd_path(char *cmd, int *return_code) +{ + char *result; + + result = ft_strdup(cmd); + if (!result) + return (NULL); + if (access(result, F_OK) == -1) + { + free(result); + return (error(ENOENT, cmd, 127, return_code)); + } + if (access(result, X_OK) == -1) { - if (cmd_path) - free(cmd_path); - cur_path = ft_strjoin(*path, "/"); - if (!cur_path) - return (NULL); - cmd_path = ft_strjoin(cur_path, cmd); - free(cur_path); - if (!cmd_path) - return (NULL); - if (access(cmd_path, X_OK) != -1) - return (cmd_path); - path++; + free(result); + return (error(EACCES, cmd, 126, return_code)); } - return (NULL); + if (is_directory(cmd)) + { + free(result); + return (error(EISDIR, cmd, 126, return_code)); + } + return (result); } -char **get_split_path(t_env *env) +static int is_directory(char *path) { - char *path; + struct stat path_stat; - path = env_get(env, "PATH"); - return (ft_split(path, ':')); + stat(path, &path_stat); + if ((path_stat.st_mode & S_IFMT) == S_IFDIR) + return (1); + else + return (0); } |
