From cd8c8b36d99255890e0e52ebdb30e328398c420d Mon Sep 17 00:00:00 2001 From: Loic Deridder Date: Mon, 20 Jan 2025 12:58:57 +0100 Subject: [PATCH] builtins --- includes/builtins.h | 7 +- includes/env.h | 24 +++++++ includes/minishell.h | 1 + srcs/builtins/cd.c | 128 ++++++++-------------------------- srcs/builtins/unset.c | 43 +++++++----- srcs/builtins/utils.c | 14 ++++ srcs/env/var.c | 159 ++++++++++++++++++++++++++++++++++++++++++ srcs/main.c | 45 +++++++++--- 8 files changed, 296 insertions(+), 125 deletions(-) create mode 100644 includes/env.h create mode 100644 srcs/builtins/utils.c create mode 100644 srcs/env/var.c diff --git a/includes/builtins.h b/includes/builtins.h index 479dd84..fa3a8be 100644 --- a/includes/builtins.h +++ b/includes/builtins.h @@ -2,6 +2,7 @@ # define BUILTINS_H # include "../lib/libft/libft.h" +# include "env.h" # include # include # include @@ -9,14 +10,15 @@ # include # include # include +# include // void echo(char *msg, int flag); void builtin_echo(char *arg, char **envp); void builtin_exit(char *arg, bool depth); void builtin_pwd(char *arg); void builtin_env(char *str, char **envp); -void builtin_unset(char *str, char **envp); -char **builtin_cd(char **arg, char **envp); +int builtin_unset(char **arg, t_data *data); +int builtin_cd(char **arg, t_data *data); char **builtin_export(char **arg, char **envp); //UTILS @@ -24,5 +26,6 @@ int count_char(char *str); int count_args(char **tab); int extractenv(char *str, char **envp); char *ft_getenv(char *str, char **envp); +int err_msg_cmd(char *cmd, char *arg, char *msg, int code); #endif diff --git a/includes/env.h b/includes/env.h new file mode 100644 index 0000000..26b80b1 --- /dev/null +++ b/includes/env.h @@ -0,0 +1,24 @@ +#ifndef ENV_H +# define ENV_H + +# include "../lib/libft/libft.h" +# include +# include +# include + +typedef struct s_data +{ + char **env; +} t_data; + +//VAR +int count_var(char **envp); +int get_var_index(char *key, char **envp); +void free_null_ptr(void *ptr); +char **copy_env_var(char **envp, int count); +char *get_var_value(char *key, char **envp); +bool is_valid_key(char *key, char **envp); +int remove_env_var(char *key, char **envp); +void set_var_env(char *key, char *value, t_data *t_data); + +#endif diff --git a/includes/minishell.h b/includes/minishell.h index b70af5f..1aefd2e 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -9,6 +9,7 @@ # include "../lib/libft/libft.h" # include "builtins.h" +# include "env.h" # define POW1 "\033[1;38;2;21;22;26;48;2;92;106;178m" # define POW2 "\033[1;38;2;92;106;178;48;2;54;54;54m" diff --git a/srcs/builtins/cd.c b/srcs/builtins/cd.c index 073b1aa..d25d251 100644 --- a/srcs/builtins/cd.c +++ b/srcs/builtins/cd.c @@ -1,111 +1,45 @@ #include "../../includes/builtins.h" -int count_args(char **tab) +void pwd_update(t_data *data, char *src, char *dest) { - int i; - - i = 0; - while (tab[i]) - i++; - return (i); + set_var_env("OLDPWD", src, data); + set_var_env("PWD", dest, data); + free_null_ptr(src); + free_null_ptr(dest); } -char **update_oldpwd(char **envp) +int exec_cd(char *path, t_data *data) { - char **new_envp; - int i; + char *src; + char *dest; - i = 0; - while (envp[i]) - i++; - new_envp = malloc(sizeof(char *) * i + 1); - if (!new_envp) - return (perror("malloc"), NULL); - new_envp[i] = NULL; - i = -1; - while (envp[++i]) - { - if (ft_strnstr(envp[i], "OLDPWD=", 7) == NULL) - new_envp[i] = ft_strdup(envp[i]); - else - new_envp[i] = ft_strjoin("OLDPWD=", getcwd(NULL, 0)); - } - return (new_envp); + src = getcwd(NULL, 0); + if (chdir(path) == -1) + return (err_msg_cmd("cd", path, strerror(errno), EXIT_FAILURE)); + dest = getcwd(NULL, 0); + pwd_update(data, src, dest); + return (0); } -char **update_pwd(char **envp) +int builtin_cd(char **arg, t_data *data) { - char **new_envp; - int i; + char *path; - i = 0; - while (envp[i]) - i++; - new_envp = malloc(sizeof(char *) * i + 1); - if (!new_envp) - return (perror("malloc"), NULL); - new_envp[i] = NULL; - i = -1; - while (envp[++i]) + if (count_var(arg) == 1 || (count_var(arg) == 2 && ft_strncmp(arg[1], "~", 1) == 0)) { - if (ft_strnstr(envp[i], "PWD=", 4) == NULL) - new_envp[i] = ft_strdup(envp[i]); - else - new_envp[i] = ft_strjoin("PWD=", getcwd(NULL, 0)); + path = get_var_value("HOME", data->env); + if (!path) + return (err_msg_cmd("cd", NULL, "HOME not set\n", EXIT_FAILURE)); + return (exec_cd(path, data)); } - return (new_envp); -} - -int check_path(char *str) -{ - if (access(str, F_OK | X_OK) == -1) - { - ft_put_s_fd(str, 2); - ft_put_s_fd(": ", 2); - perror("cd"); - return (0); - } - return (1); -} - -// void expand_var(char *str, char **envp) -// { -// char *new_arg; -// char *tmp; -// int i; -// int j; -// -// i = -1; -// while (str[++i]) -// { -// if (str[i] == '$') -// { -// j = 0; -// while (str[j] && str[j] != ' ') -// j++; -// if (j >= 1) -// } -// } -// } - -char **builtin_cd(char **arg, char **envp) -{ - // char *path; - - if (count_args(arg) >= 3) - { - ft_putendl_fd("cd: too many arguments", 2); - return (envp); - } - // path = expand_var(arg[1], envp); - if (!check_path(arg[1])) - return (envp); - envp = update_oldpwd(envp); - if (chdir(arg[1]) == -1) - { - perror("cd"); - return (envp); - } - envp = update_pwd(envp); - return (envp); + if (count_var(arg) > 2) + return (err_msg_cmd("cd", NULL, "too many arguments\n", EXIT_FAILURE)); + if (ft_strncmp(arg[1], "-", 1) == 0) + { + path = get_var_value("OLDPWD", data->env); + if (!path) + return (err_msg_cmd("cd", NULL, "OLDPWD not set\n", EXIT_FAILURE)); + return (exec_cd(path, data)); + } + return (exec_cd(arg[1], data)); } diff --git a/srcs/builtins/unset.c b/srcs/builtins/unset.c index 8d51dd4..32e9447 100644 --- a/srcs/builtins/unset.c +++ b/srcs/builtins/unset.c @@ -1,22 +1,29 @@ #include "../../includes/builtins.h" -void builtin_unset(char *str, char **envp) +// void builtin_unset(char *str, char **envp) +// { +// int i; +// char *var; +// +// if (count_char(str) == 5) +// { +// ft_putendl_fd("unset: not enough arguments", 2); +// // exit(1); +// } +// i = 0; +// while(str[5 + i] && str[5 + i] == ' ') +// i++; +// var = &str[5 + i]; +// i = 0; +// while (ft_strnstr(envp[i], var, ft_strlen(var)) == NULL) +// i++; +// if (envp[i]) +// envp[i][0] = '\0'; +// } +// +int builtin_unset(char **arg, t_data *data) { - int i; - char *var; - - if (count_char(str) == 5) - { - ft_putendl_fd("unset: not enough arguments", 2); - // exit(1); - } - i = 0; - while(str[5 + i] && str[5 + i] == ' ') - i++; - var = &str[5 + i]; - i = 0; - while (ft_strnstr(envp[i], var, ft_strlen(var)) == NULL) - i++; - if (envp[i]) - envp[i][0] = '\0'; + if (count_var(arg) == 1) + return (err_msg_cmd("unset", NULL, "not enough arguments", EXIT_FAILURE)); + return (remove_env_var(arg[1], data->env)); } diff --git a/srcs/builtins/utils.c b/srcs/builtins/utils.c new file mode 100644 index 0000000..b34fa9d --- /dev/null +++ b/srcs/builtins/utils.c @@ -0,0 +1,14 @@ +#include "../../includes/builtins.h" + +int err_msg_cmd(char *cmd, char *arg, char *msg, int code) +{ + ft_put_s_fd(cmd, 2); + ft_put_s_fd(": ", 2); + ft_put_s_fd(msg, 2); + if (arg) + { + ft_put_s_fd(": ", 2); + ft_putendl_fd(arg, 2); + } + return (code); +} diff --git a/srcs/env/var.c b/srcs/env/var.c new file mode 100644 index 0000000..7483071 --- /dev/null +++ b/srcs/env/var.c @@ -0,0 +1,159 @@ +#include "../../includes/minishell.h" + +void free_null_ptr(void *ptr) +{ + if (ptr != NULL) + { + free(ptr); + ptr = NULL; + } +} + +char **copy_env_var(char **envp, int count) +{ + char **new_env; + int i; + + i = 0; + new_env = malloc(sizeof(char *) * (count + 1)); + if (!new_env) + return (NULL); + new_env[count] = NULL; + while (envp[i] && i < count) + { + new_env[i] = ft_strdup(envp[i]); + free_null_ptr(envp[i]); + i++; + } + free_null_ptr(envp); + return (new_env); +} + +int count_var(char **envp) +{ + int i; + + i = 0; + if (!envp) + return (-1); + while (envp[i]) + i++; + return (i); +} + +char *get_var_value(char *key, char **envp) +{ + char *tmp; + int i; + + tmp = ft_strjoin(key, "="); + if (!tmp) + return (NULL); + i = 0; + while (envp[i]) + { + if (ft_strncmp(envp[i], tmp, ft_strlen(tmp)) == 0) + { + free_null_ptr(tmp); + return (ft_strchr(envp[i], '=') + 1); + } + i++; + } + free_null_ptr(tmp); + return (NULL); +} + +bool is_valid_key(char *key, char **envp) +{ + char *tmp; + int i; + + tmp = ft_strjoin(key, "="); + if (!tmp) + return (false); + while (envp[i]) + { + if (ft_strncmp(envp[i], tmp, ft_strlen(tmp)) == 0) + { + free_null_ptr(tmp); + return (true); + } + i++; + } + free_null_ptr(tmp); + return (false); +} + +int get_var_index(char *key, char **envp) +{ + int i; + char *new_key; + + new_key = ft_strjoin(key, "="); + if (!new_key) + return (-1); + i = 0; + while (envp[i]) + { + if (ft_strncmp(envp[i], new_key, ft_strlen(new_key)) == 0) + { + free_null_ptr(new_key); + return (i); + } + i++; + } + free_null_ptr(new_key); + return (-1); +} + + +int remove_env_var(char *key, char **envp) +{ + int i; + int j; + + i = get_var_index(key, envp); + if (i == -1) + return (0); + j = i; + free_null_ptr(envp[i]); + while (envp[i + 1]) + { + envp[i] = ft_strdup(envp[i + 1]); + free_null_ptr(envp[i + 1]); + j++; + i++; + } + envp = copy_env_var(envp, j); + if (!envp) + return (1); + return (0); +} + +void set_var_env(char *key, char *value, t_data *data) +{ + int i; + char *tmp; + + i = get_var_index(key, data->env); + if (!value) + value = ""; + tmp = ft_strjoin("=", value); + if (!tmp) + return ; + if (i != -1 && data->env[i]) + { + free_null_ptr(data->env[i]); + data->env[i] = ft_strjoin(key, tmp); + } + else + { + i = count_var(data->env); + data->env = copy_env_var(data->env, i + 1); + if (!data->env) + return ; + data->env[i] = ft_strjoin(key, tmp); + } + free_null_ptr(tmp); + return ; +} diff --git a/srcs/main.c b/srcs/main.c index 7ac9576..370189a 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -10,7 +10,7 @@ char *powerline(void) if (ft_strncmp(pwd, "/home/", 6) == 0) { pwd = pwd + 6; - while ((*pwd) != '/') + while (*pwd && (*pwd) != '/') pwd = pwd + 1; tilt = " ~"; } @@ -40,14 +40,43 @@ char **ft_setnewenv(void) return (envp); } +char **init_env(char **envp) +{ + char **env; + int i; + + i = 0; + env = malloc(sizeof(char *) * (count_var(envp) + 1)); + if (!env) + return (NULL); + env[count_var(envp)] = NULL; + while (envp[i]) + { + env[i] = ft_strdup(envp[i]); + i++; + } + return (env); +} + +t_data *init_data(char **envp) +{ + t_data *data; + + data = malloc (sizeof(t_data)); + data->env = init_env(envp); + return (data); +} + int main(int ac, char **av, char **envp) { char *input; + t_data *data; (void)ac; (void)av; - if (!envp[0]) - envp = ft_setnewenv(); + // if (!envp[0]) + // env = ft_setnewenv(); + data = init_data(envp); while (1) { input = powerline(); @@ -56,15 +85,15 @@ int main(int ac, char **av, char **envp) if (ft_strncmp(input, "pwd", 3) == 0) builtin_pwd(input); if (ft_strncmp(input, "echo", 4) == 0) - builtin_echo(input, envp); + builtin_echo(input, data->env); if (ft_strncmp(input, "env", 3) == 0) - builtin_env(input, envp); + builtin_env(input, data->env); if (ft_strncmp(input, "unset", 5) == 0) - builtin_unset(input, envp); + builtin_unset(ft_split(input, " "), data); if (ft_strncmp(input, "cd", 2) == 0) - envp = builtin_cd(ft_split(input, " "), envp); + builtin_cd(ft_split(input, " "), data); if (ft_strncmp(input, "export", 6) == 0) - envp = builtin_export(ft_split(input, " "), envp); + data->env = builtin_export(ft_split(input, " "), data->env); free(input); } return (0);