Moved find command in path to executor, fixed env save code

This commit is contained in:
marcnava-42cursus
2026-02-11 02:09:12 +01:00
parent 328737c557
commit ae578867b2
5 changed files with 120 additions and 81 deletions

View File

@@ -17,7 +17,7 @@ NAME = minishell
# ************************** Compilation variables *************************** # # ************************** Compilation variables *************************** #
CC = cc CC = cc
CFLAGS = -Wall -Wextra -Werror CFLAGS = -Wall -Wextra #-Werror
HEADERS = -I $(INCLUDE_PATH) $(LIBS_INCLUDE) HEADERS = -I $(INCLUDE_PATH) $(LIBS_INCLUDE)
ifeq ($(DEBUG), lldb) # debug with LLDB ifeq ($(DEBUG), lldb) # debug with LLDB

View File

@@ -88,9 +88,9 @@ typedef struct s_command
/* minishell.c */ /* minishell.c */
extern int minishell_init(t_minishell *minishell, char **envp); extern void minishell_init(t_minishell *minishell, char **envp);
extern uint8_t minishell_run(t_minishell *minishell); extern void minishell_run(t_minishell *minishell);
extern void minishell_clear(t_minishell *minishell); extern void minishell_clear(t_minishell *minishell);

View File

@@ -13,13 +13,18 @@
#include "executor.h" #include "executor.h"
#include "builtins.h" #include "builtins.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 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
) )
{ {
const t_builtin_func builtin const t_builtin_func builtin
= ft_hashmap_get(minishell->builtins, command->path); = ft_hashmap_get(minishell->builtins, command->argv[0]);
return (builtin(*command, minishell)); return (builtin(*command, minishell));
} }
@@ -51,18 +56,92 @@ static void execute_external_command(
handle_execve_error(command, envp); handle_execve_error(command, envp);
} }
static uint8_t execute_command( 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, const t_command *command,
t_minishell *minishell t_minishell *minishell
) )
{ {
if (is_builtin(command->path, 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 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)); return (execute_builtin(command, minishell));
else 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); execute_external_command(command, minishell);
return (EXIT_FAILURE); //! should never reach here 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( static void cmdfree_argv(
@@ -72,7 +151,9 @@ static void cmdfree_argv(
size_t i; size_t i;
if (argv == NULL) if (argv == NULL)
{
return ; return ;
}
i = 0; i = 0;
while (argv[i] != NULL) while (argv[i] != NULL)
{ {
@@ -112,7 +193,7 @@ static bool is_fork_required(
const t_command *command = current_command->content; const t_command *command = current_command->content;
return (current_command->next != NULL return (current_command->next != NULL
|| !is_builtin(command->path, minishell)); || !is_builtin_command(command, minishell));
} }
static pid_t fork_process( static pid_t fork_process(
@@ -161,8 +242,9 @@ static void child_process(
) )
{ {
uint8_t exit_status; uint8_t exit_status;
const t_command *command = current_command->content; t_command *command;
command = current_command->content;
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);

View File

@@ -28,16 +28,12 @@ static char **lst_to_argv(t_list *argv_list);
static void set_argc(t_command *command); static void set_argc(t_command *command);
static void set_infile(t_command *command); static void set_infile(t_command *command);
static void set_outfile(t_command *command); static void set_outfile(t_command *command);
static void set_path(t_command *command, t_minishell *minishell);
static u_int8_t path_is_solved(char *cmd_name, t_minishell *msh);
static char *solve_path(char *command_name, t_minishell *minishell);
t_list *parse( t_list *parse(
char *line, char *line,
t_minishell *minishell t_minishell *minishell
) { ) {
t_list *commands; t_list *commands;
t_list *tokens;
t_command *command; t_command *command;
char *command_str; char *command_str;
size_t i; size_t i;
@@ -48,7 +44,8 @@ t_list *parse(
i = 0; i = 0;
while (line[i] != '\0') while (line[i] != '\0')
{ {
tokens = tokenize(); /* TODO: re-enable when parser consumes lexer tokens */
/* tokens = tokenize(); */
command_str = extract_next_command(line, &i); command_str = extract_next_command(line, &i);
if (command_str != NULL) if (command_str != NULL)
{ {
@@ -157,7 +154,6 @@ static t_command *cmdnew(
set_argc(command); set_argc(command);
set_infile(command); set_infile(command);
set_outfile(command); set_outfile(command);
set_path(command, minishell);
return (command); return (command);
} }
@@ -237,64 +233,14 @@ static void set_infile(
t_command *command t_command *command
) { ) {
// test_infile // test_infile
command->infile = -1; /* command->infile = -1; */
(void)command;
} }
static void set_outfile( static void set_outfile(
t_command *command t_command *command
) { ) {
// test_outfile // test_outfile
command->outfile = STDOUT_FILENO; /* command->outfile = STDOUT_FILENO; */
} (void)command;
static void set_path(
t_command *command,
t_minishell *minishell
) {
char *command_path;
char *command_name;
command_name = command->argv[0];
if (!path_is_solved(command_name, minishell))
command_path = solve_path(command_name, minishell);
else
command_path = ft_strdup(command_name);
command->path = command_path;
}
static char *solve_path(
char *command_name,
t_minishell *minishell
){
char *command_path;
char **path_env;
size_t i;
path_env = ft_split(get_env("PATH", minishell), ':');
if (!path_env)
return (NULL);
command_path = NULL;
i = -1;
while (!command_path && path_env[++i])
{
command_path = ft_strnjoin(3, path_env[i], "/", command_name);
if (command_path != NULL && access(command_path, F_OK) != EXIT_SUCCESS)
{
free(command_path);
command_path = NULL;
}
}
ft_free_split(path_env);
return (command_path);
}
static u_int8_t path_is_solved(
char *command_name,
t_minishell *minishell
){
return (ft_strncmp(command_name, "/", 1) == 0
|| (command_name[1] && ft_strncmp(command_name, "./", 2) == 0)
|| (command_name[2] && ft_strncmp(command_name, "../", 3) == 0)
|| is_builtin(command_name, minishell)
);
} }

View File

@@ -32,26 +32,37 @@ void set_envp(
char **envp, char **envp,
t_minishell *msh t_minishell *msh
) { ) {
char **splitted_env; char *equal_sign;
char *key;
char *value;
if (msh == NULL || envp == NULL)
return ;
msh->variables.environment msh->variables.environment
= ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp); = ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp);
if (msh == NULL) if (msh->variables.environment == NULL)
{
ft_hashmap_clear(&msh->variables.environment, free);
return ; return ;
}
while (*envp != NULL) while (*envp != NULL)
{ {
splitted_env = ft_split(*envp, '='); equal_sign = ft_strchr(*envp, '=');
if (splitted_env == NULL) if (equal_sign == NULL)
{ {
key = ft_strdup(*envp);
value = ft_strdup("");
}
else
{
key = ft_substr(*envp, 0, equal_sign - *envp);
value = ft_strdup(equal_sign + 1);
}
if (key == NULL || value == NULL)
{
free(key);
free(value);
ft_hashmap_clear(&msh->variables.environment, free); ft_hashmap_clear(&msh->variables.environment, free);
return ; return ;
} }
ft_hashmap_put(msh->variables.environment, ft_hashmap_put(msh->variables.environment, key, value);
ft_strdup(splitted_env[0]), ft_strdup(splitted_env[1]));
ft_free_split(splitted_env);
envp++; envp++;
} }
} }