From: Lukáš Jiřiště Date: Tue, 27 Aug 2024 09:37:57 +0000 (+0200) Subject: Fix pipeline behaviour X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=f2736b869e672fdf7e9827214701c32dec49f582;p=42%2Fminishell.git Fix pipeline behaviour The return value is now set only after pipeline finishes (to the return value of last command). The shell also does not wait for each commmand in pipeline to end before starting the following command (preventing getting stuck on full pipe). Built-in functions still can get stuck when pipe gets full. --- diff --git a/inc/minishell_structs.h b/inc/minishell_structs.h index eb44ef1..3cfc088 100644 --- a/inc/minishell_structs.h +++ b/inc/minishell_structs.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/08/26 09:08:46 by ljiriste #+# #+# */ -/* Updated: 2024/08/26 09:31:09 by ljiriste ### ########.fr */ +/* Updated: 2024/08/27 11:35:10 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,7 +31,10 @@ typedef struct s_execution_env int stdin_fd; int stdout_fd; int ret_val; + int last_was_builtin; + int last_builtin_ret_val; t_vars *vars; + t_vec child_pids; } t_execution_env; typedef struct s_wildcard_info diff --git a/src/env.c b/src/env.c index ad5dca6..936d7ba 100644 --- a/src/env.c +++ b/src/env.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/21 21:24:52 by ljiriste #+# #+# */ -/* Updated: 2024/08/26 09:19:22 by ljiriste ### ########.fr */ +/* Updated: 2024/08/27 10:34:14 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,18 +16,25 @@ int init_env(t_execution_env *env, char **envp) { + int res; + env->stdin_fd = STDIN_FILENO; env->stdout_fd = STDOUT_FILENO; env->ret_val = 0; env->vars = malloc(sizeof(t_vars)); if (!env->vars) return (1); - return (init_vars(env->vars, envp)); + res = init_vars(env->vars, envp); + res = (ft_vec_init(&env->child_pids, sizeof(pid_t)) != success) || res; + if (res) + clean_env(env); + return (res); } void clean_env(t_execution_env *env) { clean_vars(env->vars); free(env->vars); + ft_vec_free(&env->child_pids, NULL); return ; } diff --git a/src/execution.c b/src/execution.c index 775cf77..94df96d 100644 --- a/src/execution.c +++ b/src/execution.c @@ -6,7 +6,7 @@ /* By: lnikolov ret_val = cd(count_fields(fields), fields, env); + env->last_builtin_ret_val = cd(count_fields(fields), fields, env); else if (!ft_strcmp(fields[0], "echo")) - env->ret_val = echo(count_fields(fields), fields); + env->last_builtin_ret_val = echo(count_fields(fields), fields); else if (!ft_strcmp(fields[0], "pwd")) - env->ret_val = pwd(); + env->last_builtin_ret_val = pwd(); else if (!ft_strcmp(fields[0], "env")) - env->ret_val = ft_env(count_fields(fields), env); + env->last_builtin_ret_val = ft_env(count_fields(fields), env); else if (!ft_strcmp(fields[0], "export")) - env->ret_val = export(count_fields(fields), fields, env); + env->last_builtin_ret_val = export(count_fields(fields), fields, env); else if (!ft_strcmp(fields[0], "unset")) - env->ret_val = unset(count_fields(fields), fields, env); + env->last_builtin_ret_val = unset(count_fields(fields), fields, env); else return (1); + env->last_was_builtin = 1; close_redirections(redirections); close_pipes(env); restore_std_filenos(fds); @@ -806,11 +807,11 @@ int ex_builtin(char **fields, __attribute__((unused)) t_vec *assignments, __attr int ex_fields(char **fields, t_vec *assignments, const t_vec *redirections, t_execution_env *env) { pid_t pid; - int status; char *path; if (is_builtin(fields[0])) return (ex_builtin(fields, assignments, redirections, env)); + env->last_was_builtin = 0; path = NULL; if (contains_path(fields[0]) && file_exists(fields[0])) path = ft_strdup(fields[0]); @@ -828,18 +829,14 @@ int ex_fields(char **fields, t_vec *assignments, const t_vec *redirections, t_ex execve(path, fields, assignments->vec); exit(-1); } - else if (pid > 0) + free(path); + if (pid > 0) { - free(path); - waitpid(pid, &status, 0); - if (WIFEXITED(status)) - env->ret_val = WEXITSTATUS(status); + if (ft_vec_append(&env->child_pids, &pid) != success) + return (1); } else - { - free(path); return (1); - } return (0); } @@ -962,18 +959,41 @@ int ex_command(t_parse_tree_node *command, t_execution_env *env) } } -int ex_pipeline(t_parse_tree_node *pipeline, t_execution_env *env) +void wait_for_return(t_execution_env *env) +{ + pid_t last_pid; + int status; + + if (env->last_was_builtin) + env->ret_val = env->last_builtin_ret_val; + else + { + if (env->child_pids.size == 0) + return ; + last_pid = *(pid_t *)ft_vec_access(&env->child_pids, env->child_pids.size - 1); + waitpid(last_pid, &status, 0); + if (WIFEXITED(status)) + env->ret_val = WEXITSTATUS(status); + } + ft_vec_free(&env->child_pids, NULL); + return ; +} + +int ex_pipeline(t_parse_tree_node *pipeline, t_execution_env *env, int depth) { int pipe_fds[2]; if (pipeline->children.size == 1) - return (ex_command(ft_vec_access(&pipeline->children, 0), env)); + { + if (ex_command(ft_vec_access(&pipeline->children, 0), env)) + return (1); + } else { if (pipe(pipe_fds)) return (1); ft_swap_int(&pipe_fds[1], &env->stdout_fd); - ex_pipeline(ft_vec_access(&pipeline->children, 0), env); + ex_pipeline(ft_vec_access(&pipeline->children, 0), env, depth + 1); ft_swap_int(&pipe_fds[1], &env->stdout_fd); close(pipe_fds[1]); ft_swap_int(&pipe_fds[0], &env->stdin_fd); @@ -981,24 +1001,26 @@ int ex_pipeline(t_parse_tree_node *pipeline, t_execution_env *env) ft_swap_int(&pipe_fds[0], &env->stdin_fd); close(pipe_fds[0]); } + if (depth == 0) + wait_for_return(env); return (0); } int ex_program(t_parse_tree_node *program, t_execution_env *env) { if (program->children.size == 1) - return (ex_pipeline(ft_vec_access(&program->children, 0), env)); + return (ex_pipeline(ft_vec_access(&program->children, 0), env, 0)); if (ex_program(ft_vec_access(&program->children, 0), env)) return (1); if (is_token_type(ft_vec_caccess(&program->children, 1), "AND_IF")) { if (env->ret_val == 0) - return (ex_pipeline(ft_vec_access(&program->children, 2), env)); + return (ex_pipeline(ft_vec_access(&program->children, 2), env, 0)); } else { if (env->ret_val != 0) - return (ex_pipeline(ft_vec_access(&program->children, 2), env)); + return (ex_pipeline(ft_vec_access(&program->children, 2), env, 0)); } return (0); } diff --git a/src/main.c b/src/main.c index 75762e7..708d319 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/26 13:11:47 by ljiriste #+# #+# */ -/* Updated: 2024/08/26 09:41:50 by ljiriste ### ########.fr */ +/* Updated: 2024/08/27 10:20:29 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -81,10 +81,7 @@ int main(int argc, __attribute__((unused)) char **argv, char **envp) return (1); } if (init_env(&env, envp)) - { - clean_env(&env); return (2); - } while (1) { line = rl_get_line();