Executor working, need to validate with the parser fixed, all norme fixed
This commit is contained in:
86
src/executor/command_exec.c
Normal file
86
src/executor/command_exec.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* command_exec.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
#include "builtins.h"
|
||||
#include <errno.h>
|
||||
|
||||
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_builtin(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
const t_builtin_func builtin
|
||||
= ft_hashmap_get(minishell->builtins, command->argv[0]);
|
||||
|
||||
return (builtin(*command, minishell));
|
||||
}
|
||||
|
||||
static void handle_execve_error(
|
||||
const t_command *command,
|
||||
char **envp
|
||||
)
|
||||
{
|
||||
uint8_t exit_status;
|
||||
|
||||
exit_status = resolve_execve_status();
|
||||
free_envp(envp);
|
||||
perror(command->path);
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
static void execute_external_command(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char **envp;
|
||||
|
||||
envp = get_envp(minishell);
|
||||
if (envp == NULL)
|
||||
{
|
||||
perror("get_envp");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
execve(command->path, command->argv, envp);
|
||||
handle_execve_error(command, envp);
|
||||
}
|
||||
|
||||
uint8_t executor_execute_command(
|
||||
t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (EXIT_SUCCESS);
|
||||
if (executor_is_builtin_command(command, minishell))
|
||||
return (execute_builtin(command, minishell));
|
||||
if (command->path != NULL)
|
||||
free(command->path);
|
||||
command->path = executor_resolve_command_path(command, minishell);
|
||||
if (command->path == NULL)
|
||||
{
|
||||
ft_eprintf("minishell: %s: command not found\n", command->argv[0]);
|
||||
return (127);
|
||||
}
|
||||
execute_external_command(command, minishell);
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
@@ -6,287 +6,66 @@
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/08 19:10:47 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/08 21:32:03 by sede-san ### ########.fr */
|
||||
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
#include "builtins.h"
|
||||
#include <errno.h>
|
||||
|
||||
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,
|
||||
static void init_exec_state(
|
||||
t_exec_state *state,
|
||||
t_list *command_list
|
||||
)
|
||||
{
|
||||
state->exit_status = EXIT_SUCCESS;
|
||||
state->pipeline.prev_read_fd = -1;
|
||||
state->current_command = command_list;
|
||||
state->last_child_pid = -1;
|
||||
}
|
||||
|
||||
static bool fork_current_command(
|
||||
t_exec_state *state,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
const t_builtin_func builtin
|
||||
= ft_hashmap_get(minishell->builtins, command->argv[0]);
|
||||
|
||||
return (builtin(*command, minishell));
|
||||
}
|
||||
|
||||
static void handle_execve_error(
|
||||
const t_command *command,
|
||||
char **envp
|
||||
)
|
||||
{
|
||||
const uint8_t exit_status = resolve_execve_status();
|
||||
|
||||
free_envp(envp);
|
||||
perror(command->path);
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
static void execute_external_command(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char **envp;
|
||||
|
||||
envp = get_envp(minishell);
|
||||
if (envp == NULL)
|
||||
{
|
||||
perror("get_envp");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
execve(command->path, command->argv, envp);
|
||||
handle_execve_error(command, envp);
|
||||
}
|
||||
|
||||
static bool is_path_explicit(
|
||||
const char *command_name
|
||||
)
|
||||
{
|
||||
return (command_name != NULL && ft_strchr(command_name, '/') != NULL);
|
||||
}
|
||||
|
||||
static char *resolve_path_from_env(
|
||||
const char *command_name,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char *command_path;
|
||||
char **path_env;
|
||||
char *path_value;
|
||||
size_t i;
|
||||
|
||||
path_value = get_env("PATH", minishell);
|
||||
if (path_value == NULL)
|
||||
return (NULL);
|
||||
path_env = ft_split(path_value, ':');
|
||||
if (path_env == NULL)
|
||||
return (NULL);
|
||||
command_path = NULL;
|
||||
i = -1;
|
||||
while (!command_path && path_env[++i] != NULL)
|
||||
{
|
||||
command_path = ft_strnjoin(3, path_env[i], "/", command_name);
|
||||
if (command_path != NULL && access(command_path, X_OK) != EXIT_SUCCESS)
|
||||
{
|
||||
free(command_path);
|
||||
command_path = NULL;
|
||||
}
|
||||
}
|
||||
ft_free_split(path_env);
|
||||
return (command_path);
|
||||
}
|
||||
|
||||
static char *resolve_command_path(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
const char *command_name;
|
||||
char *command_path;
|
||||
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (NULL);
|
||||
command_name = command->argv[0];
|
||||
if (is_path_explicit(command_name)
|
||||
&& access(command_name, X_OK) == EXIT_SUCCESS)
|
||||
return (ft_strdup(command_name));
|
||||
command_path = resolve_path_from_env(command_name, minishell);
|
||||
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
|
||||
)
|
||||
{
|
||||
char *resolved_path;
|
||||
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (EXIT_SUCCESS);
|
||||
if (is_builtin(command->argv[0], minishell))
|
||||
return (execute_builtin(command, minishell));
|
||||
resolved_path = resolve_command_path(command, minishell);
|
||||
if (resolved_path == NULL)
|
||||
{
|
||||
ft_eprintf("minishell: %s: command not found\n", command->argv[0]);
|
||||
return (127);
|
||||
}
|
||||
command->path = resolved_path;
|
||||
execute_external_command(command, minishell);
|
||||
return (EXIT_FAILURE); //! should never reach here
|
||||
}
|
||||
|
||||
static bool is_builtin_command(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (false);
|
||||
return (is_builtin(command->argv[0], minishell));
|
||||
}
|
||||
|
||||
static void cmdfree_argv(
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (argv == NULL)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
i = 0;
|
||||
while (argv[i] != NULL)
|
||||
{
|
||||
free(argv[i]);
|
||||
i++;
|
||||
}
|
||||
free(argv);
|
||||
}
|
||||
|
||||
static void cmdfree(
|
||||
t_command *command
|
||||
)
|
||||
{
|
||||
if (command == NULL)
|
||||
return ;
|
||||
cmdfree_argv(command->argv);
|
||||
free(command->path);
|
||||
free(command);
|
||||
}
|
||||
|
||||
static int create_pipe_if_needed(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (!current_command->next)
|
||||
return (0);
|
||||
if (pipe(pipeline->pipefd) == PIPE_ERROR)
|
||||
return (perror("pipe"), PIPE_ERROR);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool is_fork_required(
|
||||
t_list *current_command,
|
||||
const t_pipeline *pipeline,
|
||||
t_minishell *minishell
|
||||
) {
|
||||
const t_command *command = current_command->content;
|
||||
|
||||
return (pipeline->prev_read_fd != -1
|
||||
|| current_command->next != NULL
|
||||
|| !is_builtin_command(command, minishell));
|
||||
}
|
||||
|
||||
static void setup_child_input(
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (pipeline->prev_read_fd != -1)
|
||||
{
|
||||
dup2(pipeline->prev_read_fd, STDIN_FILENO);
|
||||
close(pipeline->prev_read_fd);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_child_output(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (current_command->next)
|
||||
{
|
||||
dup2(pipeline->pipefd[WRITE_PIPE], STDOUT_FILENO);
|
||||
close(pipeline->pipefd[READ_PIPE]);
|
||||
close(pipeline->pipefd[WRITE_PIPE]);
|
||||
}
|
||||
}
|
||||
|
||||
static void child_process(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
uint8_t exit_status;
|
||||
t_command *command;
|
||||
|
||||
command = current_command->content;
|
||||
setup_child_input(pipeline);
|
||||
setup_child_output(current_command, pipeline);
|
||||
exit_status = execute_command(command, minishell);
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
static void parent_cleanup(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (pipeline->prev_read_fd != -1)
|
||||
close(pipeline->prev_read_fd);
|
||||
if (current_command->next)
|
||||
{
|
||||
close(pipeline->pipefd[WRITE_PIPE]);
|
||||
pipeline->prev_read_fd = pipeline->pipefd[READ_PIPE];
|
||||
}
|
||||
else
|
||||
pipeline->prev_read_fd = -1;
|
||||
}
|
||||
|
||||
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 (last_child_pid > 0 && (pid = wait(&status)) > 0)
|
||||
pid = fork();
|
||||
if (pid == FORK_ERROR)
|
||||
return (perror("fork"), state->exit_status = EXIT_FAILURE, false);
|
||||
if (pid == 0)
|
||||
executor_child_process(state->current_command, &state->pipeline,
|
||||
minishell);
|
||||
state->last_child_pid = pid;
|
||||
return (true);
|
||||
}
|
||||
|
||||
static bool run_current_command(
|
||||
t_exec_state *state,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
bool should_fork;
|
||||
t_command *command;
|
||||
|
||||
if (executor_create_pipe_if_needed(state->current_command,
|
||||
&state->pipeline) == PIPE_ERROR)
|
||||
return (state->exit_status = EXIT_FAILURE, false);
|
||||
should_fork = executor_is_fork_required(state->current_command,
|
||||
&state->pipeline, minishell);
|
||||
if (should_fork)
|
||||
{
|
||||
if (pid == last_child_pid)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
exit_status = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status))
|
||||
exit_status = 128 + WTERMSIG(status);
|
||||
}
|
||||
if (!fork_current_command(state, minishell))
|
||||
return (false);
|
||||
}
|
||||
return (exit_status);
|
||||
else
|
||||
{
|
||||
command = state->current_command->content;
|
||||
state->exit_status = executor_execute_command(command, minishell);
|
||||
}
|
||||
executor_parent_cleanup(state->current_command, &state->pipeline);
|
||||
state->current_command = state->current_command->next;
|
||||
return (true);
|
||||
}
|
||||
|
||||
uint8_t execute(
|
||||
@@ -294,50 +73,17 @@ uint8_t execute(
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
uint8_t exit_status;
|
||||
t_pipeline pipeline;
|
||||
t_list *current_command;
|
||||
pid_t pid;
|
||||
pid_t last_child_pid;
|
||||
t_command *command;
|
||||
bool should_fork;
|
||||
t_exec_state state;
|
||||
|
||||
pipeline.prev_read_fd = -1;
|
||||
exit_status = EXIT_SUCCESS;
|
||||
last_child_pid = -1;
|
||||
current_command = command_list;
|
||||
while (current_command)
|
||||
init_exec_state(&state, command_list);
|
||||
while (state.current_command)
|
||||
{
|
||||
if (create_pipe_if_needed(current_command, &pipeline) == PIPE_ERROR)
|
||||
{
|
||||
exit_status = EXIT_FAILURE;
|
||||
if (!run_current_command(&state, minishell))
|
||||
break ;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if (state.last_child_pid > 0)
|
||||
state.exit_status = executor_wait_for_children(state.last_child_pid);
|
||||
minishell->exit_status = state.exit_status;
|
||||
ft_lstclear(&command_list, (void (*)(void *))executor_cmdfree);
|
||||
return (state.exit_status);
|
||||
}
|
||||
|
||||
77
src/executor/path_resolver.c
Normal file
77
src/executor/path_resolver.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* path_resolver.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
|
||||
static bool is_path_explicit(
|
||||
const char *command_name
|
||||
)
|
||||
{
|
||||
return (command_name != NULL && ft_strchr(command_name, '/') != NULL);
|
||||
}
|
||||
|
||||
static char *resolve_path_from_env(
|
||||
const char *command_name,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char *command_path;
|
||||
char **path_env;
|
||||
char *path_value;
|
||||
size_t i;
|
||||
|
||||
path_value = get_env("PATH", minishell);
|
||||
if (path_value == NULL)
|
||||
return (NULL);
|
||||
path_env = ft_split(path_value, ':');
|
||||
if (path_env == NULL)
|
||||
return (NULL);
|
||||
command_path = NULL;
|
||||
i = -1;
|
||||
while (!command_path && path_env[++i] != NULL)
|
||||
{
|
||||
command_path = ft_strnjoin(3, path_env[i], "/", command_name);
|
||||
if (command_path != NULL && access(command_path, X_OK) != EXIT_SUCCESS)
|
||||
{
|
||||
free(command_path);
|
||||
command_path = NULL;
|
||||
}
|
||||
}
|
||||
ft_free_split(path_env);
|
||||
return (command_path);
|
||||
}
|
||||
|
||||
static char *resolve_explicit_path(
|
||||
const char *command_name
|
||||
)
|
||||
{
|
||||
if (access(command_name, F_OK) != EXIT_SUCCESS)
|
||||
return (NULL);
|
||||
if (access(command_name, X_OK) != EXIT_SUCCESS)
|
||||
return (NULL);
|
||||
return (ft_strdup(command_name));
|
||||
}
|
||||
|
||||
char *executor_resolve_command_path(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
const char *command_name;
|
||||
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (NULL);
|
||||
command_name = command->argv[0];
|
||||
if (is_path_explicit(command_name))
|
||||
return (resolve_explicit_path(command_name));
|
||||
return (resolve_path_from_env(command_name, minishell));
|
||||
}
|
||||
73
src/executor/pipeline_helpers.c
Normal file
73
src/executor/pipeline_helpers.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* pipeline_helpers.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
#include "builtins.h"
|
||||
|
||||
int executor_create_pipe_if_needed(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (!current_command->next)
|
||||
return (0);
|
||||
if (pipe(pipeline->pipefd) == PIPE_ERROR)
|
||||
return (perror("pipe"), PIPE_ERROR);
|
||||
return (0);
|
||||
}
|
||||
|
||||
bool executor_is_builtin_command(
|
||||
const t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
if (command == NULL || command->argv == NULL || command->argv[0] == NULL)
|
||||
return (false);
|
||||
return (is_builtin(command->argv[0], minishell));
|
||||
}
|
||||
|
||||
bool executor_is_fork_required(
|
||||
t_list *current_command,
|
||||
const t_pipeline *pipeline,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
const t_command *command;
|
||||
|
||||
command = current_command->content;
|
||||
return (pipeline->prev_read_fd != -1 || current_command->next != NULL
|
||||
|| !executor_is_builtin_command(command, minishell));
|
||||
}
|
||||
|
||||
void executor_setup_child_input(
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (pipeline->prev_read_fd != -1)
|
||||
{
|
||||
dup2(pipeline->prev_read_fd, STDIN_FILENO);
|
||||
close(pipeline->prev_read_fd);
|
||||
}
|
||||
}
|
||||
|
||||
void executor_setup_child_output(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (current_command->next)
|
||||
{
|
||||
dup2(pipeline->pipefd[WRITE_PIPE], STDOUT_FILENO);
|
||||
close(pipeline->pipefd[READ_PIPE]);
|
||||
close(pipeline->pipefd[WRITE_PIPE]);
|
||||
}
|
||||
}
|
||||
97
src/executor/process_helpers.c
Normal file
97
src/executor/process_helpers.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* process_helpers.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
|
||||
void executor_child_process(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
uint8_t exit_status;
|
||||
t_command *command;
|
||||
|
||||
command = current_command->content;
|
||||
executor_setup_child_input(pipeline);
|
||||
executor_setup_child_output(current_command, pipeline);
|
||||
exit_status = executor_execute_command(command, minishell);
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
void executor_parent_cleanup(
|
||||
t_list *current_command,
|
||||
t_pipeline *pipeline
|
||||
)
|
||||
{
|
||||
if (pipeline->prev_read_fd != -1)
|
||||
close(pipeline->prev_read_fd);
|
||||
if (current_command->next)
|
||||
{
|
||||
close(pipeline->pipefd[WRITE_PIPE]);
|
||||
pipeline->prev_read_fd = pipeline->pipefd[READ_PIPE];
|
||||
}
|
||||
else
|
||||
pipeline->prev_read_fd = -1;
|
||||
}
|
||||
|
||||
uint8_t executor_wait_for_children(
|
||||
pid_t last_child_pid
|
||||
)
|
||||
{
|
||||
uint8_t exit_status;
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
exit_status = EXIT_SUCCESS;
|
||||
pid = wait(&status);
|
||||
while (last_child_pid > 0 && pid > 0)
|
||||
{
|
||||
if (pid == last_child_pid)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
exit_status = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status))
|
||||
exit_status = 128 + WTERMSIG(status);
|
||||
}
|
||||
pid = wait(&status);
|
||||
}
|
||||
return (exit_status);
|
||||
}
|
||||
|
||||
static void cmdfree_argv(
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (argv == NULL)
|
||||
return ;
|
||||
i = 0;
|
||||
while (argv[i] != NULL)
|
||||
{
|
||||
free(argv[i]);
|
||||
i++;
|
||||
}
|
||||
free(argv);
|
||||
}
|
||||
|
||||
void executor_cmdfree(
|
||||
t_command *command
|
||||
)
|
||||
{
|
||||
if (command == NULL)
|
||||
return ;
|
||||
cmdfree_argv(command->argv);
|
||||
free(command->path);
|
||||
free(command);
|
||||
}
|
||||
Reference in New Issue
Block a user