diff --git a/Makefile b/Makefile index 68ba330..c9fa4f1 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: tmaze +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2019/03/27 16:51:02 by tmaze #+# #+# # -# Updated: 2019/09/20 14:39:42 by tmaze ### ########.fr # +# Updated: 2019/09/27 16:13:51 by tmaze ### ########.fr # # # #******************************************************************************# @@ -27,7 +27,7 @@ endif # Compilator CC = gcc -FLAGS = -Wall -Wextra -Werror +FLAGS = -Wall -Wextra -Werror -g # Folders LIBDIR = libft @@ -42,6 +42,7 @@ SRC = main.c \ cmd_unsetenv.c \ cmd_cd.c \ cmd_echo.c \ + ms_exec.c \ ms_env.c OBJ = $(SRC:.c=.o) diff --git a/includes/minishell.h b/includes/minishell.h index 98c4574..a4569c0 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2018/11/18 13:12:34 by tmaze #+# #+# */ -/* Updated: 2019/09/26 16:53:31 by tmaze ### ########.fr */ +/* Updated: 2019/09/27 16:09:09 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,5 +42,9 @@ void lstdelelem(t_env **elem); void lstdel(t_env **env); t_env *lstnew(char *env); t_env *lstaddend(t_env **alst, t_env *new); +t_env *lstgetelem(char *key, t_env *env); +char **lsttotab(t_env *env); + +int exec_cmd(char **argv, t_env **env); #endif diff --git a/srcs/main.c b/srcs/main.c index 8d7754e..32437be 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/19 17:08:46 by tmaze #+# #+# */ -/* Updated: 2019/09/26 16:48:49 by tmaze ### ########.fr */ +/* Updated: 2019/09/27 16:12:10 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -75,8 +75,7 @@ int main(void) } if (i == S_BIN) { -// exec cmd - ft_printf("exec %s...\n", argv[0]); + exec_cmd(argv, &env); } } ft_del_words_tables(&argv); diff --git a/srcs/ms_env.c b/srcs/ms_env.c index 9d9169a..cca57b9 100644 --- a/srcs/ms_env.c +++ b/srcs/ms_env.c @@ -6,7 +6,7 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/20 11:43:53 by tmaze #+# #+# */ -/* Updated: 2019/09/26 16:48:37 by tmaze ### ########.fr */ +/* Updated: 2019/09/27 16:21:14 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ @@ -68,3 +68,51 @@ t_env *lstaddend(t_env **alst, t_env *new) return (*alst); } +t_env *lstgetelem(char *key, t_env *env) +{ + t_env *it; + + it = env; + while (it && !ft_strequ(it->key, key)) + it = it->next; + return (it); +} + +char **lsttotab(t_env *env) +{ + t_env *it; + char *new; + char **ret; + size_t size; + int i; + + i = 0; + ret = NULL; + it = env; + while (it) + { + i++; + it = it->next; + } + if ((ret = (char**)ft_memalloc(sizeof(char*) * (i + 1))) == NULL) + return (NULL); + while (i >= 0) + ret[i--] = NULL; + it = env; + i = 0; + while (it) + { + size = ft_strlen(it->key) + ft_strlen(it->val) + 1; + if ((new = ft_strnew(size)) == NULL) + { + ft_del_words_tables(&ret); + break ; + } + ft_strlcpy(new, it->key, size); + ft_strlcat(new, "=", size); + ft_strlcat(new, it->val, size); + ret[i++] = new; + it = it->next; + } + return (ret); +} diff --git a/srcs/ms_exec.c b/srcs/ms_exec.c index 58c1428..cde4cf7 100644 --- a/srcs/ms_exec.c +++ b/srcs/ms_exec.c @@ -6,20 +6,164 @@ /* By: tmaze +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/09/26 16:25:00 by tmaze #+# #+# */ -/* Updated: 2019/09/26 16:43:05 by tmaze ### ########.fr */ +/* Updated: 2019/09/27 16:52:50 by tmaze ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -char *check_path(char *cmd, char *path) +int ft_isin(char *str, char c) { - char **splitpath; - int i; + int i; - if ((splitpath = ft_strsplit(path, ':')) != NULL) + 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 (exec && ft_isin(exec, '/') != -1 && ft_isin(exec, '.') == -1) { - i = 0; + if ((i = access(exec, F_OK)) != 0) + put_error(exec, "no such file or directory"); + if (i != 0) + return (exec); + if ((i = stat(exec, &info)) != 0) + put_error(exec, "can't determine info"); + if (i != 0) + return (exec); + if (!S_ISREG(info.st_mode)) + { + put_error(exec, "not an executable file"); + return (exec); + } + if ((i = access(exec, X_OK)) != 0) + put_error(exec, "permission denied"); + return (exec); } return (NULL); } + +char *check_path_dot(char *exec, t_env *env) +{ + t_env *path; + char *tmp; + char *ret; + + if (exec && exec[0] == '.') + { + if ((path = lstgetelem("PWD", env)) == NULL + || path->val == NULL || (tmp = ft_strjoin(path->val, "/")) == NULL) + { + put_error(exec, "memory error"); + return (exec); + } + if ((ret = ft_strjoin(tmp, exec)) == NULL) + put_error(exec, "memory error"); + ft_strdel(&tmp); + if (ret == NULL) + return (exec); + if (access(ret, F_OK) == 0) + { + if (access(ret, X_OK) == 0) + return (ret); + put_error(exec, "permission denied"); + ft_strdel(&ret); + return (exec); + } + 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 ((ret = check_path_slash(exec)) != NULL + || (ret = check_path_dot(exec, env)) != NULL) + return (ret); + if ((path = lstgetelem("PATH", env)) == NULL + || path->val == NULL + || (path_elems = ft_strsplit(path->val, ':')) == NULL) + 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); + 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); +}