/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ms_exec.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/26 16:25:00 by tmaze #+# #+# */ /* Updated: 2019/10/18 14:10:59 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" int ft_isin(char *str, char c) { int i; i = 0; while (str && 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 ((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); } char *check_path_dot(char *exec, t_env *env) { t_env *path; char *tmp; char *ret; if ((path = lstgetelem("PWD", env)) == NULL || path->val == NULL || (tmp = ft_strjoin(path->val, "/")) == NULL) { put_error(exec, "memory error"); return (NULL); } if ((ret = ft_strjoin(tmp, exec)) == NULL) put_error(exec, "memory error"); ft_strdel(&tmp); if (ret == NULL) return (NULL); if (access(ret, F_OK) == 0) { if (access(ret, X_OK) == 0) return (exec); 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_env *env) { size_t i; t_env *path; char **path_elems; char *tmp; char *ret; ret = NULL; if (exec) { if (ft_isin(exec, '/') != -1 && ft_isin(exec, '.') == -1) { if ((ret = check_path_slash(exec)) != NULL) return (ret); else return (NULL); } if (exec[0] == '.') { if ((ret = check_path_dot(exec, env)) != NULL) return (ret); else return (NULL); } if ((path = lstgetelem("PATH", env)) == NULL || path->val == NULL || (path_elems = ft_strsplit(path->val, ':')) == NULL) { put_error(exec, "could not resolve path"); return (NULL); } i = 0; 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); break ; } ft_strdel(&tmp); if (access(ret, F_OK) == 0) { if (access(ret, X_OK) == 0) break ; put_error(exec, "permission denied"); } ft_strdel(&ret); i++; } if (path_elems[i] == NULL) put_error(exec, "command not found"); ft_del_words_tables(&path_elems); } return (ret); } int exec_cmd(char **argv, t_env **env) { int ret; char **env_tab; char *path; if ((env_tab = lsttotab(*env)) == NULL) return (-1); if ((path = check_path(argv[0], *env)) == NULL) ft_del_words_tables(&env_tab); if (path == NULL) return (-1); if ((ret = fork()) == 0) { execve(path, argv, env_tab); ft_putendl_fd("minishell: error", 1); if (ft_strcmp(path, argv[0]) != 0) ft_strdel(&path); ft_del_words_tables(&env_tab); lstdel(env); exit(-1); } else if (ret == -1) ft_putendl_fd("minishell: error", 1); if (ret == -1) return (-1); waitpid(ret, NULL, 0); ft_del_words_tables(&env_tab); if (ft_strcmp(path, argv[0]) != 0) ft_strdel(&path); return (0); }