/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* caller.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: mea +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/03 11:48:16 by narnaud #+# #+# */ /* Updated: 2022/05/11 15:29:42 by narnaud@stude ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static void exe(t_datas *datas, t_command *cmd); static pid_t caller(t_datas *datas, t_command *cmd); int is_builtin(char *cmd) { int cmd_len; cmd_len = ft_strlen(cmd) + 1; if (!ft_strncmp(cmd, "echo", ft_min(cmd_len, 5)) \ || !ft_strncmp(cmd, "pwd", ft_min(cmd_len, 4)) \ || !ft_strncmp(cmd, "cd", ft_min(cmd_len, 3)) \ || !ft_strncmp(cmd, "export", ft_min(cmd_len, 7)) \ || !ft_strncmp(cmd, "unset", ft_min(cmd_len, 6)) \ || !ft_strncmp(cmd, "env", ft_min(cmd_len, 4)) \ || !ft_strncmp(cmd, "exit", ft_min(cmd_len, 5))) return (1); else return (0); } int builtin_call(t_datas *datas, t_command *cmd) { if (ft_strncmp(cmd->argv[0], "echo", 5) == 0) return (ft_echo(cmd)); else if (ft_strncmp(cmd->argv[0], "pwd", 4) == 0) return (ft_pwd(cmd)); else if (ft_strncmp(cmd->argv[0], "cd", 3) == 0) return (ft_cd(cmd)); else if (ft_strncmp(cmd->argv[0], "export", 7) == 0) return (ft_export(datas, cmd)); else if (ft_strncmp(cmd->argv[0], "unset", 6) == 0) return (ft_unset(datas, cmd)); else if (ft_strncmp(cmd->argv[0], "env", 4) == 0) return (ft_env(datas, cmd)); else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0) return (ft_exit(datas, cmd)); else return (-1); } int check_skip(t_datas *datas, t_command *cmd) { if (cmd->next && ((cmd->ope == AND && !datas->exit_code) \ || (cmd->ope == OR && datas->exit_code))) return (0); return (1); } int piper(t_datas *datas, t_command *cmd) { int pip[2]; pid_t pid; int status; if (cmd->ope == PIPE) { pipe(pip); if (!cmd->fd[1]) cmd->fd[1] = pip[1]; if (!cmd->fd[0]) cmd->next->fd[0] = pip[0]; } pid = caller(datas, cmd); if (cmd->fd[1]) close(cmd->fd[1]); if (cmd->fd[0]) close(cmd->fd[0]); if (DEBUG) printf("%s -ope: %d, pid: %d, fdin: %d, fdout: %d\n", cmd->argv[0], cmd->ope, pid, cmd->fd[0], cmd->fd[1]); if (cmd->ope == PIPE) pid = piper(datas, cmd->next); else { waitpid(pid, &status, 0); datas->exit_code = handle_status(datas, status); while (cmd->next && check_skip(datas, cmd)) cmd = cmd->next; if (cmd->next) piper(datas, cmd->next); } return (1); } static void exe(t_datas *datas, t_command *cmd) { char **path_dirs; char *path; size_t path_length; if (ft_strchr(cmd->argv[0], '/')) execve(cmd->argv[0], cmd->argv, datas->envp); else { path_dirs = ft_split(getenv("PATH"), ':'); while (path_dirs) { path_length = ft_strlen(*path_dirs) + ft_strlen(cmd->argv[0]) + 2; path = ft_calloc(path_length, sizeof(char)); ft_memcpy(path, *path_dirs, ft_strlen(*path_dirs)); ft_memcpy(path + ft_strlen(*path_dirs), "/", 1); ft_memcpy(path + ft_strlen(*path_dirs) + 1, \ cmd->argv[0], ft_strlen(cmd->argv[0])); execve(path, cmd->argv, datas->envp); free(path); path_dirs++; } } } static pid_t caller(t_datas *datas, t_command *cmd) { pid_t pid; pid = fork(); if (!pid) { if (builtin_call(datas, cmd) == -1) { if (cmd->fd[0]) { dup2(cmd->fd[0], STDIN_FILENO); close(cmd->fd[0]); } if (cmd->fd[1]) { dup2(cmd->fd[1], STDOUT_FILENO); close(cmd->fd[1]); } exe(datas, cmd); } exit(EXIT_SUCCESS); } return (pid); }