Fixed command exit status and exec bugs, read relative and absolute paths and correctly resolved

This commit is contained in:
marcnava-42cursus
2026-02-11 02:17:40 +01:00
parent ae578867b2
commit e02613253a
2 changed files with 61 additions and 30 deletions

View File

@@ -12,12 +12,14 @@
#include "executor.h" #include "executor.h"
#include "builtins.h" #include "builtins.h"
#include <errno.h>
static bool is_path_explicit(const char *command_name); static bool is_path_explicit(const char *command_name);
static char *resolve_path_from_env(const char *command_name, static char *resolve_path_from_env(const char *command_name,
t_minishell *minishell); t_minishell *minishell);
static char *resolve_command_path(const t_command *command, static char *resolve_command_path(const t_command *command,
t_minishell *minishell); t_minishell *minishell);
static uint8_t resolve_execve_status(void);
static inline uint8_t execute_builtin( static inline uint8_t execute_builtin(
const t_command *command, const t_command *command,
t_minishell *minishell t_minishell *minishell
@@ -34,9 +36,11 @@ static void handle_execve_error(
char **envp char **envp
) )
{ {
const uint8_t exit_status = resolve_execve_status();
free_envp(envp); free_envp(envp);
perror(command->path); perror(command->path);
exit(EXIT_FAILURE); exit(exit_status);
} }
static void execute_external_command( static void execute_external_command(
@@ -112,6 +116,15 @@ static char *resolve_command_path(
return (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( static uint8_t execute_command(
t_command *command, t_command *command,
t_minishell *minishell t_minishell *minishell
@@ -188,29 +201,16 @@ static int create_pipe_if_needed(
static bool is_fork_required( static bool is_fork_required(
t_list *current_command, t_list *current_command,
const t_pipeline *pipeline,
t_minishell *minishell t_minishell *minishell
) { ) {
const t_command *command = current_command->content; 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)); || !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( static void setup_child_input(
t_pipeline *pipeline t_pipeline *pipeline
) )
@@ -248,7 +248,6 @@ static void child_process(
setup_child_input(pipeline); setup_child_input(pipeline);
setup_child_output(current_command, pipeline); setup_child_output(current_command, pipeline);
exit_status = execute_command(command, minishell); exit_status = execute_command(command, minishell);
if (is_fork_required(current_command, minishell))
exit(exit_status); exit(exit_status);
} }
@@ -268,16 +267,24 @@ static void parent_cleanup(
pipeline->prev_read_fd = -1; 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; uint8_t exit_status;
int status; int status;
pid_t pid;
exit_status = EXIT_SUCCESS; exit_status = EXIT_SUCCESS;
while (wait(&status) > 0) while (last_child_pid > 0 && (pid = wait(&status)) > 0)
{
if (pid == last_child_pid)
{ {
if (WIFEXITED(status)) if (WIFEXITED(status))
exit_status = WEXITSTATUS(status); exit_status = WEXITSTATUS(status);
else if (WIFSIGNALED(status))
exit_status = 128 + WTERMSIG(status);
}
} }
return (exit_status); return (exit_status);
} }
@@ -291,22 +298,46 @@ uint8_t execute(
t_pipeline pipeline; t_pipeline pipeline;
t_list *current_command; t_list *current_command;
pid_t pid; pid_t pid;
pid_t last_child_pid;
t_command *command;
bool should_fork;
pipeline.prev_read_fd = -1; pipeline.prev_read_fd = -1;
exit_status = EXIT_SUCCESS;
last_child_pid = -1;
current_command = command_list; current_command = command_list;
while (current_command) while (current_command)
{ {
if (create_pipe_if_needed(current_command, &pipeline) == PIPE_ERROR) if (create_pipe_if_needed(current_command, &pipeline) == PIPE_ERROR)
{
exit_status = EXIT_FAILURE;
break ; break ;
pid = fork_process(current_command, minishell); }
should_fork = is_fork_required(current_command, &pipeline, minishell);
if (should_fork)
{
pid = fork();
if (pid == FORK_ERROR) if (pid == FORK_ERROR)
{
perror("fork");
exit_status = EXIT_FAILURE;
break ; break ;
}
if (pid == 0) if (pid == 0)
child_process(current_command, &pipeline, minishell); 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); parent_cleanup(current_command, &pipeline);
current_command = current_command->next; 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); ft_lstclear(&command_list, (void (*)(void *))cmdfree);
return (exit_status); return (exit_status);
} }

View File

@@ -46,7 +46,7 @@ void minishell_run(
{ {
add_history(line); add_history(line);
commands = parse(line, minishell); commands = parse(line, minishell);
execute(commands, minishell); minishell->exit_status = execute(commands, minishell);
} }
free(line); free(line);
} }