From e02613253a199ffc0247030e1fb14c5013e0fe8b Mon Sep 17 00:00:00 2001 From: marcnava-42cursus Date: Wed, 11 Feb 2026 02:17:40 +0100 Subject: [PATCH] Fixed command exit status and exec bugs, read relative and absolute paths and correctly resolved --- src/executor/executor.c | 89 +++++++++++++++++++++++++++-------------- src/minishell.c | 2 +- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/executor/executor.c b/src/executor/executor.c index a80472a..5e16667 100644 --- a/src/executor/executor.c +++ b/src/executor/executor.c @@ -12,12 +12,14 @@ #include "executor.h" #include "builtins.h" +#include static bool is_path_explicit(const char *command_name); static char *resolve_path_from_env(const char *command_name, t_minishell *minishell); static char *resolve_command_path(const t_command *command, t_minishell *minishell); +static uint8_t resolve_execve_status(void); static inline uint8_t execute_builtin( const t_command *command, t_minishell *minishell @@ -34,9 +36,11 @@ static void handle_execve_error( char **envp ) { + const uint8_t exit_status = resolve_execve_status(); + free_envp(envp); perror(command->path); - exit(EXIT_FAILURE); + exit(exit_status); } static void execute_external_command( @@ -112,6 +116,15 @@ static char *resolve_command_path( return (command_path); } +static uint8_t resolve_execve_status(void) +{ + if (errno == ENOENT) + return (127); + if (errno == EACCES || errno == ENOEXEC || errno == EISDIR) + return (126); + return (EXIT_FAILURE); +} + static uint8_t execute_command( t_command *command, t_minishell *minishell @@ -188,29 +201,16 @@ static int create_pipe_if_needed( static bool is_fork_required( t_list *current_command, + const t_pipeline *pipeline, t_minishell *minishell ) { const t_command *command = current_command->content; - return (current_command->next != NULL + return (pipeline->prev_read_fd != -1 + || current_command->next != NULL || !is_builtin_command(command, minishell)); } -static pid_t fork_process( - t_list *current_command, - t_minishell *minishell -) -{ - pid_t pid; - - pid = 0; - if (is_fork_required(current_command, minishell)) - pid = fork(); - if (pid == FORK_ERROR) - perror("fork"); - return (pid); -} - static void setup_child_input( t_pipeline *pipeline ) @@ -248,8 +248,7 @@ static void child_process( setup_child_input(pipeline); setup_child_output(current_command, pipeline); exit_status = execute_command(command, minishell); - if (is_fork_required(current_command, minishell)) - exit(exit_status); + exit(exit_status); } static void parent_cleanup( @@ -268,16 +267,24 @@ static void parent_cleanup( pipeline->prev_read_fd = -1; } -static uint8_t wait_for_children(void) +static uint8_t wait_for_children( + pid_t last_child_pid +) { uint8_t exit_status; int status; + pid_t pid; exit_status = EXIT_SUCCESS; - while (wait(&status) > 0) + while (last_child_pid > 0 && (pid = wait(&status)) > 0) { - if (WIFEXITED(status)) - exit_status = WEXITSTATUS(status); + if (pid == last_child_pid) + { + if (WIFEXITED(status)) + exit_status = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + exit_status = 128 + WTERMSIG(status); + } } return (exit_status); } @@ -291,22 +298,46 @@ uint8_t execute( t_pipeline pipeline; t_list *current_command; pid_t pid; + pid_t last_child_pid; + t_command *command; + bool should_fork; pipeline.prev_read_fd = -1; + exit_status = EXIT_SUCCESS; + last_child_pid = -1; current_command = command_list; while (current_command) { if (create_pipe_if_needed(current_command, &pipeline) == PIPE_ERROR) + { + exit_status = EXIT_FAILURE; break ; - pid = fork_process(current_command, minishell); - if (pid == FORK_ERROR) - break ; - if (pid == 0) - child_process(current_command, &pipeline, minishell); + } + should_fork = is_fork_required(current_command, &pipeline, minishell); + if (should_fork) + { + pid = fork(); + if (pid == FORK_ERROR) + { + perror("fork"); + exit_status = EXIT_FAILURE; + break ; + } + if (pid == 0) + child_process(current_command, &pipeline, minishell); + last_child_pid = pid; + } + else + { + command = current_command->content; + exit_status = execute_command(command, minishell); + } parent_cleanup(current_command, &pipeline); current_command = current_command->next; } - exit_status = wait_for_children(); + if (last_child_pid > 0) + exit_status = wait_for_children(last_child_pid); + minishell->exit_status = exit_status; ft_lstclear(&command_list, (void (*)(void *))cmdfree); return (exit_status); } diff --git a/src/minishell.c b/src/minishell.c index 75560c9..387d24a 100644 --- a/src/minishell.c +++ b/src/minishell.c @@ -46,7 +46,7 @@ void minishell_run( { add_history(line); commands = parse(line, minishell); - execute(commands, minishell); + minishell->exit_status = execute(commands, minishell); } free(line); }