From afbb1cd2e0f72a7100b0eef09d0b60a75dfb0136 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 18 Dec 2021 05:42:08 +0100 Subject: [PATCH] shell_script() + reset "rl_event_hook" to NULL after here_doc() + split init.c in multiple files + submodule minishell_tests --- Makefile | 5 +- headers/minishell_prototypes.h | 4 +- minishell_tests | 2 +- srcs/init/handle_argv.c | 62 ++++++++++++++++++++++ srcs/init/init.c | 33 ++++++++++++ srcs/{misc/init.c => init/init_prompt.c} | 67 ++---------------------- srcs/init/init_readline.c | 33 ++++++++++++ srcs/init/init_shlvl.c | 37 +++++++++++++ srcs/main.c | 12 ++--- srcs/shell_loop.c | 6 +-- srcs/shell_script.c | 47 +++++++++++++++-- 11 files changed, 226 insertions(+), 82 deletions(-) create mode 100644 srcs/init/handle_argv.c create mode 100644 srcs/init/init.c rename srcs/{misc/init.c => init/init_prompt.c} (52%) create mode 100644 srcs/init/init_readline.c create mode 100644 srcs/init/init_shlvl.c diff --git a/Makefile b/Makefile index 6f6fdbb..ea641cc 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) DIR_SRCS = srcs \ + srcs/init \ srcs/builtins \ srcs/lexing \ srcs/parsing srcs/parsing/valid_syntax \ @@ -30,7 +31,9 @@ LIBFT = $(LIBFT_D)/libft.a SRCS = main.c \ shell_loop.c shell_script.c \ - init.c retrieve_path.c free.c \ + init.c init_prompt.c init_readline.c init_shlvl.c handle_argv.c \ + retrieve_path.c \ + free.c \ signals.c error_wrappers.c last_exit_status.c \ lexing.c fill_token.c check_operators.c \ parsing.c create_pipeline.c \ diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index b9d2944..2ea0fab 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/12/16 06:35:04 by lperrey ### ########.fr */ +/* Updated: 2021/12/17 21:16:53 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,7 @@ int g_switch_heredoc_sigint; extern char **environ; // Init -int init(t_all *c); +int init(t_all *c, char *argv[]); char *init_prompt(char *prompt_base); char **retrieve_path(void); void set_signals_behaviour(void); diff --git a/minishell_tests b/minishell_tests index 427cec8..21c56c3 160000 --- a/minishell_tests +++ b/minishell_tests @@ -1 +1 @@ -Subproject commit 427cec8cb4dc9cbd7fd963a443160bdd31683519 +Subproject commit 21c56c3985a5af91731cfeef40690d767841f4d0 diff --git a/srcs/init/handle_argv.c b/srcs/init/handle_argv.c new file mode 100644 index 0000000..59f64b8 --- /dev/null +++ b/srcs/init/handle_argv.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* handle_argv.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ +/* Updated: 2021/12/18 04:46:05 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int remap_stdin_to_script_file(char *script_file); +char *init_prompt_base(void); + +int handle_argv(t_all *c, char *argv[]) +{ + int ret; + + if (argv[1]) + { + ret = remap_stdin_to_script_file(argv[1]); + if (ret) + exit_free(c, ret); + } + else if (isatty(STDIN_FILENO)) + { + c->prompt_base = init_prompt_base(); + if (!c->prompt_base) + return (ft_reti_perror(0, "init_prompt_base()")); + c->prompt = init_prompt(c->prompt_base); + if (!c->prompt) + return (ft_reti_perror(0, "init_prompt()")); + } + return (1); +} + +int remap_stdin_to_script_file(char *script_file) +{ + int fd; + int ret; + int tmp; + + fd = open(script_file, O_RDONLY); + if (fd == -1) + { + shell_perror(script_file, ": ", "", 0); + return (EXIT_CMD_NOT_FOUND); + } + ret = dup2(fd, STDIN_FILENO); + tmp = errno; + if (close(fd) == -1) + perror("close()"); + if (ret == -1) + { + errno = tmp; + return (ft_reti_perror(EXIT_FAILURE, "dup2()")); + } + return (0); +} diff --git a/srcs/init/init.c b/srcs/init/init.c new file mode 100644 index 0000000..70277fc --- /dev/null +++ b/srcs/init/init.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ +/* Updated: 2021/12/18 04:53:11 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void init_readline(void); +int init_shlvl(void); +int handle_argv(t_all *c, char *argv[]); + +int init(t_all *c, char *argv[]) +{ + ft_bzero(c, sizeof (*c)); + init_readline(); + environ = ft_dup_2d_arr(environ, (t_dup_f)ft_strdup); + if (!environ) + return (ft_reti_perror(0, "ft_dup_2d_arr(environ)")); + c->path = retrieve_path(); + if (!init_shlvl()) + return (ft_reti_perror(0, "init_shlvl()")); + if (!handle_argv(c, argv)) + return (0); + set_signals_behaviour(); + return (1); +} diff --git a/srcs/misc/init.c b/srcs/init/init_prompt.c similarity index 52% rename from srcs/misc/init.c rename to srcs/init/init_prompt.c index 003253b..4ff91e1 100644 --- a/srcs/misc/init.c +++ b/srcs/init/init_prompt.c @@ -1,69 +1,18 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* init.c :+: :+: :+: */ +/* init_prompt.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/12/08 21:54:36 by lperrey ### ########.fr */ +/* Updated: 2021/12/18 04:28:46 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static char *init_prompt_base(void); -static int init_readline_hook(void); -static int shlvl_init(void); - -int init(t_all *c) -{ - ft_bzero(c, sizeof (*c)); - rl_outstream = stderr; - rl_startup_hook = init_readline_hook; - readline(NULL); - rl_startup_hook = NULL; - environ = ft_dup_2d_arr(environ, (t_dup_f)ft_strdup); - if (!environ) - return (ft_reti_perror(0, "ft_dup_2d_arr(environ)")); - c->path = retrieve_path(); - if (!shlvl_init()) - return (ft_reti_perror(0, "shlvl_init()")); - c->prompt_base = init_prompt_base(); - if (!c->prompt_base) - return (ft_reti_perror(0, "init_prompt_base()")); - c->prompt = init_prompt(c->prompt_base); - if (!c->prompt) - return (ft_reti_perror(0, "init_prompt()")); - set_signals_behaviour(); - return (1); -} - -static int shlvl_init(void) -{ - char *tmp; - int ret; - - tmp = getenv("SHLVL"); - if (tmp && ft_isdigit_str(tmp)) - { - tmp = ft_itoa(ft_atoi(tmp) + 1); - if (!tmp) - return (0); - tmp = ft_strjoinfree_s2("SHLVL=", tmp); - if (!tmp) - return (0); - ret = export_var(tmp); - free(tmp); - } - else - ret = export_var("SHLVL=1"); - if (ret == -1) - return (0); - return (1); -} - -static char *init_prompt_base(void) +char *init_prompt_base(void) { char *prompt_base; char *tmp; @@ -103,13 +52,3 @@ char *init_prompt(char *prompt_base) return (NULL); return (prompt); } - -/* -** set rl_startup_hook with this, for init COLUMNS and LINES variables -** and prevent leak/double_free with **environ -*/ -static int init_readline_hook(void) -{ - rl_done = 1; - return (0); -} diff --git a/srcs/init/init_readline.c b/srcs/init/init_readline.c new file mode 100644 index 0000000..3666c7c --- /dev/null +++ b/srcs/init/init_readline.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_readline.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ +/* Updated: 2021/12/18 04:31:59 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int init_readline_hook(void); + +void init_readline(void) +{ + rl_outstream = stderr; + rl_startup_hook = init_readline_hook; + readline(NULL); + rl_startup_hook = NULL; +} + +/* +** set rl_startup_hook with this, for init COLUMNS and LINES variables +** and prevent leak/double_free with **environ +*/ +static int init_readline_hook(void) +{ + rl_done = 1; + return (0); +} diff --git a/srcs/init/init_shlvl.c b/srcs/init/init_shlvl.c new file mode 100644 index 0000000..1944284 --- /dev/null +++ b/srcs/init/init_shlvl.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* init_shlvl.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ +/* Updated: 2021/12/18 04:35:33 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int init_shlvl(void) +{ + char *tmp; + int ret; + + tmp = getenv("SHLVL"); + if (tmp && ft_isdigit_str(tmp)) + { + tmp = ft_itoa(ft_atoi(tmp) + 1); + if (!tmp) + return (0); + tmp = ft_strjoinfree_s2("SHLVL=", tmp); + if (!tmp) + return (0); + ret = export_var(tmp); + free(tmp); + } + else + ret = export_var("SHLVL=1"); + if (ret == -1) + return (0); + return (1); +} diff --git a/srcs/main.c b/srcs/main.c index e28ea1c..8ad47bd 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/11/29 12:43:34 by lperrey ### ########.fr */ +/* Updated: 2021/12/18 05:08:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,13 +17,11 @@ int main(int argc, char *argv[]) t_all c; (void)argc; - (void)argv; - if (!init(&c)) + if (!init(&c, argv)) exit_free(&c, EXIT_FAILURE); - //putenv("VAR=W1 W2 W3"); // TEMP TEST -// if (argv[1] || !isatty(STDIN_FILENO)) -// shell_script(&c); -// else + if (!isatty(STDIN_FILENO)) + shell_script(&c); + else shell_loop(&c); return (0); } diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 7b1055d..bc5bbac 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/12/01 14:45:04 by lperrey ### ########.fr */ +/* Updated: 2021/12/18 03:24:54 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,8 +21,7 @@ void shell_loop(t_all *c) line_input = NULL; while (1) { - if (line_input) - free(line_input); + free(line_input); line_input = read_input(c->prompt, c); if (line_input && *line_input) { @@ -48,6 +47,7 @@ static char *read_input(char *prompt, t_all *c) ft_bzero(&signal_behaviour, sizeof signal_behaviour); signal_behaviour.sa_handler = sigint_handler_interactive; sigaction(SIGINT, &signal_behaviour, NULL); + rl_event_hook = NULL; line_input = readline(prompt); signal_behaviour.sa_handler = SIG_IGN; sigaction(SIGINT, &signal_behaviour, NULL); diff --git a/srcs/shell_script.c b/srcs/shell_script.c index 7790cfb..e82480a 100644 --- a/srcs/shell_script.c +++ b/srcs/shell_script.c @@ -6,14 +6,53 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/26 23:47:44 by lperrey #+# #+# */ -/* Updated: 2021/11/29 12:43:44 by lperrey ### ########.fr */ +/* Updated: 2021/12/18 05:29:27 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -void shell_script(t_all *c) // WIP +static char *read_input_script(t_all *c); + +void shell_script(t_all *c) { - ft_putstr_fd("Shell Script Placeholder\n", 1); - exit_free(c, EXIT_SUCCESS); + char *line_input; + + line_input = NULL; + while (1) + { + free(line_input); + line_input = read_input_script(c); + if (line_input && *line_input) + { + c->token_list = lexing(line_input); + ft_free_null(&line_input); + if (!c->token_list) + break ; + c->pipeline = parsing(c->token_list); + ft_lstclear((t_list **)&c->token_list, free); + if (!c->pipeline) + break ; + exec_cmd_line(c); + } + } + free(line_input); + exit_free(c, get_last_exit_status()); +} + +static char *read_input_script(t_all *c) +{ + char *line_input; + struct sigaction signal_behaviour; + + ft_bzero(&signal_behaviour, sizeof signal_behaviour); + signal_behaviour.sa_handler = sigint_handler_interactive; + sigaction(SIGINT, &signal_behaviour, NULL); + rl_event_hook = NULL; + line_input = readline(NULL); + signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &signal_behaviour, NULL); + if (!line_input) + exit_free(c, get_last_exit_status()); + return (line_input); }