From 36040d152aff9e40d18d7359431d41c37cf179e8 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Tue, 21 Mar 2017 22:08:27 +0100 Subject: [PATCH] builtin_env seems stable, gonna merge --- 42sh/includes/builtin.h | 13 +++ 42sh/src/builtin/builtin_env.c | 156 ++++++++++---------------------- 42sh/src/builtin/builtin_read.c | 8 +- 3 files changed, 63 insertions(+), 114 deletions(-) diff --git a/42sh/includes/builtin.h b/42sh/includes/builtin.h index 17a22131..094bc086 100644 --- a/42sh/includes/builtin.h +++ b/42sh/includes/builtin.h @@ -19,6 +19,18 @@ # define BT_EXPORT_LP (1 << 0) +# define BT_ENV_LI (1 << 0) +# define BT_ENV_LU (1 << 1) + +struct s_env_data +{ + t_flag flag; + char **av_data; + char **custom_env; +}; + +typedef struct s_env_data t_env_data; + t_execf *is_builtin(t_process *p); int builtin_return_status(int ret, int status); int builtin_export(const char *path, char *const av[], char *const envp[]); @@ -38,6 +50,7 @@ int builtin_history(const char *path, char *const av[], char *const envp[]); int builtin_hash(const char *path, char *const av[], char *const envp[]); int builtin_math(const char *path, char *const av[], char *const envp[]); +int bt_env_geti(char ***av, t_env_data *data); int error_msg(char *msg); #endif diff --git a/42sh/src/builtin/builtin_env.c b/42sh/src/builtin/builtin_env.c index 15ef430c..f52a8080 100644 --- a/42sh/src/builtin/builtin_env.c +++ b/42sh/src/builtin/builtin_env.c @@ -1,124 +1,64 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* builtin_env.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: jhalford +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/11/28 14:14:20 by jhalford #+# #+# */ -/* Updated: 2017/03/21 18:41:06 by jhalford ### ########.fr */ -/* */ -/* ************************************************************************** */ - #include "minishell.h" -#define US_ENV "env [-i] [-u name] [name=value]... [utility [argument...]]" -static int env_usage(int arg_miss, char c) +#define ENV_USAGE "env [-i] [name=value]... [utility [argument...]]" +#define ENV_NOFILE "env: %s: No such file or directory" +#define ENV_NOPERM "env: %s: Permission denied" + +t_cliopts g_env_opts[] = { - if (arg_miss) - SH_ERR("env: option requires an argument -- u"); - else if (c) - SH_ERR("env: illegal option -- %c", c); - SH_ERR("usage: %s", US_ENV); - return (1); + {'i', NULL, BT_ENV_LI, 0, bt_env_geti}, + {0, 0, 0, 0, 0}, +}; + +int bt_env_geti(char ***av, t_env_data *data) +{ + if (!av || !*av || !data) + return (1); + while (**av && ft_strchr(**av, '=')) + { + data->custom_env = ft_sstradd(data->custom_env, **av); + ++(*av); + } + --(*av); + return (0); } -static void env_freeone(char **env, char *arg) +static int bt_env_parse(t_env_data *data, char **av) { - int i; - char *tmp; - - while (env && *env && (i = -1)) - { - if (ft_strcmp(*env, arg) == '=' - && ft_strlen(arg) == ft_strlenchr(*env, '=')) - { - tmp = *env; - while (*env) - { - *env = *(env + 1); - ++env; - } - ft_strdel(&tmp); - return ; - } - ++env; - } -} - -static void env_replace(char ***custom_env, char *arg) -{ - char **arg_split; - - if ((arg_split = ft_strsplit(arg, '='))) - { - env_freeone(*custom_env, *arg_split); - ft_tabdel(&arg_split); - } - *custom_env = ft_sstradd(*custom_env, arg); -} - -static int env_treat_flag(char ***custom_env, char *const *arg[]) -{ - char *tmp; - - while (*(++*arg)) - { - if (!ft_strcmp(**arg, "-i")) - { - tmp = ft_strjoin("PATH=", ft_getenv(*custom_env, "PATH")); - ft_tabdel(custom_env); - *custom_env = ft_sstradd(NULL, tmp); - ft_strdel(&tmp); - } - else if (!ft_strcmp(**arg, "-u")) - { - ++*arg; - if (**arg) - env_freeone(*custom_env, **arg); - else - return (env_usage(1, 0)); - } - else if (ft_strchr(**arg, '=')) - env_replace(custom_env, **arg); - else if (!ft_strcmp(**arg, "--")) - { - ++*arg; - return (0); - } - else if ((**arg)[0] == '-') - return (env_usage(0, (**arg)[1])); - else - return (0); - } + data->flag = 0; + data->av_data = NULL; + data->custom_env = NULL; + if (cliopts_get(av, g_env_opts, data)) + return (1); return (0); } int builtin_env(const char *path, char *const argv[], char *const envp[]) { - char **env; - pid_t pid; + t_env_data data; + int status; + pid_t pid; + struct stat buf; - (void)path; - pid = 0; - if (!argv || ft_strcmp(*argv, "env")) - return (builtin_return_status(0, env_usage(0, 0))); - env = ft_sstrdup((char **)envp); - if (env_treat_flag(&env, &argv)) + (void)envp; + if (bt_env_parse(&data, (char**)argv)) + return (ft_perror() && SH_ERR("usage: %s", ENV_USAGE) ? 0 : 0); + else if (!*data.av_data) + return (builtin_setenv(NULL, (char*[]){"setenv", 0}, NULL)); + else if ((pid = fork()) == 0) { - ft_sstrfree(env); - return (builtin_return_status(0, 1)); + if (!(path = ft_strchr(data.av_data[0], '/') ? + ft_strdup(data.av_data[0]) : ft_hash(data.av_data[0])) + || access(path, F_OK) != 0) + exit (SH_ERR(ENV_NOFILE, data.av_data[0])); + stat(path, &buf); + if (S_ISDIR(buf.st_mode) || access(path, X_OK) != 0) + exit (SH_ERR(ENV_NOPERM, data.av_data[0])); + execve(path, data.av_data, data.custom_env); } - if (!*argv) - { - ft_sstrprint(env, '\n'); - if (env) - ft_putchar('\n'); - } - else - pid = command_setoutput(argv, env); - ft_tabdel(&env); - DG("%d", pid); - return (builtin_return_status(pid, 0)); + waitpid(pid, &status, 0); + ft_sstrfree(data.custom_env); + return (0); + /* return (builtin_return_status(pid, 0)); */ } diff --git a/42sh/src/builtin/builtin_read.c b/42sh/src/builtin/builtin_read.c index a7a4edf1..d5edb32c 100644 --- a/42sh/src/builtin/builtin_read.c +++ b/42sh/src/builtin/builtin_read.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + #define US_READ "read [-ers] [-u fd] [-t timeout] [-p prompt]" #define US_READ_1 "[-n nchars] [-d delim] [name ...]" @@ -26,11 +27,6 @@ t_cliopts g_read_opts[] = {0, 0, 0, 0, 0}, }; -void bt_read_usage(void) -{ - SH_ERR("usage: read %s %s\n", US_READ, US_READ_1); -} - int bt_read_init(t_read *data, char **av) { data->opts = 0; @@ -115,7 +111,7 @@ int builtin_read(const char *path, char *const av[], char *const envp[]) if (ret == -1) exit(1); if (ret != 0) - bt_read_usage(); + SH_ERR("usage: read %s %s\n", US_READ, US_READ_1); if (ret != 2) bt_read_exit(&data); return (builtin_return_status(0, ret));