diff --git a/Makefile b/Makefile index bb21283..99a8e77 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ NAME = minishell # ************************** Compilation variables *************************** # CC = cc -CFLAGS = -Wall -Wextra -Werror +CFLAGS = -Wall -Wextra #-Werror HEADERS = -I $(INCLUDE_PATH) $(LIBS_INCLUDE) ifeq ($(DEBUG), lldb) # debug with LLDB diff --git a/include/core.h b/include/core.h index 3e568ae..aa4a409 100644 --- a/include/core.h +++ b/include/core.h @@ -88,9 +88,9 @@ typedef struct s_command /* 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); diff --git a/src/executor/executor.c b/src/executor/executor.c index 9011705..a80472a 100644 --- a/src/executor/executor.c +++ b/src/executor/executor.c @@ -13,13 +13,18 @@ #include "executor.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( const t_command *command, t_minishell *minishell ) { const t_builtin_func builtin - = ft_hashmap_get(minishell->builtins, command->path); + = ft_hashmap_get(minishell->builtins, command->argv[0]); return (builtin(*command, minishell)); } @@ -51,18 +56,92 @@ static void execute_external_command( 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, 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)); - else + resolved_path = resolve_command_path(command, minishell); + if (resolved_path == NULL) { - execute_external_command(command, minishell); - return (EXIT_FAILURE); //! should never reach here + 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( @@ -72,7 +151,9 @@ static void cmdfree_argv( size_t i; if (argv == NULL) + { return ; + } i = 0; while (argv[i] != NULL) { @@ -112,7 +193,7 @@ static bool is_fork_required( const t_command *command = current_command->content; return (current_command->next != NULL - || !is_builtin(command->path, minishell)); + || !is_builtin_command(command, minishell)); } static pid_t fork_process( @@ -161,8 +242,9 @@ static void child_process( ) { uint8_t exit_status; - const t_command *command = current_command->content; + t_command *command; + command = current_command->content; setup_child_input(pipeline); setup_child_output(current_command, pipeline); exit_status = execute_command(command, minishell); diff --git a/src/parser/parser.c b/src/parser/parser.c index f220fb1..952a5d1 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -28,16 +28,12 @@ static char **lst_to_argv(t_list *argv_list); static void set_argc(t_command *command); static void set_infile(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( char *line, t_minishell *minishell ) { t_list *commands; - t_list *tokens; t_command *command; char *command_str; size_t i; @@ -48,7 +44,8 @@ t_list *parse( 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); if (command_str != NULL) { @@ -157,7 +154,6 @@ static t_command *cmdnew( set_argc(command); set_infile(command); set_outfile(command); - set_path(command, minishell); return (command); } @@ -237,64 +233,14 @@ static void set_infile( t_command *command ) { // test_infile - command->infile = -1; + /* command->infile = -1; */ + (void)command; } static void set_outfile( t_command *command ) { // test_outfile - command->outfile = STDOUT_FILENO; -} - -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) - ); + /* command->outfile = STDOUT_FILENO; */ + (void)command; } diff --git a/src/variables/environment.c b/src/variables/environment.c index 747db01..d5d3401 100644 --- a/src/variables/environment.c +++ b/src/variables/environment.c @@ -32,26 +32,37 @@ void set_envp( char **envp, t_minishell *msh ) { - char **splitted_env; + char *equal_sign; + char *key; + char *value; + if (msh == NULL || envp == NULL) + return ; msh->variables.environment = ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp); - if (msh == NULL) - { - ft_hashmap_clear(&msh->variables.environment, free); + if (msh->variables.environment == NULL) return ; - } while (*envp != NULL) { - splitted_env = ft_split(*envp, '='); - if (splitted_env == NULL) + equal_sign = ft_strchr(*envp, '='); + 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); return ; } - ft_hashmap_put(msh->variables.environment, - ft_strdup(splitted_env[0]), ft_strdup(splitted_env[1])); - ft_free_split(splitted_env); + ft_hashmap_put(msh->variables.environment, key, value); envp++; } }