/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* caller.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: mea +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/05/03 11:48:16 by narnaud #+# #+# */ /* Updated: 2022/05/16 10:42:40 by mea ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static void call_binary(t_datas *datas, t_command *cmd); static pid_t call(t_datas *datas, t_command *cmd); int call_builtin(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, 0)); else if (ft_strncmp(cmd->argv[0], "exit", 5) == 0) return (ft_exit(datas, cmd)); else return (-1); } static void call_binary(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 call(t_datas *datas, t_command *cmd) { pid_t pid; pid = fork(); if (!pid) { if (call_builtin(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]); } if (cmd->ope == PIPE) close(cmd->next->fd[0]); call_binary(datas, cmd); } exit(EXIT_SUCCESS); } return (pid); } void create_pipe(t_command *cmd) { int pip[2]; if (cmd->ope != PIPE) return ; pipe(pip); if (!cmd->fd[1]) cmd->fd[1] = pip[1]; else close(pip[1]); if (!cmd->next->fd[0]) cmd->next->fd[0] = pip[0]; else close(pip[0]); } int caller(t_datas *datas, t_command *cmd) { int status; create_pipe(cmd); cmd->pid = call(datas, cmd); if (cmd->fd[0]) close(cmd->fd[0]); if (cmd->fd[1]) close(cmd->fd[1]); if (cmd->ope == PIPE) caller(datas, cmd->next); waitpid(cmd->pid, &status, 0); datas->exit_code = handle_status(datas, status); if (cmd->ope != PIPE) { while (cmd->next && !((cmd->ope == AND && !datas->exit_code) \ || (cmd->ope == OR && datas->exit_code))) cmd = cmd->next; if (cmd->next) caller(datas, cmd->next); } return (1); }