diff --git a/42sh/includes/builtin.h b/42sh/includes/builtin.h index 95e58934..e20e019b 100644 --- a/42sh/includes/builtin.h +++ b/42sh/includes/builtin.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/14 22:59:57 by jhalford #+# #+# */ -/* Updated: 2017/03/25 01:55:42 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 02:18:19 by jhalford ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,9 +17,6 @@ # include "libft.h" # include "builtin_read.h" -# define BT_ENV_LI (1 << 0) -# define BT_ENV_LU (1 << 1) - struct s_env_data { t_flag flag; @@ -34,6 +31,8 @@ int builtin_return_status(int ret, int status); int builtin_export(const char *path, char *const av[], char *const envp[]); int builtin_unset(const char *path, char *const av[], char *const envp[]); int builtin_env(const char *path, char *const argv[], char *const envp[]); +int bt_env_opt_u(char *opt_arg, t_env_data *data); +int bt_env_opt_i(char *opt_arg, t_env_data *data); int builtin_echo(const char *path, char *const argv[], char *const envp[]); int builtin_cd(const char *path, char *const argv[], char *const envp[]); int builtin_exit(const char *path, char *const argv[], char *const envp[]); diff --git a/42sh/includes/builtin_read.h b/42sh/includes/builtin_read.h index 61d5aa02..544da046 100644 --- a/42sh/includes/builtin_read.h +++ b/42sh/includes/builtin_read.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/20 15:02:39 by jhalford #+# #+# */ -/* Updated: 2017/03/22 18:36:44 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:24:42 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,10 +50,10 @@ struct termios bt_read_term(int init); int bt_read_terminit(t_read *data); int bt_read_exit(t_read *data); -int bt_read_getdelim(char ***argv, t_read *data); -int bt_read_getnchars(char ***argv, t_read *data); -int bt_read_getprompt(char ***argv, t_read *data); -int bt_read_gettimeout(char ***argv, t_read *data); -int bt_read_getfd(char ***argv, t_read *data); +int bt_read_getdelim(char *opt_arg, t_read *data); +int bt_read_getnchars(char *opt_arg, t_read *data); +int bt_read_getprompt(char *opt_arg, t_read *data); +int bt_read_gettimeout(char *opt_argv, t_read *data); +int bt_read_getfd(char *opt_arg, t_read *data); #endif diff --git a/42sh/includes/minishell.h b/42sh/includes/minishell.h index 5e94eeb3..88ce279d 100644 --- a/42sh/includes/minishell.h +++ b/42sh/includes/minishell.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/10 13:07:44 by jhalford #+# #+# */ -/* Updated: 2017/03/24 17:11:16 by wescande ### ########.fr */ +/* Updated: 2017/03/25 01:41:33 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,7 +61,7 @@ int shell_init(int ac, char **av, char **env); void shell_exit(void); int data_init(int ac, char **av, char **env); void data_exit(void); -int get_c_arg(char ***av, t_data *data); +int get_c_arg(char *opt_arg, t_data *data); void shell_resetfds(void); void shell_resetsig(void); diff --git a/42sh/libft/includes/cliopts.h b/42sh/libft/includes/cliopts.h index ad5687ab..0271655d 100644 --- a/42sh/libft/includes/cliopts.h +++ b/42sh/libft/includes/cliopts.h @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/14 20:22:56 by jhalford #+# #+# */ -/* Updated: 2017/03/24 23:20:58 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:18:54 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,6 +27,7 @@ struct s_cliopts t_flag flag_on; t_flag flag_off; int (*get)(); + int arg_required:1; }; struct s_data_template diff --git a/42sh/libft/src/cliopts/cliopts_get.c b/42sh/libft/src/cliopts/cliopts_get.c index 12c317f1..49aead82 100644 --- a/42sh/libft/src/cliopts/cliopts_get.c +++ b/42sh/libft/src/cliopts/cliopts_get.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/14 20:04:04 by jhalford #+# #+# */ -/* Updated: 2017/03/25 00:03:30 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 02:02:09 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,13 +17,29 @@ #include "cliopts.h" +static char *check_required(char ***av, char *arg) +{ + char *ret; + + DG("%p, av", av); + DG("%p, *av", *av); + DG("%p, arg", arg); + DG("%s, *arg", arg); + if (!av || !*av) + return (NULL); + if (!arg || !*arg || !*(arg + 1)) + return (*++(*av)); + ret = arg + 1; + return (ret); +} + static t_cliopts *get_map_long(t_cliopts opt_map[], char *arg) { int i; i = -1; while (opt_map[++i].c) - if (ft_strcmp(opt_map[i].str, arg) == 0) + if (!ft_strcmp(opt_map[i].str, arg)) return (&opt_map[i]); return (NULL); } @@ -45,27 +61,28 @@ static int cliopts_parse_short( t_cliopts *map; char *arg; int i; + char *tmp; arg = **av + 1; - i = 0; - while (arg[i]) + i = -1; + while (arg[++i] && !(tmp = NULL)) { if (!(map = get_map_short(opt_map, arg[i]))) return (ERR_SET(E_CO_INV, arg[i])); if (map->get) { - if (!(arg[i - 1] == '-' && arg[i + 1] == 0)) - return (ERR_SET(E_CO_MULT, *arg)); - ++(*av); - if ((map->get)(av, data)) + if (map->arg_required && !(tmp = check_required(av, arg + i))) return (ERR_SET(E_CO_MISS, *arg)); + tmp = tmp ? tmp : **av; + if ((map->get)(tmp, data)) + return (ERR_SET(E_CO_MISS, *arg)); + if (map->arg_required) + break ; } ((t_data_template*)data)->flag |= map->flag_on; ((t_data_template*)data)->flag &= ~map->flag_off; - i++; } - ++(*av); - return (0); + return (++(*av) ? 0 : 0); } static int cliopts_parse_long( @@ -73,16 +90,19 @@ static int cliopts_parse_long( { t_cliopts *map; char *arg; + char *tmp; arg = **av + 2; + tmp = NULL; if (!(map = get_map_long(opt_map, arg))) return (ERR_SET(E_CO_INVL, arg)); ((t_data_template*)data)->flag |= map->flag_on; ((t_data_template*)data)->flag &= ~map->flag_off; if (map->get) { - ++(*av); - if ((map->get)(av, data)) + if (map->arg_required && !(tmp = check_required(av, NULL))) + return (ERR_SET(E_CO_MISS, *arg)); + if ((map->get)(tmp, data)) return (ERR_SET(E_CO_MISSL, arg)); } ++(*av); diff --git a/42sh/libft/src/sstr/ft_sstrdel.c b/42sh/libft/src/sstr/ft_sstrdel.c index de2fd4c4..403fcf00 100644 --- a/42sh/libft/src/sstr/ft_sstrdel.c +++ b/42sh/libft/src/sstr/ft_sstrdel.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/11/03 18:04:07 by jhalford #+# #+# */ -/* Updated: 2017/03/23 18:31:06 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:38:51 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,10 +17,10 @@ void ft_sstrdel(char **sstr, int index) int i; i = index; - free(sstr[index]); - while (sstr[i]) + ft_strdel(&sstr[index]); + while (i == index || sstr[i]) { sstr[i] = sstr[i + 1]; - i++; + ++i; } } diff --git a/42sh/src/builtin/bt_read_get.c b/42sh/src/builtin/bt_read_get.c index 60463fd3..87af8771 100644 --- a/42sh/src/builtin/bt_read_get.c +++ b/42sh/src/builtin/bt_read_get.c @@ -6,53 +6,53 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/21 18:00:03 by jhalford #+# #+# */ -/* Updated: 2017/03/21 15:52:26 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:27:06 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -int bt_read_getdelim(char ***av, t_read *data) +int bt_read_getdelim(char *opt_arg, t_read *data) { - if (!av || !*av) + if (!opt_arg) return (1); if (data) - data->delim = ***av; + data->delim = *opt_arg; return (0); } -int bt_read_getnchars(char ***av, t_read *data) +int bt_read_getnchars(char *opt_arg, t_read *data) { - if (!av || !*av) + if (!opt_arg) return (1); if (data) - data->nchars = ft_atoi(**av); + data->nchars = ft_atoi(opt_arg); return (0); } -int bt_read_getprompt(char ***av, t_read *data) +int bt_read_getprompt(char *opt_arg, t_read *data) { - if (!av || !*av || !**av) + if (!opt_arg) return (1); if (data) - data->prompt = **av; + data->prompt = opt_arg; return (0); } -int bt_read_gettimeout(char ***av, t_read *data) +int bt_read_gettimeout(char *opt_arg, t_read *data) { - if (!av || !*av) + if (!opt_arg) return (1); if (data) - data->timeout = ft_atoi(**av); + data->timeout = ft_atoi(opt_arg); return (0); } -int bt_read_getfd(char ***av, t_read *data) +int bt_read_getfd(char *opt_arg, t_read *data) { - if (!av || !*av) + if (!opt_arg) return (1); if (data) - data->fd = ft_atoi(**av); + data->fd = ft_atoi(opt_arg); return (0); } diff --git a/42sh/src/builtin/builtin_cd.c b/42sh/src/builtin/builtin_cd.c index b0e75244..58c7c548 100644 --- a/42sh/src/builtin/builtin_cd.c +++ b/42sh/src/builtin/builtin_cd.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/03 11:57:53 by jhalford #+# #+# */ -/* Updated: 2017/03/25 00:52:32 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:20:39 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,9 +21,9 @@ static t_cliopts g_cdopts[] = { - {'P', NULL, BT_CD_P, BT_CD_L, NULL}, - {'L', NULL, BT_CD_L, BT_CD_P, NULL}, - {0, NULL, 0, 0, NULL}, + {'P', NULL, BT_CD_P, BT_CD_L, NULL, 0}, + {'L', NULL, BT_CD_L, BT_CD_P, NULL, 0}, + {0, NULL, 0, 0, NULL, 0}, }; static char *bt_cd_target(char *arg) diff --git a/42sh/src/builtin/builtin_env.c b/42sh/src/builtin/builtin_env.c index 7fd7a27e..fbb147c2 100644 --- a/42sh/src/builtin/builtin_env.c +++ b/42sh/src/builtin/builtin_env.c @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/22 16:20:31 by gwojda #+# #+# */ -/* Updated: 2017/03/24 23:22:19 by ariard ### ########.fr */ +/* Updated: 2017/03/25 02:10:38 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,14 +15,42 @@ #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" +/* # define BT_ENV_LI (1 << 0) */ +/* # define BT_ENV_LU (1 << 1) */ -t_cliopts g_env_opts[] = +static t_cliopts g_env_opts[] = { - {'i', NULL, BT_ENV_LI, 0, NULL}, - {0, 0, 0, 0, 0}, + {'i', NULL, 0, 0, &bt_env_opt_i, 0}, + {'u', NULL, 0, 0, &bt_env_opt_u, 1}, + {0, 0, 0, 0, 0, 0}, }; -int bt_env_getcustom(char ***av, t_env_data *data) +int bt_env_opt_i(char *opt_arg, t_env_data *data) +{ + (void)opt_arg; + ft_tabdel(&data->custom_env); + return (0); +} + +int bt_env_opt_u(char *opt_arg, t_env_data *data) +{ + DG(); + int i; + char **env; + + if (!(env = data->custom_env)) + return (0); + i = -1; + while (env[++i]) + { + if (ft_strcmp(env[i], opt_arg) == '=' + && ft_strlen(opt_arg) == ft_strlenchr(env[i], '=')) + ft_sstrdel(env, i); + } + return (0); +} + +static int bt_env_getcustom(char ***av, t_env_data *data) { if (!av || !*av || !data) return (1); @@ -34,56 +62,51 @@ int bt_env_getcustom(char ***av, t_env_data *data) return (0); } -static int bt_env_parse(t_env_data *data, char **av) +static int bt_env_parse(t_env_data *data, char **av) { data->flag = 0; data->av_data = NULL; - DG(); + data->custom_env = ft_sstrdup(data_singleton()->env); if (cliopts_get(av, g_env_opts, data)) return (1); - DG(); - data->custom_env = NULL; bt_env_getcustom(&data->av_data, data); - DG(); - if (!(data->flag & BT_ENV_LI)) - { - DG("no -i"); - data->custom_env = ft_sstrmerge(data_singleton()->env, data->custom_env); - } - DG(); return (0); } -int builtin_env(const char *path, +int display_env(char **av) +{ + if (av && *av) + { + ft_sstrprint(av, '\n'); + ft_putchar('\n'); + ft_tabdel(&av); + } + return (0); +} + +int builtin_env(const char *path, char *const argv[], char *const envp[]) { - t_env_data data; + t_env_data dat; int status; pid_t pid; - struct stat buf; (void)envp; - if (bt_env_parse(&data, (char**)argv)) + if (bt_env_parse(&dat, (char**)argv)) return (ft_perror("env") && SH_ERR("usage: %s", ENV_USAGE)); - if (!*data.av_data) - { - ft_sstrprint(data.custom_env, '\n'); - ft_putchar('\n'); - return (0); - } + if (!*dat.av_data) + return (display_env(dat.custom_env)); else if ((pid = fork()) == 0) { - 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 (!(path = ft_strchr(dat.av_data[0], '/') ? ft_strdup(dat.av_data[0]) + : ft_hash(dat.av_data[0])) || access(path, F_OK) != 0) + exit(SH_ERR(ENV_NOFILE, dat.av_data[0])); + if (is_directory(path) || access(path, X_OK) != 0) + exit(SH_ERR(ENV_NOPERM, dat.av_data[0])); + execve(path, dat.av_data, dat.custom_env); } waitpid(pid, &status, 0); - ft_sstrfree(data.custom_env); + ft_sstrfree(dat.custom_env); tcsetpgrp(STDIN, data_singleton()->jobc.shell_pgid); - return (0); + return (WIFEXITED(status) ? WEXITSTATUS(status) : 128 + WTERMSIG(status)); } diff --git a/42sh/src/builtin/builtin_export.c b/42sh/src/builtin/builtin_export.c index 04021737..f663e725 100644 --- a/42sh/src/builtin/builtin_export.c +++ b/42sh/src/builtin/builtin_export.c @@ -6,7 +6,7 @@ /* By: gwojda +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/02/15 11:39:37 by gwojda #+# #+# */ -/* Updated: 2017/03/25 00:57:26 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:39:34 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,8 +17,8 @@ static t_cliopts g_export_opts[] = { - {'p', NULL, BT_EXPORT_LP, 0, NULL}, - {0, NULL, 0, 0, NULL}, + {'p', NULL, BT_EXPORT_LP, 0, NULL, 0}, + {0, NULL, 0, 0, NULL, 0}, }; int bt_export_print(void) diff --git a/42sh/src/builtin/builtin_read.c b/42sh/src/builtin/builtin_read.c index 899b4f80..4a65f6c9 100644 --- a/42sh/src/builtin/builtin_read.c +++ b/42sh/src/builtin/builtin_read.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/01/20 15:01:45 by jhalford #+# #+# */ -/* Updated: 2017/03/24 23:30:45 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:28:33 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,14 +17,14 @@ t_cliopts g_read_opts[] = { - {'d', NULL, BT_READ_LD, 0, bt_read_getdelim}, - {'n', NULL, BT_READ_LN, 0, bt_read_getnchars}, - {'p', NULL, BT_READ_LP, 0, bt_read_getprompt}, - {'r', NULL, BT_READ_LR, 0, NULL}, - {'s', NULL, BT_READ_LS, 0, NULL}, - {'t', NULL, BT_READ_LT, 0, bt_read_gettimeout}, - {'u', NULL, BT_READ_LU, 0, bt_read_getfd}, - {0, 0, 0, 0, 0}, + {'d', NULL, BT_READ_LD, 0, bt_read_getdelim, 1}, + {'n', NULL, BT_READ_LN, 0, bt_read_getnchars, 1}, + {'p', NULL, BT_READ_LP, 0, bt_read_getprompt, 1}, + {'r', NULL, BT_READ_LR, 0, NULL, 0}, + {'s', NULL, BT_READ_LS, 0, NULL, 0}, + {'t', NULL, BT_READ_LT, 0, bt_read_gettimeout, 1}, + {'u', NULL, BT_READ_LU, 0, bt_read_getfd, 1}, + {0, 0, 0, 0, 0, 0}, }; int bt_read_init(t_read *data, char **av) diff --git a/42sh/src/job_control/builtin_jobs.c b/42sh/src/job_control/builtin_jobs.c index be9419c5..640fbdf4 100644 --- a/42sh/src/job_control/builtin_jobs.c +++ b/42sh/src/job_control/builtin_jobs.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/15 17:43:01 by jhalford #+# #+# */ -/* Updated: 2017/03/25 00:58:09 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 02:17:23 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,8 +16,8 @@ t_cliopts g_jobs_opts[] = { - {'l', NULL, JOBS_OPT_L, 0, NULL}, - {0, 0, 0, 0, 0}, + {'l', NULL, JOBS_OPT_L, 0, NULL, 0}, + {0, 0, 0, 0, 0, 0}, }; static void bt_jobs_all(int opts) diff --git a/42sh/src/main/shell_init.c b/42sh/src/main/shell_init.c index 45d9092c..dc2bd6b8 100644 --- a/42sh/src/main/shell_init.c +++ b/42sh/src/main/shell_init.c @@ -6,7 +6,7 @@ /* By: jhalford +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2016/12/12 17:23:59 by jhalford #+# #+# */ -/* Updated: 2017/03/24 18:57:17 by jhalford ### ########.fr */ +/* Updated: 2017/03/25 01:41:36 by wescande ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,17 +15,17 @@ static t_cliopts g_opts[] = { - {'c', NULL, SH_OPTS_LC, SH_OPTS_JOBC | SH_INTERACTIVE, get_c_arg}, - {-1, "no-jobcontrol", 0, SH_OPTS_JOBC, NULL}, - {0, 0, 0, 0, 0}, + {'c', NULL, SH_OPTS_LC, SH_OPTS_JOBC | SH_INTERACTIVE, get_c_arg, 1}, + {-1, "no-jobcontrol", 0, SH_OPTS_JOBC, NULL, 0}, + {0, 0, 0, 0, 0, 0}, }; -int get_c_arg(char ***av, t_data *data) +int get_c_arg(char *opt_arg, t_data *data) { - if (!av || !*av) + if (!opt_arg) return (1); if (data) - data->c_arg = **av; + data->c_arg = opt_arg; return (0); }