diff --git a/include/include.h b/include/include.h index ceff3ef..6118011 100644 --- a/include/include.h +++ b/include/include.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/05/13 10:22:54 by jschaft ### ########.fr */ +/* Updated: 2024/05/15 18:10:34 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -52,13 +52,11 @@ typedef struct s_command int output_fd; // fd to use with '>' redirection (1 by default) } t_command; -// To make a list of pipe when needed +// An element of a list of pipes typedef struct s_pipes { - int pipe[2]; // simple pipe - int i; //index of the pipe - int inout; //in case of first or last pipe -} t_pipes; + int pipe[2]; // Simple pipe, we write on pipe[1] and we read on pipe[0] +} t_pipes; // Return the t_command representing the command given by the user. // If error, return a t_command wth the value .error = true. diff --git a/src/exec_command.c b/src/exec_command.c index ee7823f..d36107d 100644 --- a/src/exec_command.c +++ b/src/exec_command.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */ -/* Updated: 2024/05/15 12:04:07 by mcolonna ### ########.fr */ +/* Updated: 2024/05/16 13:25:23 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,75 +26,75 @@ static void free_tab(char **tab) free(tab); } -// TODO is t_call.argv ended by NULL? -static void fork_exec(const char *path, t_call call, t_pipes in, t_pipes out, - char *const envp[]) -{ - if (in.i != 0) - dup2(in.pipe[1], 0); - else - dup2(in.inout, 0); - if (out.inout == 0) - dup2(out.pipe[0], 1); - else - dup2(out.inout, 1); - execve(path, call.argv, envp); -} - -static int execute_call(t_memclass mc, t_command cmd, t_pipes in, t_pipes out, +// Execute the call with stdin = in and stdout = out. +// Find the program in $PATH +static int execute_call(t_memclass mc, t_call call, int in, int out, char *const envp[]) { char **const path = get_path(envp); pid_t pid; const char *program_path; - int status; - int i; - i = in.i; - program_path = search_path(mc, (const char **)path, cmd.calls[i].program); - if (i == 0) - in.inout = cmd.input_fd; - if (out.inout == -1) - out.inout = cmd.output_fd; + program_path = search_path(mc, (const char **)path, call.program); if (!program_path) return (127); pid = fork(); if (pid < 0) return (1); if (pid == 0) - fork_exec(program_path, cmd.calls[i], in, out, envp); - waitpid(pid, &status, 0); + { + dup2(in, 0); + dup2(out, 1); + execve(program_path, call.argv, envp); + } free_tab(path); return (0); } -// TODO works with only one call (no pipe). int execute_command(t_memclass mc, t_command command, char *const envp[]) { t_pipes *pipes; int i; + int nb_calls; + // get nb calls + nb_calls = 0; + while (command.calls[nb_calls].program != NULL) + nb_calls++; + + // create pipes + pipes = malloc(sizeof(t_pipes) * (nb_calls + 1)); i = 0; - while (command.calls[i].program != NULL) - i++; - pipes = malloc(sizeof(t_pipes) * (i + 1)); - i = 0; - while (command.calls[i].program != NULL) - { + pipes[i].pipe[0] = command.input_fd; + while (++i < nb_calls) if (pipe(pipes[i].pipe) < 0) return (exec_error()); - pipes[i].inout = 0; - i++; - } - pipes[i].inout = -1; + pipes[i].pipe[1] = command.output_fd; + i = -1; + + // call all programs + while (++i < nb_calls) + execute_call(mc, command.calls[i], pipes[i].pipe[0], pipes[i + 1].pipe[1], envp); + + // close all i = 0; - while (command.calls[i].program != NULL) + if (pipes[i].pipe[0] != 0) + close(pipes[i].pipe[0]); + while (++i < nb_calls) { - pipes[i].i = i; - pipes[i + 1].i = i + 1; - execute_call(mc, command, pipes[i], pipes[i + 1], envp); - i++; + close(pipes[i].pipe[0]); + close(pipes[i].pipe[1]); } + if (pipes[i].pipe[1] != 1) + close(pipes[i].pipe[1]); + + // wait the end of all programs + i = nb_calls; + while (wait(NULL) != -1) + ; + if (errno != ECHILD) + // TODO error + free(pipes); return (0); }