From: Lukas Jiriste Date: Thu, 2 May 2024 11:27:09 +0000 (+0200) Subject: Implement variables framework, update Libft X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=184d7cb99bcd836bf07f0707d08ddd8ef1ecee0f;p=42%2Fminishell.git Implement variables framework, update Libft So far the variable handling consists of copying the environment inherited by minishell to separate variable to make changes to it possible (I suspect that one should not directly change the environ). The vars struct consists of 2 vectos of strings, one for the exported variables and one for the others. This is done so that the exported->vec can be directly passed to execve instead of contructing it by filtering the exported values from a common vector. This is also why the vector is initialized with NULL. The other vec is constructed the same way so as to be able to reuse the code for exported. During work on this commit the function ft_strcat_alloc seemed to be a great candidate for addition to Libft. That was done and the function was used in this commit, hence the Libft update. --- diff --git a/Libft b/Libft index 580d3d9..85fc90a 160000 --- a/Libft +++ b/Libft @@ -1 +1 @@ -Subproject commit 580d3d9325f4105b5448a5f0e5503e6d105c6117 +Subproject commit 85fc90a5625657e074a2833cb5a51ffe9a0db255 diff --git a/Makefile b/Makefile index 9166aa6..573dd59 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ INCLUDE := $(addprefix -I, $(INCDIR)) SRCDIR := src SOURCES := main.c \ + vars.c \ SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES)) diff --git a/inc/minishell.h b/inc/minishell.h new file mode 100644 index 0000000..06a02cc --- /dev/null +++ b/inc/minishell.h @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* minishell.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/02 13:22:57 by ljiriste #+# #+# */ +/* Updated: 2024/05/02 13:25:41 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MINISHELL_H +# define MINISHELL_H + +# include "libft.h" + +typedef struct s_vars +{ + t_vec exported; + t_vec other; +} t_vars; + +int init_vars(t_vars *vars, char **envp); +int add_var_line(t_vec *vec, const char *line); +int add_var(t_vec *vec, const char *key, const char *value); +void clean_vars(t_vars *vars); + +#endif // MINISHELL_H diff --git a/src/main.c b/src/main.c index 59d0bf7..52c5889 100644 --- a/src/main.c +++ b/src/main.c @@ -6,10 +6,11 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/26 13:11:47 by ljiriste #+# #+# */ -/* Updated: 2024/04/26 14:13:15 by ljiriste ### ########.fr */ +/* Updated: 2024/05/02 13:54:36 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ +#include "minishell.h" #include "libft.h" #include #include // getcwd @@ -50,25 +51,49 @@ char *rl_get_line(void) return (line); } -void handle_input(__attribute__((unused)) const char *input) +void handle_input(__attribute__((unused)) const char *input, __attribute__((unused)) t_vars *vars) { return ; } -int main(void) +void print_help(void) +{ + ft_printf("Minishell should be used without any arguments.\n"); + return ; +} + +/* +// This would be more portable than the main with 3 input args +extern char **environ; +const char **envp = environ; +int main(int argc, char **argv) +*/ +int main(int argc, __attribute__((unused)) char **argv, char **envp) { char *line; + t_vars vars; + if (argc > 1) + { + print_help(); + return (1); + } + if (init_vars(&vars, envp)) + { + clean_vars(&vars); + return (2); + } while (1) { line = rl_get_line(); if (!line || !ft_strcmp(line, "exit")) - { - rl_clear_history(); - ft_printf("exit\n"); - return (0); - } - handle_input(line); + break ; + handle_input(line, &vars); free(line); } + rl_clear_history(); + clean_vars(&vars); + free(line); + ft_printf("exit\n"); + return (0); } diff --git a/src/vars.c b/src/vars.c new file mode 100644 index 0000000..8b11d6d --- /dev/null +++ b/src/vars.c @@ -0,0 +1,85 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vars.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/02 13:21:32 by ljiriste #+# #+# */ +/* Updated: 2024/05/02 13:24:39 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +#include "libft.h" +#include + +int add_var_line(t_vec *vec, const char *line) +{ + char *tmp; + + tmp = ft_strdup(line); + if (!tmp) + return (1); + if (ft_vec_insert(vec, &tmp, vec->size - 1) != success) + { + free(tmp); + return (1); + } + return (0); +} + +// The keyval_pair is freed only in case of error +// When allocation fails in ft_strcal_alloc, it is freed automatically +// When allocation the insert fails, it needs to be freed here +// When everything goes smoothly, the memory is freed when the vec +// erases this entry +int add_var(t_vec *vec, const char *key, const char *value) +{ + char *keyval_pair; + + keyval_pair = ft_strdup(key); + if (!keyval_pair) + return (1); + if (!ft_strcat_alloc(&keyval_pair, "=")) + return (1); + if (!ft_strcat_alloc(&keyval_pair, value)) + return (1); + if (ft_vec_insert(vec, &keyval_pair, vec->size - 1) != success) + { + free(keyval_pair); + return (1); + } + return (0); +} + +int init_vars(t_vars *vars, char **envp) +{ + char *tmp; + + ft_vec_init(&vars->exported, sizeof(char *)); + ft_vec_init(&vars->other, sizeof(char *)); + tmp = NULL; + ft_vec_append(&vars->exported, &tmp); + ft_vec_append(&vars->other, &tmp); + while (*envp) + { + if (add_var_line(&vars->exported, *envp)) + return (1); + ++envp; + } + return (0); +} + +static void free_str(void *str) +{ + free(*(char **)str); + return ; +} + +void clean_vars(t_vars *vars) +{ + ft_vec_free(&vars->exported, free_str); + ft_vec_free(&vars->other, free_str); + return ; +}