diff --git a/srcs/exec.c b/srcs/exec.c index f448e4d..2528f16 100644 --- a/srcs/exec.c +++ b/srcs/exec.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/11/27 15:32:29 by tmaze #+# #+# */ -/* Updated: 2019/01/16 17:26:43 by tmaze ### ########.fr */ +/* Updated: 2019/01/17 17:43:00 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -47,32 +47,131 @@ char **envlsttotab(t_list *env) ** , {"setenv", &cmd_senv}, {"unsetenv", &cmd_senv}, {"env", &cmd_env}}; */ +int ft_isin(char *str, char c) +{ + int i; + + i = 0; + while (str[i]) + if (str[i++] == c) + return (i - 1); + return (-1); +} + +void put_error(char *file, char *msg) +{ + ft_putstr("minishell: "); + ft_putstr(file); + ft_putstr(": "); + ft_putendl(msg); +} + +char *check_path_slash(char *exec) +{ + int i; + struct stat info; + + if (ft_isin(exec, '/') != -1 && ft_isin(exec, '.') == -1) + { + if ((i = access(exec, F_OK)) != 0) + put_error(exec, "no such file or directory"); + if (i != 0) + return (NULL); + if ((i = stat(exec, &info)) != 0) + put_error(exec, "can't determine info"); + if (i != 0) + return (NULL); + if (!S_ISREG(info.st_mode)) + { + put_error(exec, "not an executable file"); + return (NULL); + } + if ((i = access(exec, X_OK)) != 0) + put_error(exec, "permission denied"); + if (i != 0) + return (NULL); + return (exec); + } + return (NULL); +} + +char *check_path_dot(char *exec, t_list *env) +{ + t_envelem *path; + char *tmp; + char *ret; + + if (exec[0] == '.') + { + if ((path = env_getelemfromkey("PWD", env)) == NULL + || path->val == NULL) + { + put_error(exec, "memory error"); + return (NULL); + } + if ((tmp = ft_strjoin(path->val, "/")) == NULL) + put_error(exec, "memory error"); + if (tmp == NULL) + return (NULL); + if ((ret = ft_strjoin(tmp, exec)) == NULL) + { + put_error(exec, "memory error"); + ft_strdel(&tmp); + return (NULL); + } + ft_strdel(&tmp); + if (access(ret, F_OK) == 0) + { + if (access(ret, X_OK) == 0) + return (ret); + put_error(exec, "permission denied"); + ft_strdel(&ret); + return (NULL); + } + put_error(exec, "no such file or directory"); + ft_strdel(&ret); + } + return (NULL); +} + char *check_path(char *exec, t_list *env) { - size_t i; + size_t i; t_envelem *path; - char **path_elems; - char *tmp; - char *ret; + char **path_elems; + char *tmp; + char *ret; i = 0; ret = NULL; + if ((ret = check_path_slash(exec)) != NULL) + return (ret); + if ((ret = check_path_dot(exec, env)) != NULL) + return (ret); if ((path = env_getelemfromkey("PATH", env)) == NULL || path->val == NULL) return (NULL); - if ((path_elems = ft_strsplit(path->val,':')) == NULL) + if ((path_elems = ft_strsplit(path->val, ':')) == NULL) return (NULL); while (path_elems[i]) { if ((tmp = ft_strjoin(path_elems[i], "/")) == NULL) + put_error(exec, "memory error"); + if (tmp == NULL) break ; if ((ret = ft_strjoin(tmp, exec)) == NULL) + { + put_error(exec, "memory error"); ft_strdel(&tmp); - if (ret == NULL) break ; + } ft_strdel(&tmp); - if (access(ret, F_OK) == 0 && access(ret, X_OK) == 0) - break ; + if (access(ret, F_OK) == 0) + { + if (access(ret, X_OK) == 0) + break ; + put_error(exec, "permission denied"); + } ft_strdel(&ret); i++; } @@ -87,31 +186,25 @@ int exec_cmd(char **argv, t_list **env) char *path; size_t i; static t_builtin builtins[S_BIN] = {{"echo", &cmd_echo}, - {"cd", &cmd_cd}, {"setenv", &cmd_setenv}, - {"env", &cmd_env}, {"unsetenv", &cmd_unsetenv}}; + {"cd", &cmd_cd}, {"setenv", &cmd_setenv}, + {"env", &cmd_env}, {"unsetenv", &cmd_unsetenv}}; i = 0; - path = NULL; while (i < S_BIN) if (ft_strcmp(argv[0], builtins[i++].cmd) == 0) return ((*(builtins[i - 1].f))(argv, env)); if ((env_tab = envlsttotab(*env)) == NULL) return (-1); - if (argv[0][0] == '/' && access(argv[0], F_OK) == 0 && access(argv[0], X_OK) == 0) - path = argv[0]; - else if ((path = check_path(argv[0], *env)) == NULL) - ft_putendl_fd("minishell: error path check", 2); - else - { + if ((path = check_path(argv[0], *env)) == NULL) ft_del_words_tables(&env_tab); + if (path == NULL) return (-1); - } if ((ret = fork()) == 0) { - if (path != NULL) - execve(path, argv, env_tab); + execve(path, argv, env_tab); ft_putendl_fd("minishell: error", 2); - ft_strdel(&path); + if (ft_strcmp(path, argv[0]) != 0) + ft_strdel(&path); ft_del_words_tables(&env_tab); exit(-1); } @@ -121,5 +214,7 @@ int exec_cmd(char **argv, t_list **env) return (-1); waitpid(ret, NULL, 0); ft_del_words_tables(&env_tab); + if (ft_strcmp(path, argv[0]) != 0) + ft_strdel(&path); return (0); }