diff --git a/Makefile b/Makefile index f767677..48fecda 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,13 @@ # By: qmennen +#+ # # +#+ # # Created: 2024/10/15 11:48:46 by whaffman #+# #+# # -# Updated: 2025/03/03 11:52:43 by whaffman ######## odam.nl # +# Updated: 2025/03/04 18:26:26 by whaffman ######## odam.nl # # # # **************************************************************************** # NAME = minishell # FLAGS=-DNOCOLORS -DNOBANNER -DNOPROMPT +FLAGS=-DNOBANNER SRC_PATH = src INC_PATH = inc @@ -38,8 +39,6 @@ endif # Build configurations BUILD_CONFIGS = release debug asan tsan -FLAGS = -DNOCOLORS -DNOBANNER -DNOPROMPT - release_CFLAGS = -Wall -Werror -Werror -O2 debug_CFLAGS = -Wall -Werror -Werror -g3 -DDEBUG -DDBG='fprintf(stderr, RED "DEBUG: " RESET "%s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);' asan_CFLAGS = -Wall -Werror -Werror -fsanitize=address,leak,undefined -g3 diff --git a/README.md b/README.md index 4bae689..2959ad2 100644 --- a/README.md +++ b/README.md @@ -50,9 +50,13 @@ A lot of amazing shell stuff should it close the unused pipe-end? all redirects are opened and closed, but only last fd is used. multiple HEREDOCs can be nested, only last is used. -- [x] Expand \$ vars & support \$? +- [x] Expand \$ vars & support \$ ~? * [x] $var - * [0] $? + * [x] $? + * [ ] ~ +- [ ] export without arguments +- [ ] ft_free_arr_safe in environment mess +- [ ] builtins not first in pipeline? wtf is happening HAHAHAHAHAH its not using builtin, but core-utils - CB command to change banner - __Bonus:__ Command tree for &&, ||, * diff --git a/inc/environment.h b/inc/environment.h index 6d0e160..67e2920 100644 --- a/inc/environment.h +++ b/inc/environment.h @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/04 16:26:35 by whaffman #+# #+# */ -/* Updated: 2025/02/26 15:44:49 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:30:03 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -17,12 +17,13 @@ void environment_add(t_minishell *msh, char *name, char *value); -void environment_print(t_minishell *msh); +void environment_print(t_minishell *msh, int export); t_environment *environment_get(t_minishell *msh, char *name); void environment_free_list(t_minishell *msh); int environment_parse(t_minishell *msh, char **envp); char **environment_get_arr(t_minishell *msh); void environment_del(t_minishell *msh, char *name); void environment_free(t_minishell *msh, void *content); +void environment_update(t_minishell *msh, char *name, char *value); #endif // ENVIRONMENT_H diff --git a/inc/minishell.h b/inc/minishell.h index 37ee81a..e60db1e 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -20,6 +20,7 @@ # include "environment.h" # include "prompt.h" # include "tokenizer.h" +# include "token.h" # include "builtin.h" # include "executor.h" # include "parser.h" diff --git a/inc/parser.h b/inc/parser.h index e2f06af..cfcc5c5 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/02/11 14:03:03 by qmennen #+# #+# */ -/* Updated: 2025/02/28 14:08:11 by whaffman ######## odam.nl */ +/* Updated: 2025/03/05 12:50:03 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -15,12 +15,14 @@ # include "minishell.h" -t_command *parser_alloc_command(t_minishell *msh, char *cmd); +char *parser_sanitize_string(t_minishell *msh, char *str, char c); +t_command *parser_alloc_command(t_minishell *msh); t_list *parser_get_commands(t_minishell *msh); t_list *parser_get_input_redirects(t_list *list); void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn); char **parser_get_arguments(t_list *list, t_minishell *msh); int parser_validate_command(t_command *command); +int parser_count_arguments(t_list *list); #endif diff --git a/inc/token.h b/inc/token.h new file mode 100644 index 0000000..cbdbf41 --- /dev/null +++ b/inc/token.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 13:11:41 by qmennen #+# #+# */ +/* Updated: 2025/03/05 13:11:58 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TOKEN_H +# define TOKEN_H + +# include "minishell.h" + +t_token *token_from_list(t_list *list); + +#endif diff --git a/inc/typedef.h b/inc/typedef.h index 292ed84..33268c2 100644 --- a/inc/typedef.h +++ b/inc/typedef.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/02/05 12:36:08 by whaffman #+# #+# */ -/* Updated: 2025/02/26 17:26:27 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 18:11:00 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -58,9 +58,9 @@ typedef struct s_redirect typedef struct s_command { - char *command; + //char *command; char **args; - t_list *environment; + // t_list *environment; t_list *redirect_in; t_list *redirect_out; int fd_in; diff --git a/lib/libft b/lib/libft index e1a01cb..6c1aafa 160000 --- a/lib/libft +++ b/lib/libft @@ -1 +1 @@ -Subproject commit e1a01cbdfd8a18a0e1bd8dcc2c6fc3745b39cbce +Subproject commit 6c1aafa436b0ef0011e82abec2fff63e8d03767e diff --git a/sources.mk b/sources.mk index fd8fb6d..dab7129 100644 --- a/sources.mk +++ b/sources.mk @@ -1,27 +1,27 @@ VPATH = src:src/prompt:src/utils:src/lexer:src/token:src/environment:src/executor:src/parser:src/signal:src/debug:src/expander:src/builtin:src/redirect: SOURCES = history_write.c history_load.c prompt.c check_malloc.c \ -free_command_list.c free_freelist.c free_lexer.c free_safe.c \ -free_token.c free_token_list.c ft_lstclear_safe.c ft_lstnew_safe.c \ -ft_strdup_safe.c ft_strjoin_safe.c malloc_safe.c \ -free_minishell_line.c ft_substr_safe.c error_msg.c ft_split_safe.c \ -init_minishell.c print_banner.c ft_free_arr_safe.c free_minishell.c \ -lexer_read_char.c lexer_new.c lexer_parse_input.c \ -lexer_parse_quotes.c lexer_read_word.c lexer_token_next.c token_new.c \ +free_freelist.c free_lexer.c free_safe.c free_token.c \ +free_token_list.c ft_lstclear_safe.c ft_lstnew_safe.c \ +ft_strjoin_safe.c free_minishell_line.c ft_substr_safe.c \ +ft_split_safe.c init_minishell.c print_banner.c ft_free_arr_safe.c \ +error_msg.c free_command_list.c ft_strdup_safe.c malloc_safe.c \ +free_minishell.c lexer_read_char.c lexer_new.c lexer_parse_quotes.c \ +lexer_parse_input.c lexer_read_word.c lexer_token_next.c token_new.c \ token_char_convert.c token_parse.c token_type_convert.c \ environment_del.c environment_free.c environment_get.c \ -environment_get_arr.c environment_free_list.c environment_parse.c \ -environment_print.c environment_add.c executor_close_fds.c \ -executor_open_fds.c executor_count_fds.c executor_create_pipes.c \ -executor_create_redirects.c executor_execute_pipeline.c \ -executor_fork.c executor_absolute_path.c executor_child.c \ -parser_alloc_command.c parser_create_command.c parser_get_arguments.c \ -parser_get_commands.c parser_validate_command.c signal.c \ -signal_init.c.c print_commands.c print_freelist.c \ -expander_expand_dollar.c expander_is_character.c \ +environment_free_list.c environment_parse.c environment_add.c \ +environment_get_arr.c environment_print.c environment_update.c \ +executor_close_fds.c executor_open_fds.c executor_count_fds.c \ +executor_create_pipes.c executor_create_redirects.c executor_fork.c \ +executor_execute_pipeline.c executor_absolute_path.c executor_child.c \ +parser_create_command.c parser_validate_command.c \ +parser_alloc_command.c parser_get_commands.c parser_get_arguments.c \ +parser_sanitize_string.c signal.c signal_init.c.c print_freelist.c \ +print_commands.c expander_expand_dollar.c expander_is_character.c \ expander_parse_variables.c expander_get_variable.c \ -expander_allocate_memory.c expander_parse_string.c is_builtin.c \ -builtin_echo.c builtin_env.c builtin_router.c builtin_unset.c \ -simple_builtins.c builtin_cd.c builtin_exit.c builtin_export.c \ -builtin_pwd.c redirect_process_heredoc.c redirect_get_inputs.c \ +expander_allocate_memory.c expander_parse_string.c builtin_unset.c \ +builtin_pwd.c builtin_cd.c builtin_echo.c builtin_env.c \ +builtin_exit.c builtin_export.c builtin_router.c is_builtin.c \ +simple_builtins.c redirect_process_heredoc.c redirect_get_inputs.c \ redirect_get_outputs.c redirect_new.c redirect_new_error.c \ redirect_valid_type.c main.c \ diff --git a/src/builtin/builtin_cd.c b/src/builtin/builtin_cd.c index 81a9b89..7b18405 100644 --- a/src/builtin/builtin_cd.c +++ b/src/builtin/builtin_cd.c @@ -6,33 +6,51 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:33:07 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:43:09 by whaffman ######## odam.nl */ +/* Updated: 2025/03/03 21:42:47 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" +static int builtin_cd_change_directory(t_minishell *msh, char *path) +{ + char *oldpwd; + + oldpwd = getcwd(NULL, 0); + if (oldpwd == NULL) + return (error_msg("cd", "getcwd failed"), EXIT_FAILURE); + if (chdir(path) == -1) + return (error_msg("cd", path), free(oldpwd), EXIT_FAILURE); + environment_update(msh, "OLDPWD", oldpwd); + free(oldpwd); + path = getcwd(NULL, 0); + environment_update(msh, "PWD", path); + free(path); + return (EXIT_SUCCESS); +} + int builtin_cd(t_minishell *msh, t_command *cmd) { t_environment *env; char *path; + if (cmd->args[1] != NULL && cmd->args[2] != NULL) + return (error_msg("cd", "too many arguments"), EXIT_FAILURE); if (cmd->args[1] == NULL) { env = environment_get(msh, "HOME"); if (env == NULL || env->value == NULL) - { - error_msg(NULL, NULL); - return (EXIT_FAILURE); - } + return (error_msg("cd", "HOME not set"), EXIT_FAILURE); + path = env->value; + } + else if (ft_strcmp(cmd->args[1], "-") == 0) + { + env = environment_get(msh, "OLDPWD"); + if (env == NULL || env->value == NULL) + return (error_msg("cd", "OLDPWD not set"), EXIT_FAILURE); path = env->value; } else path = cmd->args[1]; - if (chdir(path) == -1) - { - error_msg("cd", path); - return (EXIT_FAILURE); - } - return (EXIT_SUCCESS); + return (builtin_cd_change_directory(msh, path)); } diff --git a/src/builtin/builtin_echo.c b/src/builtin/builtin_echo.c index 8a2da83..2d9b415 100644 --- a/src/builtin/builtin_echo.c +++ b/src/builtin/builtin_echo.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:33:05 by whaffman #+# #+# */ -/* Updated: 2025/02/26 15:46:29 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:16:02 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -34,5 +34,5 @@ int builtin_echo(t_minishell *msh, t_command *cmd) } if (!n_flag) printf("\n"); - return (SUCCESS); + return (EXIT_SUCCESS); } diff --git a/src/builtin/builtin_env.c b/src/builtin/builtin_env.c index 2b92fa8..882f74f 100644 --- a/src/builtin/builtin_env.c +++ b/src/builtin/builtin_env.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:33:02 by whaffman #+# #+# */ -/* Updated: 2025/02/26 15:46:55 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:33:16 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -15,6 +15,6 @@ int builtin_env(t_minishell *msh, t_command *cmd) { (void)cmd; - environment_print(msh); + environment_print(msh, FALSE); return (SUCCESS); } diff --git a/src/builtin/builtin_exit.c b/src/builtin/builtin_exit.c index e1fb75f..9f32b9f 100644 --- a/src/builtin/builtin_exit.c +++ b/src/builtin/builtin_exit.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/02/20 11:32:59 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:44:01 by whaffman ######## odam.nl */ +/* Updated: 2025/03/03 23:05:15 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ int builtin_exit(t_minishell *msh, t_command *cmd) exit_status = 0; if (ft_count_arr(cmd->args) > 2) { - ft_putstr_fd("exit\n", STDERR_FILENO); + ft_putstr_fd("exit\n", STDOUT_FILENO); ft_putstr_fd("minishell: exit: too many arguments\n", STDERR_FILENO); return (EXIT_FAILURE); } @@ -28,17 +28,16 @@ int builtin_exit(t_minishell *msh, t_command *cmd) { if (ft_isdigit_str(cmd->args[1]) == FALSE) { - ft_putstr_fd("exit\n", STDERR_FILENO); + ft_putstr_fd("exit\n", STDOUT_FILENO); ft_putstr_fd("minishell: exit: ", STDERR_FILENO); ft_putstr_fd(cmd->args[1], STDERR_FILENO); ft_putstr_fd(": numeric argument required\n", STDERR_FILENO); - return (EXIT_FAILURE); + return (2); } exit_status = ft_atoi(cmd->args[1]); } free_minishell(&msh); - ft_putendl_fd("exit", STDERR_FILENO); + ft_putendl_fd("exit", STDOUT_FILENO); rl_clear_history(); exit(exit_status); - return (FAILURE); } diff --git a/src/builtin/builtin_export.c b/src/builtin/builtin_export.c index adb01c9..71466d3 100644 --- a/src/builtin/builtin_export.c +++ b/src/builtin/builtin_export.c @@ -6,35 +6,47 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:32:53 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:37:13 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:41:06 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" +static int ft_isvalid_identifier(char *str) +{ + if (ft_isalpha(*str) == FALSE && *str != '_') + return (FALSE); + while (*str != '\0') + { + if (ft_isalnum(*str) == FALSE && *str != '_') + return (FALSE); + str++; + } + return (TRUE); +} + int builtin_export(t_minishell *msh, t_command *cmd) { - t_environment *env; + char *err; char **arr; int i; i = 0; arr = NULL; + if (cmd->args[1] == NULL) + environment_print(msh, TRUE); while (cmd->args[++i] != NULL) { arr = ft_split_safe(msh, cmd->args[i], '='); - if (arr[1] == NULL) - return (FAILURE) ; - env = environment_get(msh, arr[0]); - if (env != NULL) - { - free_safe(msh, (void **)&(env->value)); - env->value = ft_strdup_safe(msh, arr[1]); - } + if (arr != NULL && arr[0] != NULL && ft_isvalid_identifier(arr[0]) == TRUE) + environment_update(msh, arr[0], arr[1]); else - environment_add(msh, arr[0], arr[1]); + { + err = ft_strjoin_safe(msh, cmd->args[1], ": not a valid identifier"); + error_msg("export", err); + return (ft_free_arr_safe(msh, arr), EXIT_FAILURE); + } ft_free_arr_safe(msh, arr); } - ft_free_arr_safe(msh, arr); - return (SUCCESS); + return (EXIT_SUCCESS); } diff --git a/src/builtin/builtin_router.c b/src/builtin/builtin_router.c index d8e6960..6703ca5 100644 --- a/src/builtin/builtin_router.c +++ b/src/builtin/builtin_router.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:12:38 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:38:52 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:19:15 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -23,8 +23,8 @@ int builtin_router(t_minishell *msh, t_command *cmd) builtin_env, builtin_exit}; - if (!is_builtin(cmd->args[0])) + if (is_builtin(cmd->args[0]) < 0) return (FALSE); - msh->exit_status = builtin_fn[is_builtin(cmd->args[0])](msh, cmd); - return (TRUE); + return (builtin_fn[is_builtin(cmd->args[0])](msh, cmd)); + } diff --git a/src/builtin/is_builtin.c b/src/builtin/is_builtin.c index 05cb3f9..3d0301f 100644 --- a/src/builtin/is_builtin.c +++ b/src/builtin/is_builtin.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 11:03:33 by whaffman #+# #+# */ -/* Updated: 2025/02/26 14:42:49 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 15:45:38 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -25,5 +25,5 @@ int is_builtin(char *cmd) return (i); i++; } - return (FALSE); + return (-1); } diff --git a/src/builtin/simple_builtins.c b/src/builtin/simple_builtins.c index 296ddf9..3187cea 100644 --- a/src/builtin/simple_builtins.c +++ b/src/builtin/simple_builtins.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/05 16:21:39 by whaffman #+# #+# */ -/* Updated: 2025/02/26 16:08:49 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 15:43:53 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -16,6 +16,5 @@ void simple_builtins(t_minishell *msh) { if (msh->commands == NULL) return ; - if (!builtin_router(msh, msh->commands->content)) - executor_execute_pipeline(msh); + executor_execute_pipeline(msh); } diff --git a/src/debug/print_commands.c b/src/debug/print_commands.c index 2092b8d..84a18ec 100644 --- a/src/debug/print_commands.c +++ b/src/debug/print_commands.c @@ -1,55 +1,76 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* print_commands.c :+: :+: */ -/* +:+ */ -/* By: marvin +#+ */ -/* +#+ */ -/* Created: 2025/02/18 20:06:37 by qmennen #+# #+# */ -/* Updated: 2025/02/23 12:43:35 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -void print_commands(void *param) -{ - t_command *command; - int i; - - if (!DEBUG) - return ; - command = (t_command *)param; - if (!command) - return ; - printf("command: %s\n", command->command); - printf("-- Args: "); - i = 0; - while (command->args[i]) - printf("%s ", command->args[i++]); - printf("\n"); - printf("-- Input redirects:\n"); - ft_lstiter(command->redirect_in, print_redirects); - printf("-- Output redirects:\n"); - ft_lstiter(command->redirect_out, print_redirects); -} - -void print_redirects(void *param) -{ - t_redirect *redirect; - - redirect = (t_redirect *)param; - if (!redirect) - return ; - printf(" Redirect %i value %s\n", redirect->type, redirect->value); -} - -void token_print(void *param) -{ - t_token *token; - - if (!DEBUG) - return ; - token = (t_token *)param; - printf("token type %i, value %s\n", token->type, token->value); -} +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* print_commands.c :+: :+: */ +/* +:+ */ +/* By: marvin +#+ */ +/* +#+ */ +/* Created: 2025/02/18 20:06:37 by qmennen #+# #+# */ +/* Updated: 2025/03/05 13:03:54 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void print_commands(void *param) +{ + t_command *command; + int i; + + if (!DEBUG) + return ; + command = (t_command *)param; + if (!command) + return ; + printf(BOLD "\n==========================\n" RESET); + printf(GREEN BOLD "Command: " RESET "%s\n", command->args[0]); + printf(BOLD "-- Args: " RESET); + i = 0; + while (command->args[i]) + printf("%s ", command->args[i++]); + printf("\n"); + printf(BOLD "-- Input redirects:\n" RESET); + ft_lstiter(command->redirect_in, print_redirects); + printf(BOLD "-- Output redirects:\n" RESET); + ft_lstiter(command->redirect_out, print_redirects); + printf(BOLD "-- fd_in:" RESET " %i\n", command->fd_in); + printf(BOLD "-- fd_out:" RESET " %i\n", command->fd_out); + printf(BOLD "==========================" RESET "\n"); +} + +void print_redirects(void *param) +{ + t_redirect *redirect; + + redirect = (t_redirect *)param; + if (!redirect) + return ; + printf(" Redirect %i value %s\n", redirect->type, redirect->value); +} + +void token_print(void *param) +{ + t_token *token; + const char *token_type[] = { + "T_WORD", + "T_DQWORD", + "T_SQWORD", + "T_PIPE", + "T_REDIRECT_IN", + "T_REDIRECT_OUT", + "T_AND", + "T_OR", + "T_APPEND_OUT", + "T_HEREDOC", + "T_EOF", + "T_ERROR" + }; + + if (!DEBUG) + return ; + token = (t_token *)param; + if (token->type == 11) + printf(RED BOLD "[ERROR]\t\t" RESET "(%s)\n", token_type[token->type]); + else + printf( GREEN BOLD "[%s]\t\t" RESET "{%s(%d)}\n", token->value, token_type[token->type], token->type); +} diff --git a/src/environment/environment_get_arr.c b/src/environment/environment_get_arr.c index d9d2034..80abb92 100644 --- a/src/environment/environment_get_arr.c +++ b/src/environment/environment_get_arr.c @@ -6,34 +6,44 @@ /* By: willem +#+ */ /* +#+ */ /* Created: 2025/02/08 13:59:48 by willem #+# #+# */ -/* Updated: 2025/02/26 16:09:20 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 10:44:41 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" +static char *create_variable(t_minishell *msh, t_environment *env) +{ + char *var; + size_t len; + + len = ft_strlen(env->name) + ft_strlen(env->value) + 2; + var = malloc_safe(msh, len); + ft_strlcpy(var, env->name, len); + ft_strlcat(var, "=", len); + ft_strlcat(var, env->value, len); + return (var); +} + char **environment_get_arr(t_minishell *msh) { char **arr; - t_environment *env; int i; - t_list *environment; + t_list *env; - environment = msh->environment; + env = msh->environment; arr = malloc_safe(msh, - sizeof(char *) * (ft_lstsize(environment) + 1)); + sizeof(char *) * (ft_lstsize(env) + 1)); i = 0; - while (environment != NULL) + while (env != NULL) { - env = (t_environment *)environment->content; - arr[i] = malloc_safe(msh, - ft_strlen(env->name) + ft_strlen(env->value) + 2); - ft_strlcpy(arr[i], env->name, ft_strlen(env->name) + 1); - ft_strlcat(arr[i], "=", ft_strlen(env->name) + 2); - ft_strlcat(arr[i], env->value, - ft_strlen(env->name) + ft_strlen(env->value) + 2); - environment = environment->next; - i++; + if (((t_environment *)env->content)->value != NULL + && ((t_environment *)env->content)->name != NULL) + { + arr[i] = create_variable(msh, (t_environment *)env->content); + i++; + } + env = env->next; } arr[i] = NULL; return (arr); diff --git a/src/environment/environment_print.c b/src/environment/environment_print.c index 8b60aab..5fcdfb7 100644 --- a/src/environment/environment_print.c +++ b/src/environment/environment_print.c @@ -6,23 +6,25 @@ /* By: willem +#+ */ /* +#+ */ /* Created: 2025/02/08 13:52:08 by willem #+# #+# */ -/* Updated: 2025/03/01 14:24:19 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:29:49 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" -void environment_print(t_minishell *msh) +void environment_print(t_minishell *msh, int export) { - char **arr; - int i; + t_list *env_list; + t_environment *env; - arr = environment_get_arr(msh); - i = 0; - while (arr[i] != NULL) + env_list = msh->environment; + while(env_list != NULL) { - printf("%s\n", arr[i]); - i++; + env = (t_environment *)env_list->content; + if (export) + printf("declare -x %s=\"%s\"\n", env->name, env->value); + else + printf("%s=%s\n", env->name, env->value); + env_list = env_list->next; } - ft_free_arr_safe(msh, arr); } diff --git a/src/environment/environment_update.c b/src/environment/environment_update.c new file mode 100644 index 0000000..6dcb290 --- /dev/null +++ b/src/environment/environment_update.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* environment_update.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/03/03 21:28:53 by whaffman #+# #+# */ +/* Updated: 2025/03/03 21:33:16 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void environment_update(t_minishell *msh, char *name, char *value) +{ + t_environment *env; + + if (environment_get(msh, name) == NULL) + { + environment_add(msh, name, value); + } + else + { + env = environment_get(msh, name); + free_safe(msh, (void **)&(env->value)); + env->value = ft_strdup_safe(msh, value); + } +} diff --git a/src/executor/executor_absolute_path.c b/src/executor/executor_absolute_path.c index 86916b1..99c5ccc 100644 --- a/src/executor/executor_absolute_path.c +++ b/src/executor/executor_absolute_path.c @@ -16,14 +16,10 @@ static char *resolve_relative(t_minishell *msh, char *cmd) { char *executable; - if (access(cmd, F_OK) == 0) - { - executable = ft_strdup_safe(msh, cmd); - if (!executable) - return (NULL); - return (executable); - } - return (NULL); + executable = ft_strdup_safe(msh, cmd); + if (!executable) + return (NULL); + return (executable); } static char *resolve_path(t_minishell *msh, char *path, char *cmd) diff --git a/src/executor/executor_child.c b/src/executor/executor_child.c index 923492c..e7948bd 100644 --- a/src/executor/executor_child.c +++ b/src/executor/executor_child.c @@ -24,6 +24,21 @@ static int is_dir(char *path) return (S_ISDIR(path_stats.st_mode)); } +static int validate_executable_path(char *path) +{ + if (access(path, X_OK) < 0) + { + error_msg(path, "Permission denied"); + return (0); + } + if (is_dir(path)) + { + error_msg(path, "Is a directory"); + return (0); + } + return (1); +} + void executor_child(t_minishell *msh, t_command *command) { char *path; @@ -34,18 +49,13 @@ void executor_child(t_minishell *msh, t_command *command) dup2(command->fd_out, 1); executor_close_fds(command->n_fds); path = executor_absolute_path(msh, command->args[0]); - if (path == NULL || access(path, F_OK | X_OK) != 0) + if (path == NULL) { errno = 0; error_msg("minishell", "command not found"); return ; } - if (is_dir(path)) - { - ft_putstr_fd(RED BOLD, 2); - ft_putstr_fd("minishell: ", 2); - ft_putstr_fd(command->args[0], 2); - ft_putstr_fd(": " RESET "Is a directory\n", 2); - } + else if (! validate_executable_path(path)) + return ; execve(path, command->args, environment_get_arr(msh)); } diff --git a/src/executor/executor_execute_pipeline.c b/src/executor/executor_execute_pipeline.c index 166eece..81e9b1b 100644 --- a/src/executor/executor_execute_pipeline.c +++ b/src/executor/executor_execute_pipeline.c @@ -6,32 +6,63 @@ /* By: willem +#+ */ /* +#+ */ /* Created: 2025/02/12 21:25:02 by willem #+# #+# */ -/* Updated: 2025/02/26 17:42:46 by whaffman ######## odam.nl */ +/* Updated: 2025/03/05 13:10:59 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" +static int execute_builtin(t_minishell *msh, t_command *cmd) +{ + int original_stdout; + int original_stdin; + int exit_status; + + original_stdin = dup(STDIN_FILENO); + original_stdout = dup(STDOUT_FILENO); + dup2(cmd->fd_in, STDIN_FILENO); + dup2(cmd->fd_out, STDOUT_FILENO); + signal_init_child(); + exit_status = builtin_router(msh, cmd); + signal_init_minishell(); + close(cmd->fd_in); + close(cmd->fd_out); + dup2(original_stdin, STDIN_FILENO); + dup2(original_stdout, STDOUT_FILENO); + close(original_stdin); + close(original_stdout); + return (exit_status); +} + +static void executor_execute_command(t_minishell *msh, t_command *cmd) +{ + if (cmd->args[0] != NULL && is_builtin(cmd->args[0]) >= 0) + msh->exit_status = execute_builtin(msh, cmd); + else if (cmd->args[0] != NULL) + executor_fork(msh, cmd); +} + int executor_execute_pipeline(t_minishell *msh) { t_list *current; - t_command *command; pid_t last_pid; int exit_status; executor_create_pipes(msh); executor_create_redirects(msh); current = msh->commands; + ft_lstiter(current, print_commands); last_pid = 0; while (current) { - command = (t_command *)current->content; - command->environment = msh->environment; - last_pid = executor_fork(msh, command); + executor_execute_command(msh, (t_command *)current->content); current = current->next; } - waitpid(last_pid, &exit_status, 0); - msh->exit_status = ((exit_status) & 0xff00) >> 8; + if (last_pid != 0) + { + waitpid(last_pid, &exit_status, 0); + msh->exit_status = ((exit_status) & 0xff00) >> 8; + } signal_init_minishell(); - return (((exit_status) & 0xff00) >> 8); + return (msh->exit_status); } diff --git a/src/lexer/lexer_parse_input.c b/src/lexer/lexer_parse_input.c index 1fd02a1..375be79 100644 --- a/src/lexer/lexer_parse_input.c +++ b/src/lexer/lexer_parse_input.c @@ -35,10 +35,12 @@ t_list *ft_parse_input(t_minishell *msh) while (TRUE) { token = ft_token_next(msh, lexer); - if (token->type == T_EOF || token->type == T_ERROR) - break ; ft_lstadd_back(&list, ft_lstnew_safe(msh, token)); + if (token->type == T_EOF || token->type == T_ERROR) + { + break ; + } } - ft_token_free(msh, token); + // ft_token_free(msh, token); return (list); } diff --git a/src/lexer/lexer_read_word.c b/src/lexer/lexer_read_word.c index 2ffb01c..801961b 100644 --- a/src/lexer/lexer_read_word.c +++ b/src/lexer/lexer_read_word.c @@ -14,35 +14,11 @@ static int is_word_char(char c) { - return (ft_isprint(c) - && c != '<' - && c != '>' - && c != '|' - && c != '\0' - && !ft_isspace(c)); -} - -static int match_quotes(t_minishell *msh, t_lexer *lexer) -{ - char c; - int i; - int d_qts; - int s_qts; - - i = lexer->pos; - c = lexer->input[i]; - d_qts = 0; - s_qts = 0; - while (is_word_char(c)) - { - if (lexer->input[i] == '\'') - s_qts++; - if (lexer->input[i] == '\'') - d_qts++; - i++; - c = lexer->input[i]; - } - return ((s_qts % 2) == 0 && (d_qts % 2) == 0); + if (c == '<' || c == '>' || c == '|' || c == '\0') + return (0); + else if (ft_isspace(c)) + return (0); + return (ft_isprint(c)); } static int calculate_word_len(t_minishell *msh, t_lexer *lexer) @@ -54,36 +30,46 @@ static int calculate_word_len(t_minishell *msh, t_lexer *lexer) i = lexer->pos; while (is_word_char(lexer->input[i])) { - if (lexer->input[i] != '\'' && lexer->input[i] != '"') - len++; + + len++; i++; } return (len); } -char *lexer_readword(t_minishell *msh, t_lexer *lexer) +char *read_word(t_minishell *msh, t_lexer *lexer, int len) { - int len; - char *word; char c; + char *dest; + int i; - if (lexer->current_char == '"' || lexer->current_char == '\'') - { - return (lexer_parse_quotes(msh, lexer)); - } - if (!match_quotes(msh, lexer)) - return (NULL); - len = calculate_word_len(msh, lexer); - word = malloc_safe(msh, sizeof(char) * len); + dest = malloc_safe(msh, sizeof(char) * len); c = lexer->current_char; - len = 0; + i = 0; while (is_word_char(c)) { - if (c != '\'' && c != '"') - word[len++] = lexer->current_char; + dest[i++] = lexer->current_char; lexer_readchar(lexer); c = lexer->current_char; } - word[len] = 0; + dest[i] = 0; + return (dest); +} + +char *lexer_readword(t_minishell *msh, t_lexer *lexer) +{ + int len; + int qts; + char *word; + char c; + + c = lexer->current_char; + qts = (c == '"' || c == '\''); + if (qts) + return (lexer_parse_quotes(msh, lexer)); + // if (!match_quotes(msh, lexer, qts)) + // return (NULL); + len = calculate_word_len(msh, lexer); + word = read_word(msh, lexer, len); return (word); } diff --git a/src/lexer/lexer_token_next.c b/src/lexer/lexer_token_next.c index 12d571c..e8d7e34 100644 --- a/src/lexer/lexer_token_next.c +++ b/src/lexer/lexer_token_next.c @@ -22,7 +22,7 @@ static t_token_type get_word_type(char c) return (T_WORD); } -static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) +static t_token * process_word(t_minishell *msh, t_lexer *lexer, int pos) { t_token_type word_type; t_token *token; @@ -31,7 +31,9 @@ static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos) word_type = get_word_type(lexer->current_char); word = lexer_readword(msh, lexer); if (!word) + { return (token_new(msh, T_ERROR, &(lexer->current_char), pos)); + } token = token_new(msh, word_type, word, pos); free_safe(msh, (void **)&word); return (token); diff --git a/src/main.c b/src/main.c index 8a0afbf..873cd1d 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/04 16:19:22 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:25:02 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 16:08:26 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -23,7 +23,7 @@ static void main_loop(t_minishell *msh) msh->tokens = ft_parse_input(msh); ft_lstiter(msh->tokens, token_print); msh->commands = parser_get_commands(msh); - simple_builtins(msh); + executor_execute_pipeline(msh); free_minishell_line(msh); } } diff --git a/src/parser/parser_alloc_command.c b/src/parser/parser_alloc_command.c index fc49925..cd9aee4 100644 --- a/src/parser/parser_alloc_command.c +++ b/src/parser/parser_alloc_command.c @@ -1,18 +1,18 @@ /* ************************************************************************** */ /* */ /* :::::::: */ -/* parser_new_command.c :+: :+: */ +/* parser_alloc_command.c :+: :+: */ /* +:+ */ /* By: qmennen +#+ */ /* +#+ */ /* Created: 2025/02/11 16:18:21 by qmennen #+# #+# */ -/* Updated: 2025/02/26 16:14:31 by whaffman ######## odam.nl */ +/* Updated: 2025/03/04 18:18:09 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "minishell.h" -t_command *parser_alloc_command(t_minishell *msh, char *cmd) +t_command *parser_alloc_command(t_minishell *msh) { t_command *command; @@ -22,8 +22,7 @@ t_command *parser_alloc_command(t_minishell *msh, char *cmd) command->fd_out = 1; command->redirect_in = NULL; command->redirect_out = NULL; - command->environment = NULL; + // command->environment = NULL; command->n_fds = 0; - command->command = cmd; return (command); } diff --git a/src/parser/parser_count_arguments.c b/src/parser/parser_count_arguments.c new file mode 100644 index 0000000..da72901 --- /dev/null +++ b/src/parser/parser_count_arguments.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_count_arguments.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 13:09:30 by qmennen #+# #+# */ +/* Updated: 2025/03/05 13:09:47 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int parser_count_arguments(t_list *list) +{ + int cmds; + t_list *current; + t_list *prev; + t_token *token; + + cmds = 0; + current = list; + prev = NULL; + while (current) + { + token = ((t_token *)current->content); + if (token->type < 3 && (!prev || ((t_token *)prev->content)->type < 3)) + cmds++; + prev = current; + current = current->next; + } + return (cmds); +} + + diff --git a/src/parser/parser_get_arguments.c b/src/parser/parser_get_arguments.c index 0375ba9..4d4effd 100644 --- a/src/parser/parser_get_arguments.c +++ b/src/parser/parser_get_arguments.c @@ -10,26 +10,10 @@ /* */ /* ************************************************************************** */ +#include "libft.h" #include "minishell.h" - -static int count_cmds(t_list *list) -{ - int cmds; - t_list *current; - t_token *token; - - cmds = 0; - current = list; - while (current) - { - token = ((t_token *)current->content); - if (token->type >= 3) - break ; - cmds++; - current = current->next; - } - return (cmds); -} +#include "parser.h" +#include "utils.h" static int parser_should_expand(t_list *value) { @@ -40,40 +24,74 @@ static int parser_should_expand(t_list *value) if (!token) return (0); i = 0; - if (token->type == T_DQWORD) + if (token->type == T_DQWORD || token->type == T_WORD) { while (token->value[i]) { if (token->value[i] == '$' - && !expander_character_valid(token->value[i + 1])) - return (0); + && (expander_character_valid(token->value[i + 1]) || token->value[i + 1] == '?')) + return (1); i++; } - return (1); + return (0); } - return ((token->type == T_WORD && token->value[0] == '$' - && token->value[1])); + return (0); +} + +static char *parser_process_token(t_minishell *msh, char **args, t_list *prev, t_list *t_head) +{ + char *str; + t_token *token; + + if (!t_head) + return (NULL); + token = (t_token *)t_head->content; + str = NULL; + if (ft_strcmp(token->value, "") == 0) + return (NULL); + if (parser_should_expand(t_head)) + str = expander_parse_string(token->value, msh); + if (!str) + str = ft_strdup_safe(msh, token->value); + if (str && token->type == T_WORD && ft_strchr(str, '"')) + str = parser_sanitize_string(msh, str, '"'); + else if (str && token->type == T_WORD && ft_strchr(str, '\'')) + str = parser_sanitize_string(msh, str, '\''); + return (str); } char **parser_get_arguments(t_list *list, t_minishell *msh) { t_list *current; + t_list *prev; char **args; - int cmds; + int argc; int i; + char *str; + char *cat; - cmds = count_cmds(list); - args = malloc_safe(msh, (cmds + 1) * sizeof(char *)); + argc = parser_count_arguments(list); + args = malloc_safe(msh, (argc + 1) * sizeof(char *)); current = list; - i = -1; - while ((++i) < cmds && current) + i = 0; + prev = NULL; + while (argc > 0 && current) { - if (parser_should_expand(current)) - args[i] = expander_parse_string( - ((t_token *)current->content)->value, msh); - else if (((t_token *)current->content)->type < 3) - args[i] = ft_strdup_safe(msh, - ((t_token *)current->content)->value); + if (token_from_list(current)->type < 3 && (!prev || ((t_token *)prev->content)->type < 3)) + { + str = parser_process_token(msh, args, prev, current); + if (i > 0 && prev && ft_strcmp(((t_token *)prev->content)->value, "") == 0) + { + cat = malloc_safe(msh, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); + ft_strlcpy(cat, args[i - 1], ft_strlen(args[i - 1]) + 1); + ft_strlcat(cat, str, ft_strlen(str) + ft_strlen(args[i - 1]) + 1); + args[i - 1] = cat; + } + else if (str) + args[i++] = str; + argc--; + } + prev = current; current = current->next; } args[i] = 0; diff --git a/src/parser/parser_get_commands.c b/src/parser/parser_get_commands.c index 31ec57d..54c4d31 100644 --- a/src/parser/parser_get_commands.c +++ b/src/parser/parser_get_commands.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ -/* ::: :::::::: */ -/* parser_get_commands.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: qmennen +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ -/* Updated: 2025/02/27 16:07:54 by qmennen ### ########.fr */ +/* :::::::: */ +/* parser_get_commands.c :+: :+: */ +/* +:+ */ +/* By: qmennen +#+ */ +/* +#+ */ +/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */ +/* Updated: 2025/03/04 18:21:27 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -22,7 +22,6 @@ t_list *parser_get_commands(t_minishell *msh) t_list *command_list; t_list *current; t_command *command; - t_token *token; command_list = NULL; if (!msh->tokens) @@ -30,8 +29,7 @@ t_list *parser_get_commands(t_minishell *msh) current = msh->tokens; while (current) { - token = (t_token *) current->content; - command = parser_alloc_command(msh, ft_strdup_safe(msh, token->value)); + command = parser_alloc_command(msh); parser_create_command(msh, command, ¤t); if (! parser_validate_command(command)) break ; @@ -41,6 +39,5 @@ t_list *parser_get_commands(t_minishell *msh) if (current && ((t_token *)current->content)->type >= 3) current = current->next; } - ft_lstiter(command_list, print_commands); return (command_list); } diff --git a/src/parser/parser_sanitize_string.c b/src/parser/parser_sanitize_string.c new file mode 100644 index 0000000..68cdb02 --- /dev/null +++ b/src/parser/parser_sanitize_string.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_sanitize_string.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 10:56:27 by qmennen #+# #+# */ +/* Updated: 2025/03/05 11:09:25 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *parser_sanitize_string(t_minishell *msh, char *str, char c) +{ + int i; + int j; + int qts; + char *dest; + + i = 0; + qts = 0; + while (str[i++]) + if (str[i] == c) + qts++; + dest = malloc_safe(msh, ft_strlen(str) - qts + 1); + i = 0; + j = 0; + while (str[i]) + { + if (str[i] != c) + dest[j++] = str[i]; + i++; + } + dest[j] = 0; + free_safe(msh, (void **)&str); + return (dest); +} diff --git a/src/token/token_from_list.c b/src/token/token_from_list.c new file mode 100644 index 0000000..cd95ba2 --- /dev/null +++ b/src/token/token_from_list.c @@ -0,0 +1,18 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* token_from_list.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/05 13:10:47 by qmennen #+# #+# */ +/* Updated: 2025/03/05 13:11:17 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_token *token_from_list(t_list *list) +{ + return ((t_token *)list->content); +} diff --git a/src/utils/error_msg.c b/src/utils/error_msg.c index 6f97296..4bab842 100644 --- a/src/utils/error_msg.c +++ b/src/utils/error_msg.c @@ -6,7 +6,7 @@ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/02/20 17:03:13 by whaffman #+# #+# */ -/* Updated: 2025/03/03 14:13:34 by whaffman ######## odam.nl */ +/* Updated: 2025/03/03 21:20:09 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ @@ -30,13 +30,12 @@ void error_msg(char *func, char *msg) } if (msg != NULL) ft_putstr_fd(msg, STDERR_FILENO); - else - ft_putstr_fd("general error", STDERR_FILENO); - ft_putstr_fd("\n", STDERR_FILENO); - if(DEBUG && errno) + if (errno) { - perror(RED BOLD "DEBUG " SHELL_NAME RESET); + ft_putstr_fd(": ", STDERR_FILENO); + ft_putstr_fd(strerror(errno), STDERR_FILENO); errno = 0; } + ft_putstr_fd("\n", STDERR_FILENO); } } diff --git a/src/utils/free_command_list.c b/src/utils/free_command_list.c index 2ca7ce8..94eaca4 100644 --- a/src/utils/free_command_list.c +++ b/src/utils/free_command_list.c @@ -1,62 +1,60 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* free_command_list.c :+: :+: */ -/* +:+ */ -/* By: marvin +#+ */ -/* +#+ */ -/* Created: 2025/02/11 14:24:05 by qmennen #+# #+# */ -/* Updated: 2025/02/23 12:40:17 by Quinten ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -static void free_args(t_minishell *msh, char **args) -{ - int i; - - i = 0; - while (args[i]) - { - free_safe(msh, (void **)&args[i]); - i++; - } - free_safe(msh, (void **)&args); -} - -static void free_redirects(t_minishell *msh, t_list *lst) -{ - t_redirect *redir; - t_list *current; - t_list *last; - - current = lst; - while (current) - { - last = current; - redir = (t_redirect *)current->content; - if (redir && redir->value) - free_safe(msh, (void **)&redir->value); - if (redir) - free_safe(msh, (void **)&redir); - current = current->next; - free_safe(msh, (void **)&last); - } -} - -void free_command_list(t_minishell *msh, void *content) -{ - t_command *command; - - command = (t_command *)content; - if (command->command) - free_safe(msh, (void **)&(command->command)); - if (command->args) - free_args(msh, command->args); - if (command->redirect_in) - free_redirects(msh, command->redirect_in); - if (command->redirect_out) - free_redirects(msh, command->redirect_out); - free_safe(msh, (void **)&command); -} +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* free_command_list.c :+: :+: */ +/* +:+ */ +/* By: marvin +#+ */ +/* +#+ */ +/* Created: 2025/02/11 14:24:05 by qmennen #+# #+# */ +/* Updated: 2025/02/23 12:40:17 by Quinten ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static void free_args(t_minishell *msh, char **args) +{ + int i; + + i = 0; + while (args[i]) + { + free_safe(msh, (void **)&args[i]); + i++; + } + free_safe(msh, (void **)&args); +} + +static void free_redirects(t_minishell *msh, t_list *lst) +{ + t_redirect *redir; + t_list *current; + t_list *last; + + current = lst; + while (current) + { + last = current; + redir = (t_redirect *)current->content; + if (redir && redir->value) + free_safe(msh, (void **)&redir->value); + if (redir) + free_safe(msh, (void **)&redir); + current = current->next; + free_safe(msh, (void **)&last); + } +} + +void free_command_list(t_minishell *msh, void *content) +{ + t_command *command; + + command = (t_command *)content; + if (command->args) + free_args(msh, command->args); + if (command->redirect_in) + free_redirects(msh, command->redirect_in); + if (command->redirect_out) + free_redirects(msh, command->redirect_out); + free_safe(msh, (void **)&command); +} diff --git a/src/utils/ft_strdup_safe.c b/src/utils/ft_strdup_safe.c index 99bbf95..3ea5cde 100644 --- a/src/utils/ft_strdup_safe.c +++ b/src/utils/ft_strdup_safe.c @@ -1,22 +1,24 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* ft_strdup_safe.c :+: :+: */ -/* +:+ */ -/* By: whaffman +#+ */ -/* +#+ */ -/* Created: 2025/02/20 18:01:27 by whaffman #+# #+# */ -/* Updated: 2025/02/20 18:04:53 by whaffman ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -char *ft_strdup_safe(t_minishell *msh, const char *str) -{ - char *new_str; - - new_str = ft_strdup(str); - check_malloc(msh, new_str); - return (new_str); -} +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* ft_strdup_safe.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/02/20 18:01:27 by whaffman #+# #+# */ +/* Updated: 2025/03/04 09:59:41 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +char *ft_strdup_safe(t_minishell *msh, const char *str) +{ + char *new_str; + + if (!str) + return (NULL); + new_str = ft_strdup(str); + check_malloc(msh, new_str); + return (new_str); +} diff --git a/src/utils/malloc_safe.c b/src/utils/malloc_safe.c index 5485afd..b4d423a 100644 --- a/src/utils/malloc_safe.c +++ b/src/utils/malloc_safe.c @@ -1,22 +1,23 @@ -/* ************************************************************************** */ -/* */ -/* :::::::: */ -/* malloc_safe.c :+: :+: */ -/* +:+ */ -/* By: whaffman +#+ */ -/* +#+ */ -/* Created: 2025/02/20 18:06:46 by whaffman #+# #+# */ -/* Updated: 2025/02/20 18:07:00 by whaffman ######## odam.nl */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" - -void *malloc_safe(t_minishell *msh, size_t size) -{ - void *ptr; - - ptr = malloc(size); - check_malloc(msh, ptr); - return (ptr); -} +/* ************************************************************************** */ +/* */ +/* :::::::: */ +/* malloc_safe.c :+: :+: */ +/* +:+ */ +/* By: whaffman +#+ */ +/* +#+ */ +/* Created: 2025/02/20 18:06:46 by whaffman #+# #+# */ +/* Updated: 2025/03/04 16:38:10 by whaffman ######## odam.nl */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void *malloc_safe(t_minishell *msh, size_t size) +{ + void *ptr; + if (size == 0) + return (NULL); + ptr = malloc(size); + check_malloc(msh, ptr); + return (ptr); +}