save commit
This commit is contained in:
256
executor_old.c
Normal file
256
executor_old.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* executor.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/10/28 13:03:44 by sede-san #+# #+# */
|
||||
/* Updated: 2026/02/08 03:42:11 by sede-san ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "executor.h"
|
||||
#include "builtins.h"
|
||||
#include <errno.h>
|
||||
|
||||
static inline bool can_execute_command(t_command *command, t_minishell *minishell);
|
||||
static inline bool command_exists(t_command *command, t_minishell *minishell);
|
||||
static u_int8_t execute_command(t_command *command, t_minishell *minishell);
|
||||
static u_int8_t execute_command(t_command *command, t_minishell *minishell);
|
||||
// static inline bool is_piped(t_command *command);
|
||||
static void cmdfree(t_command *command);
|
||||
static void cmdfree_argv(char **argv);
|
||||
|
||||
# define WRITE_PIPE 1
|
||||
# define READ_PIPE 0
|
||||
# define CHILD_PID 0
|
||||
|
||||
u_int8_t execute(
|
||||
t_list *command_list,
|
||||
t_minishell *minishell
|
||||
) {
|
||||
t_list *current_command;
|
||||
int prev_read_fd;
|
||||
pid_t pid;
|
||||
u_int8_t exit_status;
|
||||
int child_exit_status;
|
||||
|
||||
prev_read_fd = -1;
|
||||
exit_status = EXIT_SUCCESS;
|
||||
current_command = command_list;
|
||||
while (current_command != NULL)
|
||||
{
|
||||
t_command *command = (t_command *)current_command->content;
|
||||
int pipefd[2];
|
||||
|
||||
/* Create pipe ONLY if there is a next command */
|
||||
if (current_command->next)
|
||||
{
|
||||
if (pipe(pipefd) == -1)
|
||||
{
|
||||
perror("pipe");
|
||||
exit_status = EXIT_FAILURE;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
// create fork
|
||||
pid = 0;
|
||||
if (current_command->next != NULL
|
||||
|| !is_builtin(command->path, minishell))
|
||||
pid = fork();
|
||||
// handle fork error
|
||||
if (pid == -1)
|
||||
{
|
||||
perror("fork");
|
||||
return (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// handle child process
|
||||
if (pid == CHILD_PID)
|
||||
{
|
||||
/* If we have input from previous pipe */
|
||||
if (prev_read_fd != -1)
|
||||
{
|
||||
dup2(prev_read_fd, STDIN_FILENO);
|
||||
close(prev_read_fd);
|
||||
}
|
||||
/* If we pipe output to next command */
|
||||
if (current_command->next)
|
||||
{
|
||||
dup2(pipefd[WRITE_PIPE], STDOUT_FILENO);
|
||||
close(pipefd[READ_PIPE]);
|
||||
close(pipefd[WRITE_PIPE]);
|
||||
}
|
||||
execute_command(command, minishell); // child process exits here
|
||||
}
|
||||
|
||||
// handle parent process
|
||||
waitpid(pid, &child_exit_status, 0); // wait for child to finish
|
||||
if (prev_read_fd != -1)
|
||||
close(prev_read_fd);
|
||||
|
||||
if (current_command->next)
|
||||
{
|
||||
close(pipefd[WRITE_PIPE]); /* parent does not write */
|
||||
prev_read_fd = pipefd[READ_PIPE]; /* pass read end forward */
|
||||
}
|
||||
else
|
||||
prev_read_fd = -1;
|
||||
|
||||
// continue executing
|
||||
current_command = current_command->next;
|
||||
}
|
||||
ft_lstclear(&command_list, (void (*)(void *))cmdfree);
|
||||
exit_status = child_exit_status;
|
||||
return (exit_status);
|
||||
}
|
||||
|
||||
static inline bool can_execute_command(
|
||||
t_command *command,
|
||||
t_minishell *minishell
|
||||
) {
|
||||
if (!is_builtin(command->path, minishell)
|
||||
&& access(command->path, X_OK) != EXIT_SUCCESS)
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
static inline bool command_exists(
|
||||
t_command *command,
|
||||
t_minishell *minishell
|
||||
) {
|
||||
if (!is_builtin(command->path, minishell)
|
||||
&& access(command->path, F_OK) != EXIT_SUCCESS)
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
static u_int8_t execute_command(
|
||||
t_command *command,
|
||||
t_minishell *minishell
|
||||
)
|
||||
{
|
||||
char **envp;
|
||||
t_builtin_func builtin;
|
||||
|
||||
if (is_builtin(command->path, minishell))
|
||||
{
|
||||
builtin = ft_hashmap_get(minishell->builtins, command->path);
|
||||
return (builtin(*command, minishell));
|
||||
}
|
||||
envp = get_envp(minishell);
|
||||
execve(command->path, command->argv, envp);
|
||||
// handle error if execve fails
|
||||
perror("execve");
|
||||
free_envp(envp);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// static inline bool is_piped(
|
||||
// t_command *command
|
||||
// ) {
|
||||
// return (command->piped_to != NULL || command->piped_from != NULL);
|
||||
// }
|
||||
|
||||
// static u_int8_t handle_child_process(
|
||||
// t_command *command,
|
||||
// t_minishell *minishell
|
||||
// ) {
|
||||
// if (!redirect_pipes(command))
|
||||
// exit(EXIT_FAILURE);
|
||||
// execute_command(command, minishell);
|
||||
// exit(EXIT_FAILURE);
|
||||
// }
|
||||
|
||||
// static int redirect_pipe(
|
||||
// int from,
|
||||
// int to
|
||||
// ) {
|
||||
// if (dup2(from, to) == -1)
|
||||
// return (-1);
|
||||
// close(from);
|
||||
// return (0);
|
||||
// }
|
||||
|
||||
// static int redirect_pipes(
|
||||
// t_command *command
|
||||
// ) {
|
||||
// if (command->piped_from &&
|
||||
// redirect_pipe(command->piped_from->outfile, STDIN_FILENO) == -1)
|
||||
// {
|
||||
// perror("dup2");
|
||||
// return (0);
|
||||
// }
|
||||
// if (command->piped_to &&
|
||||
// redirect_pipe(command->outfile, STDOUT_FILENO) == -1)
|
||||
// {
|
||||
// perror("dup2");
|
||||
// return (0);
|
||||
// }
|
||||
// return (1);
|
||||
// }
|
||||
|
||||
// static void show_error(
|
||||
// t_command *command,
|
||||
// t_minishell *minishell
|
||||
// ) {
|
||||
// if (!command_exists(command, minishell))
|
||||
// {
|
||||
// ft_eprintf("minishell: %s: command not found\n", command->argv[0]);
|
||||
// minishell->exit_status = 127;
|
||||
// }
|
||||
// else if (!can_execute_command(command, minishell))
|
||||
// {
|
||||
// ft_eprintf("minishell: %s: %s\n", command->path, strerror(errno));
|
||||
// minishell->exit_status = errno;
|
||||
// }
|
||||
// }
|
||||
|
||||
static void cmdfree(
|
||||
t_command *command
|
||||
) {
|
||||
if (command == NULL)
|
||||
return ;
|
||||
cmdfree_argv(command->argv);
|
||||
free(command->path);
|
||||
free(command);
|
||||
}
|
||||
|
||||
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 debug_print_command_info(
|
||||
// t_command *command
|
||||
// ) {
|
||||
// size_t i;
|
||||
|
||||
// if (command == NULL)
|
||||
// {
|
||||
// printf("Command is NULL\n");
|
||||
// return ;
|
||||
// }
|
||||
// printf("Command info:\n");
|
||||
// printf(" Path: %s\n", command->path);
|
||||
// printf(" Argc: %d\n", command->argc);
|
||||
// printf(" Argv:\n");
|
||||
// for (i = 0; i < (size_t)command->argc; i++)
|
||||
// printf(" arg[%zu]: %s\n", i, command->argv[i]);
|
||||
// printf(" Infile FD: %d\n", command->infile);
|
||||
// printf(" Outfile FD: %d\n", command->outfile);
|
||||
// printf("--------------------------\n");
|
||||
// }
|
||||
Reference in New Issue
Block a user