From 31435865aa5e67c7a683e90da2adafba692c5eab Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:52:41 +0200 Subject: [PATCH 1/6] improve: Add to history only in interactive mode --- source/utils/user_input_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utils/user_input_utils.c b/source/utils/user_input_utils.c index a257a8c3..77d8fa1d 100644 --- a/source/utils/user_input_utils.c +++ b/source/utils/user_input_utils.c @@ -38,7 +38,7 @@ bool read_input( errno = SUCCESS; else if (errno != SUCCESS) return (false); - if (add_to_history && *line && **line) + if (add_to_history && is_interactive && *line && **line) add_history(*line); return (errno == SUCCESS); } From 8f534b8aea096dc26c75f15dabef42cee0e135b3 Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:03:01 +0200 Subject: [PATCH 2/6] fix: Prevent infinite input loop if readline is used non-interactively --- source/utils/user_input_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/utils/user_input_utils.c b/source/utils/user_input_utils.c index 77d8fa1d..e8bf70d1 100644 --- a/source/utils/user_input_utils.c +++ b/source/utils/user_input_utils.c @@ -34,7 +34,7 @@ bool read_input( free(tmp); } } - if (errno == EINTR) + if (errno == EINTR || errno == ENOTTY) errno = SUCCESS; else if (errno != SUCCESS) return (false); From ea50c1db8d01de8aaf2605c3e9b644f5ef7ccf1a Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:19:51 +0200 Subject: [PATCH 3/6] fix: Limit retries of getting user input after failure --- include/utils.h | 4 ++-- source/backend/redirection/heredoc.c | 2 +- source/main.c | 2 +- source/utils/user_input_utils.c | 32 +++++++++++++++++++++------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/include/utils.h b/include/utils.h index 7c9849a3..b0b9fe7e 100644 --- a/include/utils.h +++ b/include/utils.h @@ -18,9 +18,9 @@ /* User input utils */ bool read_input( char **line, + t_sh *shell, char *prompt, - bool add_to_history, - bool is_interactive); + bool add_to_history); /* Token list utils */ t_tok *init_token(t_tok_typ type, char *data); diff --git a/source/backend/redirection/heredoc.c b/source/backend/redirection/heredoc.c index 9a78146d..6e1f18b1 100644 --- a/source/backend/redirection/heredoc.c +++ b/source/backend/redirection/heredoc.c @@ -109,7 +109,7 @@ static t_hd_st read_heredoc(t_sh *shell, t_list **line_list, char *here_end) while (true) { line = NULL; - if (!read_input(&line, HEREDOC_PROMPT, false, shell->is_interactive)) + if (!read_input(&line, shell, HEREDOC_PROMPT, false)) return (free(line), HD_ERROR); if (shell->exit_code == TERM_BY_SIGNAL + SIGINT) return (free(line), HD_ABORT); diff --git a/source/main.c b/source/main.c index 6d1be23b..27b1884e 100644 --- a/source/main.c +++ b/source/main.c @@ -28,7 +28,7 @@ int main(void) print_welcome_msg(&shell); while (true) { - if (!read_input(&shell.input_line, PROMPT, true, shell.is_interactive)) + if (!read_input(&shell.input_line, &shell, PROMPT, true)) continue ; if (!shell.input_line) exec_exit(&shell, NULL); diff --git a/source/utils/user_input_utils.c b/source/utils/user_input_utils.c index e8bf70d1..ec298ca3 100644 --- a/source/utils/user_input_utils.c +++ b/source/utils/user_input_utils.c @@ -10,24 +10,26 @@ /* */ /* ************************************************************************** */ -#include "defines.h" +#include "clean.h" + +static bool limit_retries(t_sh *shell, bool success); bool read_input( char **line, + t_sh *shell, char *prompt, - bool add_to_history, - bool is_interactive) + bool add_to_history) { char *tmp; errno = SUCCESS; - if (is_interactive) + if (shell->is_interactive) *line = readline(prompt); else { tmp = get_next_line(STDIN_FILENO); if (errno != SUCCESS) - return (free(tmp), false); + return (free(tmp), limit_retries(shell, false)); if (tmp) { *line = ft_strtrim(tmp, "\n"); @@ -37,8 +39,22 @@ bool read_input( if (errno == EINTR || errno == ENOTTY) errno = SUCCESS; else if (errno != SUCCESS) - return (false); - if (add_to_history && is_interactive && *line && **line) + return (limit_retries(shell, false)); + if (add_to_history && shell->is_interactive && *line && **line) add_history(*line); - return (errno == SUCCESS); + return (limit_retries(shell, errno == SUCCESS)); +} + +static bool limit_retries(t_sh *shell, bool success) +{ + static int retries; + + if (success == true) + { + retries = 0; + return (true); + } + else if (++retries > 5) + clean_and_exit_shell(shell, GENERAL_ERROR, "read input failed"); + return (false); } From d18ea9e787b3ea81d584ffdc0fbce7f1267367c4 Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:21:10 +0200 Subject: [PATCH 4/6] improve: Give user feedback when retrying getting user input --- source/utils/user_input_utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/utils/user_input_utils.c b/source/utils/user_input_utils.c index ec298ca3..0bc892ce 100644 --- a/source/utils/user_input_utils.c +++ b/source/utils/user_input_utils.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "clean.h" +#include "utils.h" static bool limit_retries(t_sh *shell, bool success); @@ -56,5 +57,6 @@ static bool limit_retries(t_sh *shell, bool success) } else if (++retries > 5) clean_and_exit_shell(shell, GENERAL_ERROR, "read input failed"); + print_error("%s: read input failed, trying again...\n", PROGRAM_NAME); return (false); } From c595b15aba581eb0bee610fcec22c9ca8476e00d Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:21:57 +0200 Subject: [PATCH 5/6] improve: Add program name prefix to all `clean_and_exit_shell()` error msgs --- source/shell/clean.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/shell/clean.c b/source/shell/clean.c index 22e4f217..e700f3f0 100644 --- a/source/shell/clean.c +++ b/source/shell/clean.c @@ -21,7 +21,7 @@ static void close_std_io(void); void clean_and_exit_shell(t_sh *shell, int exit_code, char *msg) { if (msg) - print_error("%s\n", msg); + print_error("%s: %s\n", PROGRAM_NAME, msg); clean_shell(shell); safe_close_all_pipes(shell); free_get_next_line(); From 9d9c5c31a67c8e18e8766496168dde1b97f348ea Mon Sep 17 00:00:00 2001 From: Lukas Dullinger <129603980+itislu@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:25:55 +0200 Subject: [PATCH 6/6] style: Add macro for max input retries --- include/defines.h | 3 +++ source/utils/user_input_utils.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/defines.h b/include/defines.h index e1dce484..10692dc3 100644 --- a/include/defines.h +++ b/include/defines.h @@ -115,6 +115,9 @@ # define PT_ROW_NUM 192 # define UNDEFINED_STATE -1 +/* User Input */ +# define MAX_INPUT_RETRIES 5 + /* Export */ # define EXPORT_PREFIX "export " diff --git a/source/utils/user_input_utils.c b/source/utils/user_input_utils.c index 0bc892ce..7d0c191d 100644 --- a/source/utils/user_input_utils.c +++ b/source/utils/user_input_utils.c @@ -55,7 +55,7 @@ static bool limit_retries(t_sh *shell, bool success) retries = 0; return (true); } - else if (++retries > 5) + else if (++retries > MAX_INPUT_RETRIES) clean_and_exit_shell(shell, GENERAL_ERROR, "read input failed"); print_error("%s: read input failed, trying again...\n", PROGRAM_NAME); return (false);