/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* exec.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/11/27 15:32:29 by tmaze #+# #+# */ /* Updated: 2019/01/16 17:26:43 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" #define S_BIN 5 char **envlsttotab(t_list *env) { size_t i; size_t env_size; t_list *tmp; char **ret; i = 0; tmp = env; env_size = ft_lstsize(env); if ((ret = (char**)ft_memalloc(sizeof(char*) * (env_size + 1))) == NULL) return (NULL); while (i <= env_size) ret[i++] = NULL; i = 0; while (tmp) { if ((ret[i] = ft_strnew(ft_strlen(((t_envelem*)(tmp->content))->key) + ft_strlen(((t_envelem*)(tmp->content))->val) + 1)) == NULL) { ft_del_words_tables(&ret); return (NULL); } i++; tmp = tmp->next; } return (ret); } /* ** , {"setenv", &cmd_senv}, {"unsetenv", &cmd_senv}, {"env", &cmd_env}}; */ char *check_path(char *exec, t_list *env) { size_t i; t_envelem *path; char **path_elems; char *tmp; char *ret; i = 0; ret = NULL; if ((path = env_getelemfromkey("PATH", env)) == NULL || path->val == NULL) return (NULL); if ((path_elems = ft_strsplit(path->val,':')) == NULL) return (NULL); while (path_elems[i]) { if ((tmp = ft_strjoin(path_elems[i], "/")) == NULL) break ; if ((ret = ft_strjoin(tmp, exec)) == NULL) ft_strdel(&tmp); if (ret == NULL) break ; ft_strdel(&tmp); if (access(ret, F_OK) == 0 && access(ret, X_OK) == 0) break ; ft_strdel(&ret); i++; } ft_del_words_tables(&path_elems); return (ret); } int exec_cmd(char **argv, t_list **env) { int ret; char **env_tab; 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}}; 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 { ft_del_words_tables(&env_tab); return (-1); } if ((ret = fork()) == 0) { if (path != NULL) execve(path, argv, env_tab); ft_putendl_fd("minishell: error", 2); ft_strdel(&path); ft_del_words_tables(&env_tab); exit(-1); } else if (ret == -1) ft_putendl_fd("minishell: error", 2); if (ret == -1) return (-1); waitpid(ret, NULL, 0); ft_del_words_tables(&env_tab); return (0); }