/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* pipeline.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/16 01:57:38 by lperrey #+# #+# */ /* Updated: 2021/11/29 12:26:27 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->pipeline)) return (0); if (!pipeline_find_access(c->pipeline, c->path)) return (0); if (ft_2d_arrlen(c->pipeline) == 1 && c->pipeline[0]->builtin_func) simple_command_builtin(c->pipeline[0], c); else wait_subshell(pipeline_exec(c->pipeline, c)); free_pipeline(&c->pipeline); 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->pipeline); i -= 1; if (pipeline[i]->error) set_last_exit_status(pipeline[i]->error); return (pipeline[i]->pid); }