/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* e_externs_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 #include #include #include #include #include "d_define.h" #include "e_externs_next.h" #include "f_fail.h" #include "m_redirs.h" #include "s_destroy.h" #include "s_line.h" #include "s_lpipes.h" #include "s_struct.h" #include "u_utils.h" static uint8_t get_builtin_id(const char com[], t_msh *msh) { uint8_t i; i = 0; while (msh->bu_ref[i] && ft_strncmp(com, msh->bu_ref[i], ft_strlen(msh->bu_ref[i]) + 1) != 0) { i++; } return (i); } static void e_pipe_child(char *fullpath[], uint8_t pipe_id, t_com *ptr, t_msh *msh) { uint8_t bu_id; uint8_t ret; dup_redirs(ptr, msh); if (ft_strncmp(fullpath[pipe_id], "builtin", 8) == 0) { bu_id = get_builtin_id(ptr->bin, msh); ret = msh->bu_ptr[bu_id](ptr->argv + 1, msh); u_eof_fd(msh->fd); s_lpipes_clear(&msh->pipes); s_line_clear(&msh->curr); s_destroy(msh); ft_delwords(fullpath); exit(ret); } else execve(fullpath[pipe_id], ptr->argv, msh->envp); /* TODO: handle execve failed */ } static size_t e_get_pipes_count(struct s_lpipes *ptr) { struct s_lpipes *rptr; size_t pipes; rptr = ptr; pipes = 0; while (rptr->next != NULL) { rptr = rptr->next; pipes++; } return (pipes); } static void e_pipe_exec_path(char *fullpath[], struct s_lpipes *head, t_msh *msh) { int fd[256][2]; size_t pipes; size_t i; size_t j; int pid; int status; /* TODO: norm, error mgmnt */ pipes = e_get_pipes_count(head); i = 0; while (i < pipes) { pipe(fd[i]); i++; } i = 0; while (i <= pipes) { if ((pid = fork()) == 0) { if (i != 0) dup2(fd[i - 1][FT_WRITE_END], STDIN_FILENO); if (i != pipes) dup2(fd[i][FT_READ_END], STDOUT_FILENO); j = 0; while (j < pipes) { close(fd[j][FT_WRITE_END]); close(fd[j][FT_READ_END]); j++; } e_pipe_child(fullpath, i, head->com, msh); } head = head->next; i++; } i = 0; while (i < pipes) { close(fd[i][FT_WRITE_END]); close(fd[i][FT_READ_END]); i++; } waitpid(pid, &status, 0); msh->ret = WEXITSTATUS(status); } void e_externs_pipes(struct s_lpipes *ptr, t_msh *msh) { struct s_lpipes *head; struct s_lpipes *rptr; char **envpath; char **fullpath; size_t i; size_t pipes; uint8_t bu_id; head = ptr; rptr = ptr; pipes = e_get_pipes_count(head); if ((fullpath = (char **)malloc((pipes + 2) * sizeof(char *))) == NULL) f_alloc_and_destroy_msh(msh); fullpath[pipes + 1] = NULL; i = 0; while (rptr != NULL) { if (ft_ischarset("/.", rptr->com->bin[0]) == TRUE) { if ((fullpath[i] = ft_strdup(rptr->com->bin)) == NULL) f_alloc_and_destroy_msh(msh); } else if ((envpath = get_env_path(msh)) != NULL) { if ((bu_id = get_builtin_id(rptr->com->bin, msh)) < FT_BUILTINS_COUNT) { if ((fullpath[i] = ft_strdup("builtin")) == NULL) f_alloc_and_destroy_msh(msh); } else fullpath[i] = search_in_path(rptr->com->bin, envpath, msh); ft_delwords(envpath); } i++; rptr = rptr->next; } i = 0; e_pipe_exec_path(fullpath, head, msh); ft_delwords(fullpath); }