From 532b4e959fc537202f0f2345d1f6b422de4f1bdc Mon Sep 17 00:00:00 2001 From: mcolonna Date: Fri, 28 Jun 2024 14:34:38 +0200 Subject: [PATCH] [ADD] export builtin (unfinished) --- Makefile | 2 +- include/builtins.h | 5 +- include/main.h | 3 +- include/variables.h | 12 ++++- src/builtin.c | 21 +++++---- src/builtin2.c | 13 +++++- src/exec_command.c | 14 ++++-- src/main.c | 4 +- src/parse_command.c | 6 +-- src/variables.c | 105 +++++++++++++++++++++++++----------------- src/variables_utils.c | 55 ++++++++++++++++++++++ src/variables_utils.h | 25 ++++++++++ 12 files changed, 199 insertions(+), 66 deletions(-) create mode 100644 src/variables_utils.c create mode 100644 src/variables_utils.h diff --git a/Makefile b/Makefile index f0fc9f9..17dd156 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ INCLUDES = include/ libtf/ libft/ # .c files in src/ without the extension CODE = main ask_command error path parse_command exec_command builtin builtin2\ signals cool_readline variables parse_command_utils \ - parse_command_read_string parse_command_read_element + parse_command_read_string parse_command_read_element variables_utils # directories to 'make' LIBRARIES = libtf libft # .a files to include diff --git a/include/builtins.h b/include/builtins.h index ce51969..d94ff57 100644 --- a/include/builtins.h +++ b/include/builtins.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 11:52:13 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:25:50 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,4 +27,7 @@ int echo_builtin(const char **argv); // Execute cd builtin int cd_builtin(t_env *env, t_call call); +// Execute export builtin +int export_builtin(t_env *env, t_call call); + #endif diff --git a/include/main.h b/include/main.h index 4f6df78..80a8769 100644 --- a/include/main.h +++ b/include/main.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/13 16:39:07 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:01:25 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,6 @@ typedef struct s_env t_memclass mc_command; // open during the execution of a command int errorstatus; // Error status of the last executed command t_list *variables; // Shell variables - char *const *envp; // Environment variables bool exit; // Set to true to exit minishell } t_env; diff --git a/include/variables.h b/include/variables.h index 06fba69..b64db7f 100644 --- a/include/variables.h +++ b/include/variables.h @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 13:43:21 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 13:10:43 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:22:50 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ typedef struct s_variable { const char *name; const char *value; + bool exported; } t_variable; // Set a variable to a new value. @@ -26,4 +27,13 @@ void variables_set(t_list *variables, const char *name, // Get the value of a variable from its name. const char *variables_get(t_list *variables, const char *name); +// Set a variable as exported. +void variables_export(t_list *variables, const char *name); + +// Unset a variable. +void variables_unset(t_list *variables, const char *name); + +// Get a envp of all exported variables. +char *const *variables_envp(t_list *variables, t_memclass mc); + #endif diff --git a/src/builtin.c b/src/builtin.c index 0fa47fa..b819a7e 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */ -/* Updated: 2024/06/28 13:12:49 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:24:40 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,12 +29,12 @@ bool is_builtin(const char *str) return ( ft_strncmp(str, "cd", 3) == 0 || ft_strncmp(str, "exit", 5) == 0 -// || ft_strncmp(str, "export", 7) == 0 + || ft_strncmp(str, "export", 7) == 0 || ft_strncmp(str, "env", 4) == 0 || ft_strncmp(str, "pwd", 4) == 0 || ft_strncmp(str, "echo", 5) == 0 || ft_strncmp(str, "unset", 6) == 0 - ); + ); } // Execute the builtin pwd for the current directory. @@ -49,16 +49,21 @@ static int pwd_builtin(void) return (0); } -static int env_builtin(char *const envp[]) +// TODO check arguments +static int env_builtin(t_env *env, t_call call) { - int i; + int i; + const t_memclass mc = mem_subclass(fatal_error, env->mc_global); + char *const *envp = variables_envp(env->variables, mc); + (void)call; i = 0; while (envp[i] != NULL) { printf("%s\n", envp[i]); i++; } + mem_freeall(mc); return (0); } @@ -72,8 +77,8 @@ int exec_builtin(t_env *env, t_call call) return (cd_builtin(env, call)); if (ft_strncmp(call.program, "exit", 5) == 0) env->exit = true; -/* if (ft_strncmp(call.program, "export", 7) == 0) - return (export_builtin(call.argv));*/ + if (ft_strncmp(call.program, "export", 7) == 0) + return (export_builtin(env, call)); if (ft_strncmp(call.program, "unset", 6) == 0) return (unset_builtin(env, call)); if (ft_strncmp(call.program, "pwd", 4) == 0) @@ -81,6 +86,6 @@ int exec_builtin(t_env *env, t_call call) if (ft_strncmp(call.program, "echo", 5) == 0) return (echo_builtin((const char **)call.argv)); if (ft_strncmp(call.program, "env", 4) == 0) - return (env_builtin(env->envp)); + return (env_builtin(env, call)); return (1); } diff --git a/src/builtin2.c b/src/builtin2.c index 569635b..5afdddd 100644 --- a/src/builtin2.c +++ b/src/builtin2.c @@ -6,12 +6,23 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */ -/* Updated: 2024/06/28 12:04:26 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:26:05 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" +// TODO 'name=value' notation +int export_builtin(t_env *env, t_call call) +{ + int i; + + i = 0; + while (call.argv[++i]) + variables_export(env->variables, call.argv[i]); + return (0); +} + int echo_builtin(const char **argv) { int i; diff --git a/src/exec_command.c b/src/exec_command.c index 95cf450..1c808b9 100644 --- a/src/exec_command.c +++ b/src/exec_command.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */ -/* Updated: 2024/06/28 12:54:07 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:04:08 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -86,19 +86,23 @@ static int create_pipes(t_exec_command_global *global, t_command command) static int exec_each_call(t_exec_command_global *global, t_command command, t_env *env) { - int i; - int r; - int inout[2]; + int i; + int r; + int inout[2]; + t_memclass mc; i = -1; while (++i < global->nb_calls) { + mc = mem_subclass(fatal_error, global->mc); inout[0] = global->pipes[i].pipe[0]; inout[1] = global->pipes[i + 1].pipe[1]; if (is_builtin(command.calls[i].program)) r = exec_builtin(env, command.calls[i]); else - r = execute_call(global, command.calls[i], inout, env->envp); + r = execute_call(global, command.calls[i], inout, + variables_envp(env->variables, mc)); + mem_freeall(mc); if (r) return (r); } diff --git a/src/main.c b/src/main.c index dd27111..b034f77 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:33:45 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 12:53:23 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:10:09 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,6 +29,7 @@ static t_list variables_from_envp(t_env env, char *const envp[]) var = mem_alloc(fatal_error, env.mc_global, sizeof(t_variable)); var->name = splitted[0]; var->value = splitted[1]; + var->exported = true; list_add(fatal_error, &r, var); } return (r); @@ -92,7 +93,6 @@ int main(const int argc, const char *argv[], char *const envp[]) set_global_mc(env.mc_global); env.mc_command = NULL; env.errorstatus = 0; - env.envp = envp; variables = variables_from_envp(env, envp); env.variables = &variables; start(&env); diff --git a/src/parse_command.c b/src/parse_command.c index 4613a8b..f7747e2 100644 --- a/src/parse_command.c +++ b/src/parse_command.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 13:14:15 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:10:53 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,8 +59,8 @@ static bool parse_variable_set_command( streamstr_init(&args->stream, command); skip_blank(&args->stream); name = str_dup(fatal_error, args->mc, ""); - read_only(args, &var.name, SYMBOL_CHARS); - if (str_len(var.name) == 0 || stream_pop(&args->stream) != '=') + read_only(args, &name, SYMBOL_CHARS); + if (str_len(name) == 0 || stream_pop(&args->stream) != '=') return (false); value = read_string(args, "<>|/"); if (args->r.error) diff --git a/src/variables.c b/src/variables.c index 5ff6f54..53142f9 100644 --- a/src/variables.c +++ b/src/variables.c @@ -6,52 +6,12 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 13:11:41 by mcolonna ### ########.fr */ +/* Updated: 2024/06/28 14:33:14 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" - -static void variables_free(t_list *variables, t_list_element *el) -{ - if (el->previous) - el->previous->next = el->next; - else - variables->first = el->next; - if (el->next) - el->next->previous = el->previous; - else - variables->last = el->previous; - variables->size--; - mem_free(el->value); - mem_free(el); -} - -// Return a pointer to the variable 'name'. -// (An undefined variable is considered of an empty value) -static t_variable *variables_find(t_list *variables, const char *name) -{ - t_list_element *el; - t_list_element *next; - t_variable *r; - - el = variables->first; - while (el) - { - next = el->next; - r = (t_variable *)el->value; - if (str_eq(r->name, name)) - return (r); - if (str_eq(r->value, "")) - variables_free(variables, el); - el = next; - } - r = mem_alloc(fatal_error, variables->mc, sizeof(t_variable)); - r->name = str_dup(fatal_error, variables->mc, name); - r->value = ""; - list_add(fatal_error, variables, r); - return (r); -} +#include "variables_utils.h" void variables_set(t_list *variables, const char *name, const char *value) { @@ -63,3 +23,64 @@ const char *variables_get(t_list *variables, const char *name) { return (variables_find(variables, name)->value); } + +void variables_export(t_list *variables, const char *name) +{ + variables_find(variables, name)->exported = true; +} + +void variables_unset(t_list *variables, const char *name) +{ + t_list_element *el; + t_list_element *next; + t_variable *r; + + el = variables->first; + while (el) + { + next = el->next; + r = (t_variable *)el->value; + if (str_eq(r->name, name)) + { + if (el->previous) + el->previous->next = el->next; + else + variables->first = el->next; + if (el->next) + el->next->previous = el->previous; + else + variables->last = el->previous; + variables->size--; + mem_free(el->value); + mem_free(el); + } + el = next; + } +} + +char *const *variables_envp(t_list *variables, t_memclass mc) +{ + t_list_element *el; + const int count = variables_countexported(variables); + char **r; + int i; + char *tmp; + + r = mem_alloc(fatal_error, mc, (count + 1) * sizeof(char *)); + el = variables->first; + i = -1; + while (el) + { + if (((t_variable *)(el->value))->exported) + { + tmp = str_join( + fatal_error, mc, ((t_variable *)(el->value))->name, "="); + r[++i] = str_join( + fatal_error, mc, tmp, ((t_variable *)(el->value))->value); + mem_free(tmp); + } + el = el->next; + } + r[++i] = NULL; + return (r); +} diff --git a/src/variables_utils.c b/src/variables_utils.c new file mode 100644 index 0000000..7e9150f --- /dev/null +++ b/src/variables_utils.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* variables_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ +/* Updated: 2024/06/28 14:30:52 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" +#include "variables_utils.h" + +t_variable *variables_find(t_list *variables, const char *name) +{ + t_list_element *el; + t_list_element *next; + t_variable *r; + + el = variables->first; + while (el) + { + next = el->next; + r = (t_variable *)el->value; + if (str_eq(r->name, name)) + return (r); + if (str_eq(r->value, "") && !r->exported) + variables_unset(variables, r->name); + el = next; + } + r = mem_alloc(fatal_error, variables->mc, sizeof(t_variable)); + r->name = str_dup(fatal_error, variables->mc, name); + r->value = ""; + r->exported = false; + list_add(fatal_error, variables, r); + return (r); +} + +int variables_countexported(t_list *variables) +{ + int r; + t_list_element *el; + + r = 0; + el = variables->first; + while (el) + { + if (((t_variable *)(el->value))->exported) + r++; + el = el->next; + } + return (r); +} diff --git a/src/variables_utils.h b/src/variables_utils.h new file mode 100644 index 0000000..a08a7a4 --- /dev/null +++ b/src/variables_utils.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* variables_utils.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ +/* Updated: 2024/06/28 14:35:55 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VARIABLES_UTILS_H +# define VARIABLES_UTILS_H + +# include "include.h" + +// Return a pointer to the variable 'name'. +// (An undefined variable is considered of an empty value) +t_variable *variables_find(t_list *variables, const char *name); + +// Return the number of exported variables. +int variables_countexported(t_list *variables); + +#endif