/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* e_pipes.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: rbousset +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/14 17:19:27 by rbousset #+# #+# */ /* Updated: 2020/02/14 17:19:29 by rbousset ### ########lyon.fr */ /* */ /* ************************************************************************** */ #include #include #include #ifdef __linux__ # include #else # include #endif #include #include "e_builtins.h" #include "e_pipes_next.h" #include "f_fail.h" #include "s_lpipes.h" #include "s_struct.h" #include "u_utils.h" #include "u_path.h" static unsigned char e_get_current_path(char fullpath[], struct s_lpipes *ptr, t_msh *msh) { unsigned char fp_ret; fp_ret = 0; if (ptr->com->bin != NULL && ft_ischarset("/.", ptr->com->bin[0]) == TRUE) { ft_strlcpy(fullpath, ptr->com->bin, PATH_MAX); } else if (ptr->com->bin != NULL) { if (u_get_builtin_id(ptr->com->bin) < B_BUILTINS_COUNT) { ft_strlcpy(fullpath, "builtin", 8); } else { fp_ret = u_search_in_path(fullpath, ptr->com->bin, PATH_MAX, msh); } } return (fp_ret); } /* ** TODO: handle fork() failed, etc */ static int e_unroll_pipes(int fd[256][2], size_t pipes, t_msh *msh) { struct s_lpipes *head; char fullpath[PATH_MAX]; int pid; unsigned short i; unsigned char fp_ret; head = msh->pipes; i = 0; while (i <= pipes && i < 255) { fp_ret = e_get_current_path(fullpath, head, msh); if ((pid = fork()) == 0) { if (i != 0) dup2(fd[i - 1][E_WRITE_END], STDIN_FILENO); if (i != pipes) dup2(fd[i][E_READ_END], STDOUT_FILENO); e_close_unused_fds(fd, pipes); e_pipe_child(fullpath, fp_ret, head->com, msh); } head = head->next; i++; } return (pid); } /* ** TODO: error mgmnt */ static void e_pipe_exec(size_t pipes, t_msh *msh) { int fd[256][2]; int pid; int status; unsigned short i; i = 0; while (i < pipes && i < 255) { pipe(fd[i]); i++; } pid = e_unroll_pipes(fd, pipes, msh); i = 0; while (i < pipes && i < 255) { close(fd[i][E_WRITE_END]); close(fd[i][E_READ_END]); i++; } waitpid(pid, &status, 0); msh->ret = WEXITSTATUS(status); } void e_pipes(t_msh *msh) { const size_t pipes = e_get_pipes_count(msh->pipes); e_pipe_exec(pipes, msh); s_lpipes_clear(&msh->pipes); }