/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* pipeline.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ /* Updated: 2021/11/18 14:12:36 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" static int open_pipes(t_cmd *pipeline[]); static int pipeline_find_access(t_cmd *pipeline[], char *path[]); static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c); int pipeline(t_all *c) { if (!open_pipes(c->cmd_arr)) return (0); if (!pipeline_find_access(c->cmd_arr, c->path)) return (0); if (ft_2d_arrlen(c->cmd_arr) == 1 && c->cmd_arr[0]->builtin_func) simple_command_builtin(c->cmd_arr[0], c); else wait_subshell(pipeline_exec(c->cmd_arr, c), &c->last_exit_status); free_pipeline(&c->cmd_arr); return (1); } static int open_pipes(t_cmd *pipeline[]) { int i; int pipes[2]; i = 0; while (pipeline[i] && pipeline[i + 1]) { if (pipe(pipes) == -1) return (ft_reti_perror(0, "pipe()")); if (pipeline[i]->fd_out == STDOUT_FILENO) pipeline[i]->fd_out = pipes[STDOUT_FILENO]; else if (close(pipes[STDOUT_FILENO]) == -1) perror("close()"); if (pipeline[i]->fd_in == STDIN_FILENO) pipeline[i + 1]->fd_in = pipes[STDIN_FILENO]; else if (close(pipes[STDIN_FILENO]) == -1) perror("close()"); i++; } return (1); } static int pipeline_find_access(t_cmd *pipeline[], char *path[]) { int i; i = 0; while (pipeline[i]) { if (!cmd_find_access(pipeline[i], path)) return (0); i++; } return (1); } // TODO : Change exit status as in documentation : // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_08_02 static pid_t pipeline_exec(t_cmd *pipeline[], t_all *c) { int i; int ret; i = 0; while (pipeline[i]) { if (!pipeline[i]->error) { ret = cmd_exec_in_subshell(pipeline[i], c); if (ret != EXIT_SUCCESS) free_exit(c, ret); } i++; } close_pipeline_fd(c->cmd_arr); i -= 1; if (pipeline[i]->error) c->last_exit_status = pipeline[i]->error; return (pipeline[i]->pid); }