[ADD] export builtin (unfinished)

This commit is contained in:
mcolonna 2024-06-28 14:34:38 +02:00
parent f578b5311b
commit 532b4e959f
12 changed files with 199 additions and 66 deletions

View file

@ -7,7 +7,7 @@ INCLUDES = include/ libtf/ libft/
# .c files in src/ without the extension # .c files in src/ without the extension
CODE = main ask_command error path parse_command exec_command builtin builtin2\ CODE = main ask_command error path parse_command exec_command builtin builtin2\
signals cool_readline variables parse_command_utils \ 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' # directories to 'make'
LIBRARIES = libtf libft LIBRARIES = libtf libft
# .a files to include # .a files to include

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ /* 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 // Execute cd builtin
int cd_builtin(t_env *env, t_call call); int cd_builtin(t_env *env, t_call call);
// Execute export builtin
int export_builtin(t_env *env, t_call call);
#endif #endif

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ /* 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 t_memclass mc_command; // open during the execution of a command
int errorstatus; // Error status of the last executed command int errorstatus; // Error status of the last executed command
t_list *variables; // Shell variables t_list *variables; // Shell variables
char *const *envp; // Environment variables
bool exit; // Set to true to exit minishell bool exit; // Set to true to exit minishell
} t_env; } t_env;

View file

@ -6,7 +6,7 @@
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */ /* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/27 13:43:21 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 *name;
const char *value; const char *value;
bool exported;
} t_variable; } t_variable;
// Set a variable to a new value. // 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. // Get the value of a variable from its name.
const char *variables_get(t_list *variables, const char *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 #endif

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/03 12:02:45 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 ( return (
ft_strncmp(str, "cd", 3) == 0 ft_strncmp(str, "cd", 3) == 0
|| ft_strncmp(str, "exit", 5) == 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, "env", 4) == 0
|| ft_strncmp(str, "pwd", 4) == 0 || ft_strncmp(str, "pwd", 4) == 0
|| ft_strncmp(str, "echo", 5) == 0 || ft_strncmp(str, "echo", 5) == 0
|| ft_strncmp(str, "unset", 6) == 0 || ft_strncmp(str, "unset", 6) == 0
); );
} }
// Execute the builtin pwd for the current directory. // Execute the builtin pwd for the current directory.
@ -49,16 +49,21 @@ static int pwd_builtin(void)
return (0); 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; i = 0;
while (envp[i] != NULL) while (envp[i] != NULL)
{ {
printf("%s\n", envp[i]); printf("%s\n", envp[i]);
i++; i++;
} }
mem_freeall(mc);
return (0); return (0);
} }
@ -72,8 +77,8 @@ int exec_builtin(t_env *env, t_call call)
return (cd_builtin(env, call)); return (cd_builtin(env, call));
if (ft_strncmp(call.program, "exit", 5) == 0) if (ft_strncmp(call.program, "exit", 5) == 0)
env->exit = true; env->exit = true;
/* if (ft_strncmp(call.program, "export", 7) == 0) if (ft_strncmp(call.program, "export", 7) == 0)
return (export_builtin(call.argv));*/ return (export_builtin(env, call));
if (ft_strncmp(call.program, "unset", 6) == 0) if (ft_strncmp(call.program, "unset", 6) == 0)
return (unset_builtin(env, call)); return (unset_builtin(env, call));
if (ft_strncmp(call.program, "pwd", 4) == 0) 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) if (ft_strncmp(call.program, "echo", 5) == 0)
return (echo_builtin((const char **)call.argv)); return (echo_builtin((const char **)call.argv));
if (ft_strncmp(call.program, "env", 4) == 0) if (ft_strncmp(call.program, "env", 4) == 0)
return (env_builtin(env->envp)); return (env_builtin(env, call));
return (1); return (1);
} }

View file

@ -6,12 +6,23 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/25 13:28:29 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" #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 echo_builtin(const char **argv)
{ {
int i; int i;

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:48:00 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, static int exec_each_call(t_exec_command_global *global,
t_command command, t_env *env) t_command command, t_env *env)
{ {
int i; int i;
int r; int r;
int inout[2]; int inout[2];
t_memclass mc;
i = -1; i = -1;
while (++i < global->nb_calls) while (++i < global->nb_calls)
{ {
mc = mem_subclass(fatal_error, global->mc);
inout[0] = global->pipes[i].pipe[0]; inout[0] = global->pipes[i].pipe[0];
inout[1] = global->pipes[i + 1].pipe[1]; inout[1] = global->pipes[i + 1].pipe[1];
if (is_builtin(command.calls[i].program)) if (is_builtin(command.calls[i].program))
r = exec_builtin(env, command.calls[i]); r = exec_builtin(env, command.calls[i]);
else 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) if (r)
return (r); return (r);
} }

View file

@ -6,7 +6,7 @@
/* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */ /* By: jschaft <cecile.schaft@orange.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 14:33:45 by mcolonna #+# #+# */ /* 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 = mem_alloc(fatal_error, env.mc_global, sizeof(t_variable));
var->name = splitted[0]; var->name = splitted[0];
var->value = splitted[1]; var->value = splitted[1];
var->exported = true;
list_add(fatal_error, &r, var); list_add(fatal_error, &r, var);
} }
return (r); return (r);
@ -92,7 +93,6 @@ int main(const int argc, const char *argv[], char *const envp[])
set_global_mc(env.mc_global); set_global_mc(env.mc_global);
env.mc_command = NULL; env.mc_command = NULL;
env.errorstatus = 0; env.errorstatus = 0;
env.envp = envp;
variables = variables_from_envp(env, envp); variables = variables_from_envp(env, envp);
env.variables = &variables; env.variables = &variables;
start(&env); start(&env);

View file

@ -6,7 +6,7 @@
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */ /* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:47:40 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); streamstr_init(&args->stream, command);
skip_blank(&args->stream); skip_blank(&args->stream);
name = str_dup(fatal_error, args->mc, ""); name = str_dup(fatal_error, args->mc, "");
read_only(args, &var.name, SYMBOL_CHARS); read_only(args, &name, SYMBOL_CHARS);
if (str_len(var.name) == 0 || stream_pop(&args->stream) != '=') if (str_len(name) == 0 || stream_pop(&args->stream) != '=')
return (false); return (false);
value = read_string(args, "<>|/"); value = read_string(args, "<>|/");
if (args->r.error) if (args->r.error)

View file

@ -6,52 +6,12 @@
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */ /* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/24 13:47:40 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" #include "include.h"
#include "variables_utils.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);
}
void variables_set(t_list *variables, const char *name, const char *value) 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); 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);
}

55
src/variables_utils.c Normal file
View file

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* variables_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

25
src/variables_utils.h Normal file
View file

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* variables_utils.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mcolonna <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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